vue实现标签云效果的方法详解

本文实例讲述了vue实现标签云效果的方法。分享给大家供大家参考,具体如下:

闲扯两句

最近想给自己的博客上加上一个3D标签云的效果,用来表示自己博客文章的分组,网上找到了canvas实现的,还有a元素实现的解析3D标签云,我想让标签可以选择和点击,又不想在标签数量较多时操作a标签导致性能问题,于是svg就成了一个不错的选择。

标签初始化

这里实现的核心主要是参考了前面的那篇解析3D标签云的文章,作者给出了源码,讲解也比较通俗易懂。大体来说,整个代码分三步:

  • 根据标签的数量,算出每个标签在球面上分布的x,y,z坐标
  • 根据标签的坐标,将标签绘制出来,x,y坐标通过标签的位置来表示,z坐标通过标签字体的大小和透明度来表示
  • 通过函数根据球的旋转角速度不断计算标签新的x,y坐标,制造出旋转效果
  • 通过mousemove事件,根据鼠标坐标值,改变球旋转的角速度,做出交互效果

贴上代码:

  <div id='app' >
    <svg :width='width' :height='height' @mousemove='listener($event)'>
      <a :href="tag.href" rel="external nofollow" v-for='tag in tags'>
        <text :x='tag.x' :y='tag.y' :font-size='20 * (600/(600-tag.z))' :fill-opacity='((400+tag.z)/600)'>{{tag.text}}</text>
      </a>
    </svg>
  </div>

在模板中,借用指令v-for来渲染标签,每个标签上绑定了x,y,font-size(用来表现z轴),fill-opacity(都是与z坐标有关的表达式,用来表现z轴),及text;

 data: {
   width:700,//svg宽度
   height:700,//svg高度
   tagsNum:20,//标签数量
   RADIUS:200,//球的半径
   speedX:Math.PI/360,//球一帧绕x轴旋转的角度
   speedY:Math.PI/360,//球-帧绕y轴旋转的角度
   tags: []
 }
 computed:{
   CX(){//球心x坐标
     return this.width/2;
   },
   CY(){//球心y坐标
     return this.height/2;
   }
 },

做好了上面的基础,下面我们来初始化标签数据:

 created(){//初始化标签位置
   let tags=[];
   for(let i = 0; i < this.tagsNum; i++){
     let tag = {};
     let k = -1 + (2 * (i + 1) - 1) / this.tagsNum;
     let a = Math.acos(k);
     let b = a * Math.sqrt(this.tagsNum * Math.PI)//计算标签相对于球心的角度
     tag.text = i + 'tag';
     tag.x = this.CX + this.RADIUS * Math.sin(a) * Math.cos(b);//根据标签角度求出标签的x,y,z坐标
     tag.y = this.CY + this.RADIUS * Math.sin(a) * Math.sin(b);
     tag.z = this.RADIUS * Math.cos(a);
     tag.href = 'https://imgss.github.io';//给标签添加链接
     tags.push(tag);
   }
   this.tags = tags;//让vue替我们完成视图更新
 },

到了这里,我们就算了算坐标,vue完成了视图更新的工作,这时基本上就可以得到一副静态的图像了:

下面就是通过改变每一个tag的x,y的值来使球旋转起来;实现方法是rotateX,rotateY函数:

  rotateX(angleX){
    var cos = Math.cos(angleX);
    var sin = Math.sin(angleX);
    for(let tag of this.tags){
      var y1 = (tag.y- this.CY) * cos - tag.z * sin + this.CY;
      var z1 = tag.z * cos + (tag.y- this.CY) * sin;
      tag.y = y1;
      tag.z = z1;
    }
  },
  rotateY(angleY){
    var cos = Math.cos(angleY);
    var sin = Math.sin(angleY);
    for(let tag of this.tags){
      var x1 = (tag.x - this.CX) * cos - tag.z * sin + this.CX;
      var z1 = tag.z * cos + (tag.x - this.CX) * sin;
      tag.x = x1;
      tag.z = z1;
    }
  },

这两个函数就是根据标签原来的坐标和球旋转的角度算出新的坐标,最后在mounted钩子下面,写一个animate函数,不断调用这两个函数,实现旋转动画

  mounted(){//使球开始旋转
    setInterval(() => {
      this.rotateX(this.speedX);
      this.rotateY(this.speedY);
    }, 17)
  },

全部代码如下:

   <script>
    var app = new Vue({
      el: '#app',
      data: {
        width:700,
        height:700,
        tagsNum:20,
        RADIUS:200,
        speedX:Math.PI/360,
        speedY:Math.PI/360,
        tags: []
      },
      computed:{
        CX(){
          return this.width/2;
        },
        CY(){
          return this.height/2;
        }
      },
      created(){//初始化标签位置
        let tags=[];
        for(let i = 0; i < this.tagsNum; i++){
          let tag = {};
          let k = -1 + (2 * (i + 1) - 1) / this.tagsNum;
          let a = Math.acos(k);
          let b = a * Math.sqrt(this.tagsNum * Math.PI);
          tag.text = i + 'tag';
          tag.x = this.CX + this.RADIUS * Math.sin(a) * Math.cos(b);
          tag.y = this.CY + this.RADIUS * Math.sin(a) * Math.sin(b);
          tag.z = this.RADIUS * Math.cos(a);
          tag.href = 'https://imgss.github.io';
          tags.push(tag);
        }
        this.tags = tags;
      },
      mounted(){//使球开始旋转
        setInterval(() => {
          this.rotateX(this.speedX);
          this.rotateY(this.speedY);
        }, 17)
      },
      methods: {
        rotateX(angleX){
          var cos = Math.cos(angleX);
          var sin = Math.sin(angleX);
          for(let tag of this.tags){
            var y1 = (tag.y- this.CY) * cos - tag.z * sin + this.CY;
            var z1 = tag.z * cos + (tag.y- this.CY) * sin;
            tag.y = y1;
            tag.z = z1;
          }
        },
        rotateY(angleY){
          var cos = Math.cos(angleY);
          var sin = Math.sin(angleY);
          for(let tag of this.tags){
            var x1 = (tag.x - this.CX) * cos - tag.z * sin + this.CX;
            var z1 = tag.z * cos + (tag.x-this.CX) * sin;
            tag.x = x1;
            tag.z = z1;
          }
        },
        listener(event){//响应鼠标移动
          var x = event.clientX - this.CX;
          var y = event.clientY - this.CY;
          this.speedX = x*0.0001>0 ? Math.min(this.RADIUS*0.00002, x*0.0001) : Math.max(-this.RADIUS*0.00002, x*0.0001);
          this.speedY = y*0.0001>0 ? Math.min(this.RADIUS*0.00002, y*0.0001) : Math.max(-this.RADIUS*0.00002, y*0.0001);
        }
       }
     })
  </script>

完整demo · vue · no vue

总结

vue的数据绑定可以减少我们对dom的操作,而将关注点放在逻辑上面,vue构造函数提供的几个选项可以帮助我们更好的组织代码

希望本文所述对大家vue.js程序设计有所帮助。

(0)

相关推荐

  • Javascript随机标签云代码实例

    先来看一下效果 代码如下 <!DOCTYPE HTML> <html> <head> <meta charset="UTF-8"> <title>随机标签云</title> <style type="text/css"> *{ margin:0; padding:0 } a{ text-decoration:none } #wrap{ width:400px; margin:auto

  • jquery 3D 标签云示例代码

    相关选项 zoom: 90 初始的缩放度 min_zoom: 25 max_zoom: 120 zoom_factor: 2 - 鼠标滚轮的缩放速度 rotate_factor: -0.45 - 鼠标移动时球体旋转的数量.正数将反向旋转 fps: 10 - 定义每秒动画更新的次数 centrex: 250 - 在container div中水平方向旋转中心 centrey: 250 在container div中垂直方向旋转中心 min_font_size: 12 max_font_size:

  • 用JS实现3D球状标签云示例代码

    Matter: 1.发现实例不足,无法悬停(有待解决) 2.无法系统随机自动上色(有待解决) 首先使用标签云的一家高知名度的网站---照片共享网站Flickr.标签云的设计者是交互设计师Stewart Butterfield.之后,标签云被诸如del.Technorati等网站采纳. 首次公布的外观标签云(或至少是一个加权名单),可归结起来主要是"潜意识档案" ,在 Douglas Coupland的Microserfs( 1995 ) .在Lester Leaps Out,威尔士诗人

  • js简单实现标签云效果实例

    本文实例讲述了js简单实现标签云效果.分享给大家供大家参考.具体如下: 这里的JavaScript标签云,基于妙味课堂miaov.js文件,非常流行的网页效果,在网页的右侧或左侧开辟一小块地方,用来显示热门的标签,形式就选择标签云吧,绝对酷哦,相信你也会喜欢. 运行效果如下图所示: 具体代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xh

  • 教你用javascript实现随机标签云效果_附代码

    标签云是一套相关的标签以及与此相应的权重.典型的标签云有30至150个标签.权重影响使用的字体大小或其他视觉效果.同时,直方图或饼图表是最常用的代表约12种不同的权数.因此,标签云彩能代表更多的权,尽管不那么准确.此外,标签云通常是可以交互的:标签是典型的超链接,让用户可以仔细了解他们的内容.   大概可以理解为一堆相关或者不相关的标签混到一块,根据不同的重要程度,或者其他维度的不同来为每个标签设置不同的样式已凸显他们的不同,这样的一堆标签在一起就是我们通常说的标签云了.   下面我们大概说一下

  • javascript实现动态标签云

    今天上学校的图书馆,看到了一个好玩的东西,特意百度了下,发现叫做"标签球",效果图为: 直接代码如下: CSS: #div1 {position:relative; width:350px; height:350px; border:1px solid #000; margin: 20px auto 0; } #div1 a {position:absolute; top:0px; left:0px; font-family: Microsoft YaHei; color:#000;

  • 深入解析JS实现3D标签云的原理与方法

    本文实例讲述了深入解析JS实现3D标签云的原理与方法.分享给大家供大家参考,具体如下: 最近开始用canvas搞3D了,搞得也是简单的东西,就是球体转圈.做出来后,突然想起以前看过的3D标签云,在以前觉得真心狂拽酷炫叼啊,当时也确实不知道怎么在平面上模拟3D,所以也就没去搞了.现在刚好用了canvas搞3D,也发现,好像3D标签云也差不多,然后就写了一下. 具体怎么做呢,先说一下原理,3D标签云就是做一个球面,然后再球面上取均匀分布的点,把点坐标赋给标签,再根据抽象出来的Z轴大小来改变标签的字体

  • JavaScript实现的圆形浮动标签云效果实例

    本文实例讲述了JavaScript实现的圆形浮动标签云效果.分享给大家供大家参考.具体如下: 这里介绍的JS标签云效果,在鼠标的作用下会自动转动,整体上围绕成一个圆形,各个标签之间无需Div代码,直接文字+链接的形式,有多少就显示多少,JavaScript会自动调整显示数量,让视觉效果最佳. 运行效果如下图所示: 具体代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://

  • vue实现标签云效果的方法详解

    本文实例讲述了vue实现标签云效果的方法.分享给大家供大家参考,具体如下: 闲扯两句 最近想给自己的博客上加上一个3D标签云的效果,用来表示自己博客文章的分组,网上找到了canvas实现的,还有a元素实现的解析3D标签云,我想让标签可以选择和点击,又不想在标签数量较多时操作a标签导致性能问题,于是svg就成了一个不错的选择. 标签初始化 这里实现的核心主要是参考了前面的那篇解析3D标签云的文章,作者给出了源码,讲解也比较通俗易懂.大体来说,整个代码分三步: 根据标签的数量,算出每个标签在球面上分

  • Vue.js标签页组件使用方法详解

    本文实例为大家分享了Vue.js标签页组件使用的具体代码,供大家参考,具体内容如下 效果 入口页 index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0&q

  • vue实现标签云效果的示例

    闲扯两句 最近想给自己的博客上加上一个3D标签云的效果,用来表示自己博客文章的分组,网上找到了canvas实现的,还有a元素实现的解析3D标签云,我想让标签可以选择和点击,又不想在标签数量较多时操作a标签导致性能问题,于是svg就成了一个不错的选择. 标签初始化 这里实现的核心主要是参考了前面的那篇解析3D标签云的文章,作者给出了源码,讲解也比较通俗易懂.大体来说,整个代码分三步: 根据标签的数量,算出每个标签在球面上分布的x,y,z坐标 根据标签的坐标,将标签绘制出来,x,y坐标通过标签的位置

  • SpringBoot+Vue实现EasyPOI导入导出的方法详解

    目录 前言 一.为什么做导入导出 二.什么是 EasyPOI 三.项目简介 项目需求 效果图 开发环境 四.实战开发 核心源码 前端页面 后端核心实现 五.项目源码 小结 前言 Hello~ ,前后端分离系列和大家见面了,秉着能够学到知识,学会知识,学懂知识的理念去学习,深入理解技术! 项目开发过程中,很大的需求都有 导入导出功能,我们依照此功能,来实现并还原真实企业开发中的实现思路 一.为什么做导入导出 为什么做导入导出 导入 在项目开发过程中,总会有一些统一的操作,例如插入数据,系统支持单个

  • Vue 项目中Echarts 5使用方法详解

    目录 前言 创建项目 基本使用 安装 使用方法 柱状图 动态排序柱状图 前言 Echarts 是一个纯JavaScript的图表库,兼容绝大部分的浏览器,底层依赖轻量级的canvas类库ZRender,提供直观,生动,可交互,可高度个性化定制的数据可视化图表. 创建项目 先使用vue-cli创建一个新的项目,配置按照自己的需要选择,默认的也可 vue create vue_echarts cd vue_echarts npm run serve 基本使用 安装 首先安装echarts npm i

  • vue+Element-ui实现分页效果实例代码详解

    当我们向后台请求大量数据的时候,并要在页面展示出来,请求的数据可能上百条数据或者更多的时候,并不想在一个页面展示,这就需要使用分页功能来去完成了. 1.本次所使用的是vue2.0+element-ui实现一个分页功能,element-ui这个组件特别丰富,分页中给我提供了一个Pagination 分页,使用Pagination 快速完成分页功能 最终效果展示 <div class="deit"> <div class="crumbs"> &l

  • vue组件之间的数据传递方法详解

    (1)props属性: 在父组件中,可以通过子组件标签属性的形式将数据或者函数传给子组件,子组件通过props去读取父组件传过来的数据 用法 父组件传数据给子组件: 一般的属性值都是用来给子组件展示的 子组件传数据给父组件 属性值为函数类型的,一般是用来子组件向父组件传递数据,子组件通过调用父组件传过来的函数,可以修改父组件的状态数据 缺点: 隔层组件间传递: 必须逐层传递(麻烦) 兄弟组件间: 必须借助父组件(麻烦) 注意: //子组件获取父组件传过来的值 props: { obj: {//o

  • Vue屏幕自适应三种实现方法详解

    目录 使用 scale-box 组件 设置设备像素比例(设备像素比) 通过JS设置zoom属性调整缩放比例 使用 scale-box 组件 属性: width宽度 默认1920 height高度 默认1080 bgc背景颜色 默认"transparent" delay自适应缩放防抖延迟时间(ms) 默认100 vue2版本:vue2大屏适配缩放组件(vue2-scale-box - npm) npm install vue2-scale-box 或者 yarn add vue2-sca

  • Vue父子组件属性传递实现方法详解

    目录 前言 组件之间属性的传递 父组件传递属性给子组件 子组件传递属性给父组件 前言 这节我们主要从案例出发,用Vue3的写法写父子组件之间的属性传递. 组件之间属性的传递 我们定义一个Rate组件,具有以下功能: 接收来自外部组件传入的参数,starCount代表星星个数.color代表星星颜色. 需要根据传入星星的个数,展示对应数量的星星. 父组件传递属性给子组件 那么在编写组件的时候,我们需要注意什么? 我们可以使用defineProps来规范传递数据的格式.可以结合withDefault

  • 对vue中v-if的常见使用方法详解

    使用过Vue的小伙伴一定使用过v-if 这个属性,但是这个属性主要是来干什么的呢,他得用途是那些? 这里我总结了一下,v-if使用一般有两个场景: 1- 多个元素 通过条件判断展示或者隐藏某个元素.或者多个元素 2- 进行两个视图之间的切换 下面我写了两个例子,是Vue官方的简单实例. 第一个实例实现了 type等于不同值,A,B,C 三个元素的展示情况. 第二个例子实现了,点击按钮实现两个视图的切换. <!DOCTYPE html> <html lang="en"&

随机推荐