栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > Web开发 > JavaScript

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

JavaScript 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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

本文实例讲述了深入解析JS实现3D标签云的原理与方法。分享给大家供大家参考,具体如下:

最近开始用canvas搞3D了,搞得也是简单的东西,就是球体转圈。做出来后,突然想起以前看过的3D标签云,在以前觉得真心狂拽酷炫叼啊,当时也确实不知道怎么在平面上模拟3D,所以也就没去搞了。现在刚好用了canvas搞3D,也发现,好像3D标签云也差不多,然后就写了一下。

具体怎么做呢,先说一下原理,3D标签云就是做一个球面,然后再球面上取均匀分布的点,把点坐标赋给标签,再根据抽象出来的Z轴大小来改变标签的字体大小,透明度,做出立体感觉,然后球体就做好了。关键代码就下面这几句:

function innit(){
  for(var i=0;i

上面的代码是用于生成球面上的点的x,y,z轴的坐标。用到的就是简单的球面方程:已知半径r和球心,一般为了方便,我们都以坐标轴原点为球心,有下面三个方程

 x=r*sinθ*cosΦ   y=r*sinθ*sinΦ   z=r*cosθ;

也就是说,我们可以对θ和Φ取随机数,来获得圆上的随机点坐标。但仅此还不够,因为如果要做3D标签云,一个很重要点的就是平均分布。如果单纯的取随机坐标,会导致一些标签重叠,相对来说就没那么美观了。所以我们引入第二个公式:

θ = arccos( ((2*num)-1)/all - 1);
Φ = θ*sqrt(all * π);

num是当前第几个点,all则是点的总数。这个公式的是我在别人的代码里找到的,我也不懂原理。不过确实好用。

有了上面两个公式以后,我们就可以获得球面上所需要的平均分布的点。然后再对每个标签进行操作:

var scale = fallLength/(fallLength-this.z);
var alpha = (this.z+RADIUS)/(2*RADIUS);
this.ele.style.fontSize = 15 * scale + "px";
this.ele.style.opacity = alpha+0.5;
this.ele.style.filter = "alpha(opacity = "+(alpha+0.5)*100+")";
this.ele.style.zIndex = parseInt(scale*100);
this.ele.style.left = this.x + CX - this.ele.offsetWidth/2 +"px";
this.ele.style.top = this.y + CY - this.ele.offsetHeight/2 +"px";

fallLength是焦距,也就是一个常量,scale和alpha都是要根据z轴来调整的比例。后面的属性操作就比较简单了,调整一下字体大小,透明度,以及元素位置,球体就做出来了,效果如下(忽略字的内容,乱写的):

球体做出来了,是时候让其动起来了。这时就引入第三个公式了,矩阵旋转算法:

还可以直接戳 计算机图形学3D变换;

然后,我们就可以写出两个函数,一个是绕X轴旋转,一个是绕Y轴旋转。

function rotateX(){
  var cos = Math.cos(angleX);
  var sin = Math.sin(angleX);
  tags.forEach(function(){
    var y1 = this.y * cos - this.z * sin;
    var z1 = this.z * cos + this.y * sin;
    this.y = y1;
    this.z = z1;
  })
  
}
function rotateY(){
  var cos = Math.cos(angleY);
  var sin = Math.sin(angleY);
  tags.forEach(function(){
    var x1 = this.x * cos - this.z * sin;
    var z1 = this.z * cos + this.x * sin;
    this.x = x1;
    this.z = z1;
  })
}

然后就可以通过控制angleX和angleY两个角度的值来控制标签云的旋转方向以及旋转速度,角度的正负值控制旋转方向,大小控制旋转速度。

接下来就可以用鼠标事件来控制了:

if("addEventListener" in window){
  paper.addEventListener("mousemove" , function(event){
    var x = event.clientX - EX - CX;
    var y = event.clientY - EY - CY;
    // angleY = -x* (Math.sqrt(Math.pow(x , 2) + Math.pow(y , 2)) > RADIUS/4 ? 0.0002 : 0.0001);
    // angleX = -y* (Math.sqrt(Math.pow(x , 2) + Math.pow(y , 2)) > RADIUS/4 ? 0.0002 : 0.0001);
    angleY = x*0.0001;
    angleX = y*0.0001;
  });
}
else {
  paper.attachEvent("onmousemove" , function(event){
    var x = event.clientX - EX - CX;
    var y = event.clientY - EY - CY;
    angleY = x*0.0001;
    angleX = y*0.0001;
  });
}

当这个也写好后,3D标签云就算完工了,完成效果就直接看DEMO吧:3D标签云;

下面贴出标签云的所有代码,其实都可以通过控制台看代码,不过还是贴一下吧:(本人技术不是很好,代码写的不好请见谅)




  
  
    .tagBall{
      width: 800px;
      height: 800px;
      margin:50px auto;
      position: relative;
    }
    .tag{
      display: block;
      position: absolute;
      left: 0px;
      top: 0px;
      color: #000;
      text-decoration: none;
      font-size: 15px;
      font-family: "微软雅黑";
      font-weight: bold;
    }
    .tag:hover{border:1px solid #666;}
  
  3D标签


  
    某某某
    我喜欢你
    某某某
    我喜欢你
    某某某
    我喜欢你
    某某某
    我喜欢你
    某某某
    我喜欢你
    某某某
    我喜欢你
    某某某
    我喜欢你
    某某某
    我喜欢你
    某某某
    我喜欢你
    某某某
    我喜欢你
    某某某
    我喜欢你
    某某某
    我喜欢你
    我喜欢你
    某某某
    我喜欢你
    某某某
    我喜欢你
    某某某
    我喜欢你
    我喜欢你
    某某某
    我喜欢你
    某某某
    我喜欢你
    我喜欢你
    某某某
    我喜欢你
    某某某
    我喜欢你
    某某某
    我喜欢你
    我喜欢你
    某某某
    我喜欢你
  
  



或者直接看github源码:

https://github.com/whxaxes/canvas-test/blob/gh-pages/src/3D-demo/3Dtag.html

更多关于Javascript相关内容感兴趣的读者可查看本站专题:《Javascript切换特效与技巧总结》、《Javascript查找算法技巧总结》、《Javascript动画特效与技巧汇总》、《Javascript错误与调试技巧总结》、《Javascript数据结构与算法技巧总结》及《Javascript数学运算用法总结》

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

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/74080.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号