HTML5实现3D球效果

效果图:

javascript 复制代码
<!DOCTYPE html>
<html>
<head>
	<meta name="format-detection" content="telephone=yes"/>
	<title>3d球型标签云</title>

</head>
<style>
    body {
    	background: #000
    }
    #main {
    	margin: 20px auto;
    	width: 450px;
    	height: 450px;
    	border: 1px solid green;
    	position: relative;
    	z-index: 10;
    }
    #main a {
    	position: absolute;
    	left: 0;
    	top: 0;
    	font-size: 15px;
    	font-weight: bolder;
    	text-decoration: none;
    	z-index: 9;
    }
    a:hover {
    	transform: scale(2);
    }
	.red {
		color: red;
	}
	.blue {
		color: blur;
	}
	.yellow {
		color: yellow;
	}
</style>
<body>
<div id="main"> 
	<a href="#">小仙女</a> 
	<a href="#" class="red">苹果</a> 
	<a href="#">香蕉</a> 
	<a href="#">西瓜</a> 
	<a href="#" class="blue">小仙女</a> 
	<a href="#">SEO</a> 
	<a href="#">小公主</a> 
	<a href="#" class="yellow">梨</a> 
	<a href="#">小泰迪</a> 
	<a href="#" class="red">CSS</a> 
	<a href="#">小猫咪</a> 
	<a href="#" class="blue">Java</a> 
	<a href="#">小度熊</a> 
	<a href="#">C#</a> 
	<a href="#">语言类别</a> 
	<a href="#" class="blue">西红柿</a> 
	<a href="#">C++</a> 
	<a href="#">C</a> 
	<a href="#">番茄</a> 
	<a href="#">demo</a>
</div> 
</body>
</html>
<script type="text/javascript">
document.getElementById('main').onclick=function() {
	window.location.hash = 'page';
	alert(11);
}

// 1.计算所有的标签在球面上的坐标
var main = document.getElementById('main');
var tagElement = document.getElementsByTagName('a');
var tagLength = tagElement.length;
var offsetList = [];
var radius = 120;
var tspeed = 10; 
var size = 250;
var active = false;
var d = 300;
var lasta = 1; 
var lastb = 1;
var mouseX = 0; 
var mouseY = 0; 


// 2.计算所有元素的offsetWidth,offsetHeight值
for (var i = 0; i < tagElement.length; i++) {
    offsetList.push({
    	offsetWidth: tagElement[i].offsetWidth,
    	offsetHeight: tagElement[i].offsetHeight
    });
};

calcXYZ();
// 鼠标移入事件
main.onmouseover = function (){ 
	active = true; 
}; 
// 鼠标移出事件
main.onmouseout = function () {
    active = false;
    // clearInterval(t);
}; 
main.onmousemove = function (event) {
	var e = window.event  || event; //兼容ie和其他浏览器的事件
	mouseX = (e.clientX - (main.offsetLeft + main.offsetWidth/2))/5;
    mouseY = (e.clientY - (main.offsetTop + main.offsetHeight/2))/5;
}
var t = setInterval(update, 30);




// 设置元素在球形坐标系的位置
function calcXYZ() {
	// var radomθ,radomΦ;
	for (var i = 0; i < tagElement.length; i++) {
		var radomθ = Math.acos(-1 + (2 * i)/tagLength); //θ = arccos(((2 * num)-1)/all - 1);
		var radomΦ = Math.sqrt(tagLength * Math.PI) * radomθ; //Φ = θ*sqrt(all * π);
		//x,y,z坐标的计算公式 x=r*sinθ*cosΦ   y=r*sinθ*sinΦ   z=r*cosθ;
		var x = radius * Math.sin(radomθ) * Math.cos(radomΦ);
		var y = radius * Math.sin(radomθ) * Math.sin(radomΦ);
		var z = radius * Math.cos(radomθ);
		offsetList[i].x = x;
		offsetList[i].y = y;
		offsetList[i].z = z;
		// 设置元素的位置
		tagElement[i].style.left = x + main.offsetWidth/2 - offsetList[i].offsetWidth/2 + 'px';
		tagElement[i].style.top = y + main.offsetHeight/2 - offsetList[i].offsetHeight/2 + 'px';
	}
}

// 计算中心点的sin,cos值
function sineCosine( a, b, c) {
    sa = Math.sin(a * (Math.PI/180));
    ca = Math.cos(a * (Math.PI/180)); 
    sb = Math.sin(b * (Math.PI/180));
    cb = Math.cos(b * (Math.PI/180));
    sc = Math.sin(c * (Math.PI/180));
    cc = Math.cos(c * (Math.PI/180));
}

// 球运动算法
function update() {
    var a, 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 < tagLength; j++) {
		var rx1 = offsetList[j].x;
		var ry1 = offsetList[j].y * ca + offsetList[j].z * (-sa);
		var rz1 = offsetList[j].y * sa + offsetList[j].z * 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;

		offsetList[j].x = rx3;
		offsetList[j].y = ry3;
		offsetList[j].z = rz3;

		per = d / (d + rz3);

		// offsetList[j].x=(howElliptical*rx3*per)-(howElliptical*2); 
		// offsetList[j].y=ry3*per; 
		// offsetList[j].scale=per; 
		offsetList[j].alpha = per;

		offsetList[j].alpha=(offsetList[j].alpha - 0.6)*(10/6); 
	} 
    doPosition();
// depthSort(); 
}


function doPosition() {
	// console.log(11);
    var l = main.offsetWidth/2;
    var t = main.offsetHeight/2;
    for(var i = 0; i < tagLength; i++) {
        tagElement[i].style.left = offsetList[i].x + l - offsetList[i].offsetWidth/2 + 'px';
        tagElement[i].style.top = offsetList[i].y + t - offsetList[i].offsetHeight/2 + 'px';
        // console.log(tagElement[i].style.left, tagElement[i].style.top)
        // tagElement[i].style.fontSize=Math.ceil(12*mcList[i].scale/2)+8+'px';

        // tagElement[i].style.filter="alpha(opacity="+100*mcList[i].alpha+")";
        tagElement[i].style.opacity = offsetList[i].alpha;
    }
} 
</script>
相关推荐
weixin_382395233 小时前
为小工厂量身打造:本地部署的物料管理系统带缺料计算
前端·制造
__zRainy__3 小时前
解决pnpm v10+不自动构建
前端·pnpm·工程化
猫猫不是喵喵.3 小时前
Vue3 Props 属性
前端·javascript·vue.js
醉城夜风~4 小时前
CSS元素显示模式(display)
前端·css
AI大模型-小华5 小时前
Codex 三方充值快速入门指南
java·前端·数据库·chatgpt·ai编程·codex·chatgpt pro
做前端的娜娜子7 小时前
同一链接实现 PC Web 与移动 H5 自适应
前端·掘金·金石计划
小帅不太帅8 小时前
架构没变、规模没变,DeepSeek V4 Flash 正式版凭什么暴涨 47 分?
前端·aigc·deepseek
jarvisuni8 小时前
DeepSeekFlash前端依旧拉垮,而且变慢了很多!
前端·javascript·算法
卷福同学9 小时前
AI编程出海第二步:验证关键词能否做站
前端·人工智能·后端