寫在前面
本來是沒有準備寫這個知識點,但是下載這個 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 用法的講解了,整好最近我手里有需求需要用到這塊,順手將這個分享出去,大家用的時候有什么問題隨時下面留言即可!