3d标签云实现过程(tagcloud.js)同步原生和 vue

写在前面

本来是没有准备写这个知识点,但是下载这个 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 用法的讲解了,整好最近我手里有需求需要用到这块,顺手将这个分享出去,大家用的时候有什么问题随时下面留言即可!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/160573.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Exception】Error: Dynamic require of “path“ is not supported

Talk is cheap, show me the code. 环境 | Environment kversionOSwindows 11Node.jsv18.14.2npm9.5.0vite5.0.0vue3.3.8 报错日志 | Error log >npm run dev> app10.0.0 dev > viteERROR failed to load config from C:\code\frontend\app1\vite.config.js …

【LeetCode二叉树进阶题目】606,102,107

二叉树进阶题目 606. 根据二叉树创建字符串解题思路及实现 102. 二叉树的层序遍历解题思路及实现 107. 二叉树的层序遍历 II解题思路及实现 606. 根据二叉树创建字符串 描述 给你二叉树的根节点 root &#xff0c;请你采用前序遍历的方式&#xff0c;将二叉树转化为一个由括号…

从零开始学习typescript——运算符(算术运算符、赋值运算符、比较运算符)

算术运算符 算术运算符主要是针对数值类型和长整型&#xff1b;包括有加法、减法、乘法、除法、自增、自减等运算 加法&#xff08;&#xff09; let x:number1let y:number 2console.log(xy)减法&#xff08;-&#xff09; let x:number1let y:number 2console.log(y-x)乘法…

晶振有哪几种?晶振旁边的两个电容起什么作用?

晶振可以分为普通晶振、温补晶振、压控晶振、恒温晶振、差分晶振。 普通晶振通常用作微处理器的时钟器件&#xff0c;主要应用于那些稳定度要求不要的设备中&#xff0c;例如电视机、微波炉。 温补晶振&#xff0c;在晶振内部采取了对晶体频率、温度特性进行补偿&#xff0c;已…

软件工程理论与实践 (吕云翔) 第十三章 软件测试方法与过程课后习题及其答案解析

第十三章 软件测试方法与过程 1.判断题 &#xff08;1&#xff09;白盒测试无须考虑模块内部的执行过程和程序结构&#xff0c;只需了解模块的功能即可。() 解析&#xff1a;白盒测试需要考虑模块内部的执行过程和程序结构&#xff0c;以便设计测试用例和覆盖代码路径。 &a…

软文推广有什么作用?媒介盒子分享

数字时代&#xff0c;品牌方以往的营销打法可能需要应时而变&#xff0c;传统的广告模式很难将品牌推广出去&#xff0c;原因就在于传统广告的成本高昂并且针对性较弱&#xff0c;而软文推广能够通过较低的成本将产品或品牌信息送到消费者面前&#xff0c;今天媒介盒子就来分享…

58同城算法工程师一面&二面 面试题

来源&#xff1a;投稿 作者&#xff1a;LSC 编辑&#xff1a;学姐 一面 40min 1.Gbdt和xgboost的区别 XGBoost是对GBDT的改进和扩展&#xff0c;它提供了更高的效率、更好的性能、正则化技术、内置特征选择等功能。 (1)正则化: GBDT使用基本的树模型&#xff0c;并在每一轮…

vue3.0 + qiankun遇到的问题

进入子应用再回到主应用切换动态路由时 TypeError: Cannot read properties of undefined (reading ‘appWrapperGetter’) application ‘plat’ died in status UNMOUNTING: instance.$destroy is not a function 第一个报错是因为子应用切走时没有销毁 vue的实例&#xff0…

常用RFC规范汇总

官网&#xff1a;https://www.rfc-editor.org/ The RFC Series (ISSN 2070-1721) contains technical and organizational documents about the Internet, including the specifications and policy documents produced by five streams: the Internet Engineering Task Force …

TCP/IP

分层模型 TCP 传输控制协议 UDP 用户数据包协议 四层 应用层 负责发送/接收消息 传输层 负责拆分和组装 .期间会有编号 网络层 TCP/UDP 属于网络层, 不会判断和处理编号 数据链路层 以太网 ,网络设备 TCP 连接 TCP连接需要端口,进行通信 Java 通过Socket 接收消息 发送 …

基于SpringBoot+Vue的体检预约管理系统

基于SpringBootVue的体检预约管理系统的设计与实现~ 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringBootMyBatisVue工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 主页 管理员界面 用户界面 摘要 体检预约管理系统是一种基于Spring Boot…

Vue3常用操作

一、Vue3项目构建 1、安装最新版本vue npm create vuelatest 2、选择需要的配置 3、进入项目 cd 项目名称 4、下载依赖 npm install 5、启动项目 npm run dev

chatGLM3微调

文章目录 一、问答数据集生成器使用设置问题启动使用产出效果 二、进行微调第一步&#xff1a;下载模型第二步&#xff1a;项目准备2.1 下载项目2.2 然后使用 pip 安装依赖2.3 开始 第三步进行微调3.1安装相关依赖3.2准备数据集&#xff0c;并且上传3.3对数据集进行预处理3.4 进…

如何使用技术SEO来优化评论

你在网上购买吗&#xff1f;我的意思是&#xff0c;在当今时代&#xff0c;谁不这样做&#xff1f;作为买家&#xff0c;无论您想购买什么&#xff0c;您都了解全面和高质量评论的价值。这是您在决定是否购买产品时考虑的重要因素。 这就是为什么许多人在网上购物之前使用评论…

移动端click事件、touch事件、tap事件的区别

在移动端&#xff0c;有三种常见的事件类型&#xff0c;click事件、touch事件、tap事件。它们的区别如下&#xff1a; click事件&#xff1a;click事件是在用户点击屏幕的时候触发&#xff0c;如果是移动设备&#xff0c;则会在用户点击屏幕的同时触发touch事件。但是&#xff…

【开源】基于Vue和SpringBoot的康复中心管理系统

项目编号&#xff1a; S 056 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S056&#xff0c;文末获取源码。} 项目编号&#xff1a;S056&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 普通用户模块2.2 护工模块2.3 管理员…

uni-app中vue3+setup实现下拉刷新、上拉加载更多效果

在小程序或各类app中&#xff0c;下拉刷新和上拉加载更多是极为常见和使用非常频繁的两个功能&#xff0c;通过对这两个功能的合理使用可以极大的方便用户进行操作。 合理的设计逻辑才能更容易挽留住用户&#xff0c;因为这些细节性的小功能点就变得极为重要起来。 那么在uni…

基于WEB的停车场管理系统的设计和实现【附源码】

基于WEB的停车场管理系统的设计和实现 摘 要 随着现代社会的快速发展&#xff0c;人民生活水平快速提高&#xff0c;汽车的数量飞速增加&#xff0c;与此同时停车问题也越来越受到人们的关注&#xff0c;为了实现对停车场进行有效的管理&#xff0c;结合一些停车场的模式和现状…

游戏被攻击了怎么办

随着网络技术和网络应用的发展&#xff0c;网络安全问题显得越来越重要&#xff0c;在创造一个和谐共赢的互联网生态环境的路途中总是会遇到各种各样的问题。最常见的当属于DDOS攻击&#xff08;Distributed Denial of Service&#xff09;即分布式阻断服务。由于容易实施、难以…

【LeetCode刷题】--40.组合总和II

40.组合总和II 本题详解&#xff1a;回溯算法 class Solution {public List<List<Integer>> combinationSum2(int[] candidates, int target) {int len candidates.length;List<List<Integer>> res new ArrayList<>();if (len 0) {return re…