javascript实现动态标签云


Posted in Javascript onOctober 16, 2015

今天上学校的图书馆,看到了一个好玩的东西,特意百度了下,发现叫做“标签球”,效果图为:

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; font-weight:bold; text-decoration:none; padding: 3px 6px; }
#div1 a:hover {border: 1px solid #eee; background: #FFF; }
#div1 .blue {color:blue;}
#div1 .red {color:red;}
#div1 .green {color:green;}

HTML:

<div id="div1">
  <a href="#">标签云</a>
  <a href="#" class="red">PHP</a>
  <a href="#">瀑布流</a>
  <a href="#">Tab</a>
  <a href="#" class="blue">流体布局</a>
  <a href="#">SEO</a>
  <a href="#" class="red">彩蛋</a>
  <a href="#" class="green">JavaScript</a>
  <a href="#">miaov</a>
  <a href="#" class="red">CSS</a>
  <a href="#">asp.net</a>
  <a href="#" class="blue">蓝色经典</a>
  <a href="#">OOP</a>
  <a href="#" class="red">Android</a>
  <a href="#" class="blue">妙味茶馆</a>
  <a href="#">dialog</a>
  <a href="#" class="blue">淘客</a>
  <a href="#">Pin</a>
  <a href="#">微博</a>
  <a href="#" class="green">IPhone</a>
</div>

JS

$(document).ready(function() {
  $("#div1").windstagball({
      radius:120,
      speed:10
    });
  });

首先得写好布局,最外层div样式position设置为relative

内层元素position为absolute,这样才能形成效果,top为0,left为0
先导入jquery文件,再导入相应的插件文件
获取$("#xxx")元素,并调用windstagball()函数,radius是标签球的变径大小,speed顾名思义就是运动的速度。

附上js插件

var radius = 120;
var dtr = Math.PI/180;
var d=300;

var mcList = [];
var active = false;
var lasta = 1;
var lastb = 1;
var distr = true;
var tspeed=10;
var size=250;

var mouseX=0;
var mouseY=0;

var howElliptical=1;

var aA=null;
var oDiv=null;

window.onload=function ()
{
	var i=0;
	var oTag=null;
	
	oDiv=document.getElementById('div1');
	
	aA=oDiv.getElementsByTagName('a');
	
	for(i=0;i<aA.length;i++)
	{
		oTag={};
		
		oTag.offsetWidth=aA[i].offsetWidth;
		oTag.offsetHeight=aA[i].offsetHeight;
		
		mcList.push(oTag);
	}
	
	sineCosine( 0,0,0 );
	
	positionAll();
	
	oDiv.onmouseover=function ()
	{
		active=true;
	};
	
	oDiv.onmouseout=function ()
	{
		active=false;
	};
	
	oDiv.onmousemove=function (ev)
	{
		var oEvent=window.event || ev;
		
		mouseX=oEvent.clientX-(oDiv.offsetLeft+oDiv.offsetWidth/2);
		mouseY=oEvent.clientY-(oDiv.offsetTop+oDiv.offsetHeight/2);
		
		mouseX/=5;
		mouseY/=5;
	};
	
	setInterval(update, 30);
};

function update()
{
	var a;
	var b;
	
	if(active)
	{
		a = (-Math.min( Math.max( -mouseY, -size ), size ) / radius ) * tspeed;
		b = (Math.min( Math.max( -mouseX, -size ), size ) / radius ) * tspeed;
	}
	else
	{
		a = lasta * 0.98;
		b = lastb * 0.98;
	}
	
	lasta=a;
	lastb=b;
	
	if(Math.abs(a)<=0.01 && Math.abs(b)<=0.01)
	{
		return;
	}
	
	var c=0;
	sineCosine(a,b,c);
	for(var j=0;j<mcList.length;j++)
	{
		var rx1=mcList[j].cx;
		var ry1=mcList[j].cy*ca+mcList[j].cz*(-sa);
		var rz1=mcList[j].cy*sa+mcList[j].cz*ca;
		
		var rx2=rx1*cb+rz1*sb;
		var ry2=ry1;
		var rz2=rx1*(-sb)+rz1*cb;
		
		var rx3=rx2*cc+ry2*(-sc);
		var ry3=rx2*sc+ry2*cc;
		var rz3=rz2;
		
		mcList[j].cx=rx3;
		mcList[j].cy=ry3;
		mcList[j].cz=rz3;
		
		per=d/(d+rz3);
		
		mcList[j].x=(howElliptical*rx3*per)-(howElliptical*2);
		mcList[j].y=ry3*per;
		mcList[j].scale=per;
		mcList[j].alpha=per;
		
		mcList[j].alpha=(mcList[j].alpha-0.6)*(10/6);
	}
	
	doPosition();
	depthSort();
}

function depthSort()
{
	var i=0;
	var aTmp=[];
	
	for(i=0;i<aA.length;i++)
	{
		aTmp.push(aA[i]);
	}
	
	aTmp.sort
	(
		function (vItem1, vItem2)
		{
			if(vItem1.cz>vItem2.cz)
			{
				return -1;
			}
			else if(vItem1.cz<vItem2.cz)
			{
				return 1;
			}
			else
			{
				return 0;
			}
		}
	);
	
	for(i=0;i<aTmp.length;i++)
	{
		aTmp[i].style.zIndex=i;
	}
}

function positionAll()
{
	var phi=0;
	var theta=0;
	var max=mcList.length;
	var i=0;
	
	var aTmp=[];
	var oFragment=document.createDocumentFragment();
	
	//随机排序
	for(i=0;i<aA.length;i++)
	{
		aTmp.push(aA[i]);
	}
	
	aTmp.sort
	(
		function ()
		{
			return Math.random()<0.5?1:-1;
		}
	);
	
	for(i=0;i<aTmp.length;i++)
	{
		oFragment.appendChild(aTmp[i]);
	}
	
	oDiv.appendChild(oFragment);
	
	for( var i=1; i<max+1; i++){
		if( distr )
		{
			phi = Math.acos(-1+(2*i-1)/max);
			theta = Math.sqrt(max*Math.PI)*phi;
		}
		else
		{
			phi = Math.random()*(Math.PI);
			theta = Math.random()*(2*Math.PI);
		}
		//坐标变换
		mcList[i-1].cx = radius * Math.cos(theta)*Math.sin(phi);
		mcList[i-1].cy = radius * Math.sin(theta)*Math.sin(phi);
		mcList[i-1].cz = radius * Math.cos(phi);
		
		aA[i-1].style.left=mcList[i-1].cx+oDiv.offsetWidth/2-mcList[i-1].offsetWidth/2+'px';
		aA[i-1].style.top=mcList[i-1].cy+oDiv.offsetHeight/2-mcList[i-1].offsetHeight/2+'px';
	}
}

function doPosition()
{
	var l=oDiv.offsetWidth/2;
	var t=oDiv.offsetHeight/2;
	for(var i=0;i<mcList.length;i++)
	{
		aA[i].style.left=mcList[i].cx+l-mcList[i].offsetWidth/2+'px';
		aA[i].style.top=mcList[i].cy+t-mcList[i].offsetHeight/2+'px';
		
		aA[i].style.fontSize=Math.ceil(12*mcList[i].scale/2)+8+'px';
		
		aA[i].style.filter="alpha(opacity="+100*mcList[i].alpha+")";
		aA[i].style.opacity=mcList[i].alpha;
	}
}

function sineCosine( a, b, c)
{
	sa = Math.sin(a * dtr);
	ca = Math.cos(a * dtr);
	sb = Math.sin(b * dtr);
	cb = Math.cos(b * dtr);
	sc = Math.sin(c * dtr);
	cc = Math.cos(c * dtr);
}
Javascript 相关文章推荐
javascript getElementsByTagName
Jan 31 Javascript
Jquery中children与find之间的区别详细解析
Nov 29 Javascript
JavaScript使用Max函数返回两个数字中较大数的方法
Apr 06 Javascript
js实现超简单的展开、折叠目录代码
Aug 28 Javascript
js获取Get值的方法
Sep 29 Javascript
javascript滚轮事件基础实例讲解(37)
Feb 14 Javascript
Vue filters过滤器的使用方法
Jul 14 Javascript
jQuery zTree 异步加载添加子节点重复问题
Nov 29 jQuery
仿淘宝JSsearch搜索下拉深度用法
Jan 15 Javascript
微信小程序实现提交input信息到后台的方法示例
Jan 19 Javascript
vue 列表页跳转详情页获取id以及详情页通过id获取数据
Mar 27 Javascript
JavaScript实现五子棋小游戏
Oct 26 Javascript
在Ubuntu系统上安装Node.JS的教程
Oct 15 #Javascript
jquery实现简单实用的弹出层效果代码
Oct 15 #Javascript
简单谈谈node.js 版本控制 nvm和 n
Oct 15 #Javascript
jQuery实现仿QQ在线客服效果的滚动层代码
Oct 15 #Javascript
JS实现选中当前菜单后高亮显示的导航条效果
Oct 15 #Javascript
JS+CSS实现另类带提示效果的竖向导航菜单
Oct 15 #Javascript
JS利用cookie记忆当前位置的防刷新导航效果
Oct 15 #Javascript
You might like
PHP 读取文件内容代码(txt,js等)
2009/12/06 PHP
PHP实现HTTP断点续传的方法
2015/06/17 PHP
PHP+Apache+Mysql环境搭建教程
2016/08/01 PHP
PHP递归删除多维数组中的某个值
2017/04/17 PHP
JQuery 无废话系列教程(二) jquery实战篇上
2009/06/23 Javascript
jquery序列化表单去除指定元素示例代码
2014/04/10 Javascript
JQuery表格拖动调整列宽效果(自己动手写的)
2014/09/01 Javascript
drag-and-drop实现图片浏览器预览
2015/08/06 Javascript
Bootstrap网格系统详解
2016/04/26 Javascript
js和C# 时间日期格式转换的简单实例
2016/05/28 Javascript
JavaScript判断微信浏览器实例代码
2016/06/13 Javascript
JavaScript高仿支付宝倒计时页面及代码实现
2016/10/21 Javascript
详解前端自动化工具gulp自动添加版本号
2016/12/20 Javascript
原生js实现倒计时--2018
2017/02/21 Javascript
Vue2.0使用过程常见的一些问题总结学习
2017/04/10 Javascript
Webpack如何引入bootstrap的方法
2017/06/17 Javascript
jQuery实现导航栏头部菜单项点击后变换颜色的方法
2017/07/19 jQuery
js链表操作(实例讲解)
2017/08/29 Javascript
说说node中的可读流和可写流的区别
2018/06/01 Javascript
vue实现父子组件之间的通信以及兄弟组件的通信功能示例
2019/01/29 Javascript
JavaScript:ES2019 的新特性(译)
2019/08/08 Javascript
Vue文本模糊匹配功能如何实现
2020/07/30 Javascript
nodejs+express最简易的连接数据库的方法
2020/12/23 NodeJs
[00:12]DAC2018 Miracle-站上中单舞台,他能否再写奇迹?
2018/04/06 DOTA
[44:40]Serenity vs Pain 2018国际邀请赛小组赛BO2 第一场 8.19
2018/08/21 DOTA
Python批量更改文件名的实现方法
2017/10/29 Python
浅谈python常用程序算法
2019/03/22 Python
Python如何绘制日历图和热力图
2020/08/07 Python
Python实现定时监测网站运行状态的示例代码
2020/09/30 Python
KTV的创业计划书范文
2014/02/02 职场文书
网页美工求职信
2014/02/15 职场文书
房产继承公证书
2014/04/09 职场文书
王金山在党的群众路线教育实践活动总结大会上的讲话稿
2014/10/25 职场文书
2015年世界卫生日活动总结
2015/02/09 职场文书
安全保证书格式
2015/02/28 职场文书
如何理解Vue前后端数据交互与显示
2021/05/10 Vue.js