写在前面
本来是没有准备写这个知识点,但是下载这个 js 的时候发现很多都是要钱或者是积分的,我就不明白了一个开源了这么久的 js 怎么还有人拿来挣钱的,同时还有一些只有原生 html 的例子,但是现在都是 框架主导的一些项目,显然是不行的,这篇文章就简单的写一下 怎么使用原生和 vue 分别使用 tagcloudjs 实现标签云,喜欢的可以直接拿去用,当然你也可以直接参考这个的例子写,我没有试过,但是 demo 是可行的tagcloudjs. 当然防止你们下载失败,我最后面会将源码贴出来,直接用就可以了,但是 vue 实现的和原生实现的 js 有一点点的差别,因为原来的 tagcloudjs 无法给 vue 使用。
结果展示
大概就是下面这个样子
原生代码实现
<!DOCTYPE html>
<html><head><meta charset="utf-8"><title></title></head><body><div class="wrapper"><div class="tagcloud fl"><span id="pagetext">CSDN 玩家 1</span><span id="pagetext">CSDN 玩家 2</span><span id="pagetext">CSDN 玩家 3</span><span id="pagetext">CSDN 玩家 4</span><span id="pagetext">CSDN 玩家 5</span><span id="pagetext">CSDN 玩家 6</span><span id="pagetext">CSDN 玩家 7</span><span id="pagetext">CSDN 玩家 8</span><span id="pagetext">CSDN 玩家 9</span></div></div><script src="../assets/js/tagcloud.js"></script><script>tagcloud({selector: '.tagcloud', //元素选择器fontsize: 16, //基本字体大小, 单位pxradius: 100, //滚动半径, 单位pxmspeed: 'normal', //滚动最大速度, 取值: slow, normal(默认), fastispeed: 'normal', //滚动初速度, 取值: slow, normal(默认), fastdirection: 135, //初始滚动方向, 取值角度(顺时针360): 0对应top, 90对应left, 135对应right-bottom(默认)...keep: false //鼠标移出组件后是否继续随鼠标滚动, 取值: false, true(默认) 对应 减速至初速度滚动, 随鼠标滚动});</script></body><style>.wrapper {width: 50%;height: 300px;margin: 0 auto;margin-top: 70px;}.tagcloud {position: relative;margin-top: 0px;}.tagcloud span {position: absolute;top: 0;left: 0;cursor: pointer;display: block;padding: 11px 30px;color: #60A2FF;font-size: 16px;border: 1px solid #e6e7e8;border-radius: 18px;background-color: #f2f4f8;text-decoration: none;white-space: nowrap;-o-box-shadow: 6px 4px 8px 0 rgba(151, 142, 136, .34);-ms-box-shadow: 6px 4px 8px 0 rgba(151, 142, 136, .34);-moz-box-shadow: 6px 4px 8px 0 rgba(151, 142, 136, .34);-webkit-box-shadow: 6px 4px 8px 0 rgba(151, 142, 136, .34);box-shadow: 6px 4px 8px 0 rgba(151, 142, 136, .34);-ms-filter: "progid:DXImageTransform.Microsoft.Shadow(Strength=4,Direction=135, Color='#000000')";/*兼容ie7/8*/filter: progid:DXImageTransform.Microsoft.Shadow(color='#969696', Direction=125, Strength=9);/*strength是阴影大小,direction是阴影方位,单位为度,可以为负数,color是阴影颜色 (尽量使用数字)使用IE滤镜实现盒子阴影的盒子必须是行元素或以行元素显示(block或inline-block;)*/}.tagcloud a:hover {color: #3385cf;}</style>
</html>
给原生 HTML 实现用的tagcloud.js源码
/*
* 3d标签云
* 功能:鼠标移入标签,当前标签静止放大
* 说明:
* */window.tagcloud = (function(win, doc) { // ns// 判断对象function isObject (obj) {return Object.prototype.toString.call(obj) === '[object Object]';}// 构造函数function TagCloud (options) {var self = this;self.config = TagCloud._getConfig(options);self.box = self.config.element; //组件元素self.fontsize = self.config.fontsize; //平均字体大小self.radius = self.config.radius; //滚动半径self.depth = 2 * self.radius; //滚动深度self.size = 2 * self.radius; //随鼠标滚动变速作用区域self.mspeed = TagCloud._getMsSpeed(self.config.mspeed);self.ispeed = TagCloud._getIsSpeed(self.config.ispeed);self.items = self._getItems();self.direction = self.config.direction; //初始滚动方向self.keep = self.config.keep; //鼠标移出后是否保持之前滚动//初始化self.active = false; //是否为激活状态self.lasta = 1;self.lastb = 1;self.mouseX0 = self.ispeed * Math.sin(self.direction * Math.PI / 180); //鼠标与滚动圆心x轴初始距离self.mouseY0 = -self.ispeed * Math.cos(self.direction * Math.PI / 180); //鼠标与滚动圆心y轴初始距离self.mouseX = self.mouseX0; //鼠标与滚动圆心x轴距离self.mouseY = self.mouseY0; //鼠标与滚动圆心y轴距离self.index = -1;//鼠标移入TagCloud._on(self.box, 'mouseover', function () {self.active = true;});//鼠标移出TagCloud._on(self.box, 'mouseout', function () {self.active = false;});//鼠标在内移动TagCloud._on(self.keep ? win : self.box, 'mousemove', function (ev) {var oEvent = win.event || ev;var boxPosition = self.box.getBoundingClientRect();self.mouseX = (oEvent.clientX - (boxPosition.left + self.box.offsetWidth / 2)) / 5;self.mouseY = (oEvent.clientY - (boxPosition.top + self.box.offsetHeight / 2)) / 5;});for (var j = 0, len = self.items.length; j < len; j++) {self.items[j].element.index=j;//鼠标移出子元素,当前元素静止放大self.items[j].element.onmouseover = function(){self.index = this.index;};//鼠标移出子元素,当前元素继续滚动self.items[j].element.onmouseout = function(){self.index = -1;};}//定时更新TagCloud.boxs.push(self.box);self.update(self); //初始更新self.box.style.visibility = "visible";self.box.style.position = "relative";self.box.style.minHeight = 1.2 * self.size + "px";self.box.style.minWidth = 2.5 * self.size + "px";for (var j = 0, len = self.items.length; j < len; j++) {self.items[j].element.style.position = "absolute";self.items[j].element.style.zIndex = j + 1;}self.up = setInterval(function() {self.update(self);}, 30);}//实例TagCloud.boxs = []; //实例元素数组// 静态方法们TagCloud._set = function (element) {if (TagCloud.boxs.indexOf(element) == -1) {//ie8不支持数组的indexOf方法return true;}};//添加数组IndexOf方法if (!Array.prototype.indexOf){Array.prototype.indexOf = function(elt /*, from*/){var len = this.length >>> 0;var from = Number(arguments[1]) || 0;from = (from < 0)? Math.ceil(from): Math.floor(from);if (from < 0)from += len;for (; from < len; from++){if (from in this && this[from] === elt)return from;}return -1;};}TagCloud._getConfig = function (config) {var defaultConfig = { //默认值fontsize: 16, //基本字体大小, 单位pxradius: 60, //滚动半径, 单位pxmspeed: "normal", //滚动最大速度, 取值: slow, normal(默认), fastispeed: "normal", //滚动初速度, 取值: slow, normal(默认), fastdirection: 135, //初始滚动方向, 取值角度(顺时针360): 0对应top, 90对应left, 135对应right-bottom(默认)...keep: true //鼠标移出组件后是否继续随鼠标滚动, 取值: false, true(默认) 对应 减速至初速度滚动, 随鼠标滚动};if(isObject(config)) {for(var i in config) {if(config.hasOwnProperty(i)) {//hasOwnProperty()用来判断一个属性是定义在对象本身而不是继承自原型链defaultConfig[i] = config[i]; //用户配置}}}return defaultConfig;// 配置 Merge};TagCloud._getMsSpeed = function (mspeed) { //滚动最大速度var speedMap = {slow: 1.5,normal: 3,fast: 5};return speedMap[mspeed] || 3;};TagCloud._getIsSpeed = function (ispeed) { //滚动初速度var speedMap = {slow: 10,normal: 25,fast: 50};return speedMap[ispeed] || 25;};TagCloud._getSc = function(a, b) {var l = Math.PI / 180;//数组顺序0,1,2,3表示asin,acos,bsin,bcosreturn [Math.sin(a * l),Math.cos(a * l),Math.sin(b * l),Math.cos(b * l)];};TagCloud._on = function (ele, eve, handler, cap) {if (ele.addEventListener) {ele.addEventListener(eve, handler, cap);} else if (ele.attachEvent) {ele.attachEvent('on' + eve, handler);} else {ele['on' + eve] = handler;}};// 原型方法TagCloud.prototype = {constructor: TagCloud, // 反向引用构造器update: function () {var self = this, a, b;if (!self.active && !self.keep) {self.mouseX = Math.abs(self.mouseX - self.mouseX0) < 1 ? self.mouseX0 : (self.mouseX + self.mouseX0) / 2; //重置鼠标与滚动圆心x轴距离self.mouseY = Math.abs(self.mouseY - self.mouseY0) < 1 ? self.mouseY0 : (self.mouseY + self.mouseY0) / 2; //重置鼠标与滚动圆心y轴距离}a = -(Math.min(Math.max(-self.mouseY, -self.size), self.size) / self.radius ) * self.mspeed;b = (Math.min(Math.max(-self.mouseX, -self.size), self.size) / self.radius ) * self.mspeed;if (Math.abs(a) <= 0.01 && Math.abs(b) <= 0.01) { return; }self.lasta = a;self.lastb = b;var sc = TagCloud._getSc(a, b);for (var j = 0, len = self.items.length; j < len; j++) {var rx1 = self.items[j].x,ry1 = self.items[j].y*sc[1] + self.items[j].z*(-sc[0]),rz1 = self.items[j].y*sc[0] + self.items[j].z*sc[1];var rx2 = rx1 * sc[3] + rz1 * sc[2],ry2 = ry1,rz2 = rz1 * sc[3] - rx1 * sc[2];if(self.index==j){self.items[j].scale = 1; //取值范围0.6 ~ 3self.items[j].fontsize = 16;self.items[j].alpha = 1;self.items[j].element.style.zIndex = 99;}else{var per = self.depth / (self.depth + rz2);self.items[j].x = rx2;self.items[j].y = ry2;self.items[j].z = rz2;self.items[j].scale = per; //取值范围0.6 ~ 3self.items[j].fontsize = Math.ceil(per * 2) + self.fontsize - 6;self.items[j].alpha = 1.5 * per - 0.5;self.items[j].element.style.zIndex = Math.ceil(per*10-5);}self.items[j].element.style.fontSize = self.items[j].fontsize + "px";self.items[j].element.style.left = self.items[j].x + (self.box.offsetWidth - self.items[j].offsetWidth) / 2 + "px";self.items[j].element.style.top = self.items[j].y + (self.box.offsetHeight - self.items[j].offsetHeight) / 2 + "px";self.items[j].element.style.filter = "alpha(opacity=" + 100 * self.items[j].alpha + ")";self.items[j].element.style.opacity = self.items[j].alpha;}},_getItems: function () {var self = this,items = [],element = self.box.children, // children 全部是Elementlength = element.length,item;for (var i = 0; i < length; i++) {item = {};item.angle = {};item.angle.phi = Math.acos(-1 + (2 * i + 1) / length);item.angle.theta = Math.sqrt((length + 1) * Math.PI) * item.angle.phi;item.element = element[i];item.offsetWidth = item.element.offsetWidth;item.offsetHeight = item.element.offsetHeight;item.x = self.radius * 1.5 * Math.cos(item.angle.theta) * Math.sin(item.angle.phi);item.y = self.radius * 1.5 * Math.sin(item.angle.theta) * Math.sin(item.angle.phi);item.z = self.radius * 1.5 * Math.cos(item.angle.phi);item.element.style.left = item.x + (self.box.offsetWidth - item.offsetWidth) / 2 + "px";item.element.style.top = item.y + (self.box.offsetHeight - item.offsetHeight) / 2 + "px";items.push(item);}return items; //单元素数组}};if (!doc.querySelectorAll) {//ie7不支持querySelectorAll,所以要重新定义doc.querySelectorAll = function (selectors) {var style = doc.createElement('style'), elements = [], element;doc.documentElement.firstChild.appendChild(style);doc._qsa = [];style.styleSheet.cssText = selectors + '{x-qsa:expression(document._qsa && document._qsa.push(this))}';window.scrollBy(0, 0);style.parentNode.removeChild(style);while (doc._qsa.length) {element = doc._qsa.shift();element.style.removeAttribute('x-qsa');elements.push(element);}doc._qsa = null;return elements;};}return function (options) { // factoryoptions = options || {}; // 短路语法var selector = options.selector || '.tagcloud', //默认选择class为tagcloud的元素elements = doc.querySelectorAll(selector),instance = [];for (var index = 0, len = elements.length; index < len; index++) {options.element = elements[index];if (!!TagCloud._set(options.element)) {instance.push(new TagCloud(options));}}return instance;};})(window, document);
vue 实现
<template><div class="tagcloud"><span v-for="i in 10">CSDN 玩家{{ i}}</span></div>
</template><script setup>import { onMounted } from 'vue';import { tagcloud } from '../../src/assets/tagcloud.js'onMounted(() => {tagcloud({selector: '.tagcloud', //元素选择器fontsize: 16, //基本字体大小, 单位pxradius: 100, //滚动半径, 单位pxmspeed: 'normal', //滚动最大速度, 取值: slow, normal(默认), fastispeed: 'normal', //滚动初速度, 取值: slow, normal(默认), fastdirection: 135, //初始滚动方向, 取值角度(顺时针360): 0对应top, 90对应left, 135对应right-bottom(默认)...keep: false //鼠标移出组件后是否继续随鼠标滚动, 取值: false, true(默认) 对应 减速至初速度滚动, 随鼠标滚动});})
</script>
- style 同原生的一致,这里不贴代码了,避免文章太长你们看着烦
给 vue 实现用的 tagcloud.js
export const tagcloud = (function (win = window, doc = document)
将原生js 中的第一行代码改为上面的即可,将 tagcloud 导出去就可以给 vue 直接使用了,这里需要注意的一点是用的时候需要保证页面DOM 元素全部加载结束再执行 tagcloud 的方法,否则是无法加载出来的,这个和 echartsjs 用法是保持一致的,因为这些图形类的 js 使用的前提条件就是你的 DOM 元素需要存在,否则都是徒劳,当你没有效果的时候检查一下是不是 DOM 加载失败了或者是没有加载出来即可
写在后面
以上就是关于 tagcloudjs 用法的讲解了,整好最近我手里有需求需要用到这块,顺手将这个分享出去,大家用的时候有什么问题随时下面留言即可!