实现思路
本案例主要实现两个功能:
- 鼠标拖拽使球体旋转;
- 鼠标轮滚动进入球体内部;
核心:球体形成思路
html
<div class="stage">
<div class="unit">
//<div class=".ball"> 组成球体的一个个小长方形
</div>
</div>
原理
- 把球体分为一层一层,以直径这层为基础,给其加上样式transform:rotateX(),区间为[-90ded,90deg],注意,层数*每一层旋转角度 = 90deg 由此一层一层的组成一个球体;
- 球体直径这层如何形成:若干个长方形,叠加在一起(绝对定位),每一个都加上样式:transform:rotateZ(radius) transformY(radius/长方形数量);注意长方形沿Y轴旋转角度为 360/数量*所在位置 即形成以radius为半径的圆环;
以上涉及物理空间想象,必要时请画图作以辅助
-
数量过多,可利用js组件DOM(这里引入jquery)
//这个函数为创建半个圆,half为1时创建半圆,为-1创建下半圆 function half(flag) { for (var i = 0; i < framefloor[j]; i++) { $("<div class='ball'></div>").css( { **//!!!!!!!!!!注意这里 非常非常重要 必须先X后Y 先变化x在变化Y 和先变化Y在变化X 最后呈现的是两种不同的结果!!!!!!!!!!!!!!!!!!!!** "transform":"rotateY(" + 360 / framefloor[j] * i + "deg) rotateX(" + 90/(floor-1) * j*flag + "deg) translateZ("+ r+"px)", "background" : "rgb(" + parseInt(Math.random() * 255) + "," + parseInt(Math.random() * 255) + "," + parseInt(Math.random() * 255) + ")" } ).appendTo($unit); } }
-
.unit是运动单元,即球体之后的运动和拉伸以它为主体。
-
呈现3d效果时,要在运动元素的父元素上加上perspective属性。
这个属性的含义,我的理解是,假设屏幕外你的眼睛是定点,perspective的值即是你的眼睛到图像的距离。
所以,首先.unit和.stage得加上perspective属性。
事件
-
“滚动鼠标进入球体内部原理”:鼠标滚动时改变.stage的perspective属性值,当其小于球体半径时,即出现进入到球体内部的效果
$document.mousewheel(function (event,delta) { //滚轮向上滚 delta值为-1 向下值为1 //阻止鼠标滚轮的默认事件 event.preventDefault(); $(".stage").css({ "perspective": (a-=delta*15) + "px", }) })
-
拖拽鼠标 球体旋转:
var drag=function(obj){ $document.bind("mousedown",start); function start(event){ if(event.button==0){//判断是否点击鼠标左键 /* * clientX和clientY代表鼠标当前的横纵坐标 * bind()绑定事件,同样unbind解绑定,此效果的实现最后必须要解绑定,否则鼠标松开后拖拽效果依然存在 */ //movemove事件必须绑定到$(document)上,鼠标移动是在整个屏幕上的 gapx = event.clientX; gapy = event.clientY; $(document).bind("mousemove",move); //此处的$(document)可以改为obj $(document).bind("mouseup",stop); } return false;//阻止默认事件或冒泡 } function move(event){ console.log(event.clientX) console.log(event.clientY) obj.css({ "transform":"rotateX("+(event.clientX-gapx)/10+"deg) rotateY("+(event.clientY-gapy)/10+"deg)", }); return false;//阻止默认事件或冒泡 } function stop(){ //解绑定,这一步很必要 $(document).unbind("mousemove",move); $(document).unbind("mouseup",stop); } } drag($unit);//传入的必须是jQuery对象,否则不能调用jQuery的自定义函数
完整代码
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Title</title><style>*{margin:0;padding:0}html,body{height:100%;background:lightgray}.stage{width:100%;height:100%;margin:auto auto;perspective:800px}.unit{width:100%;height:100%;position:relative;transform-style:preserve-3d}.ball{width:100px;height:20px;position:absolute;opacity:.6;top:50%;left:50%;margin-top:-50px;margin-left:-30px;border-radius:50%}</style></head><body><div class="stage"><div class="unit"></div></div><script src="../js/jquery-3.3.1.min.js"></script><script src="../js/jquery.mousewheel.min.js"></script><script>$document = $(document);$unit = $(".unit");//每一层小ball组件的个数,写入数组 var framefloor = [24,22,20,18,18,12,10,8,4,1];//层数 var floor = framefloor.length;//舞台的默认景深perspective var a = parseInt($(".stage").css("perspective"));circle(framefloor,350);// 参数 每层的组件数量(数组) 半径(默认为 300) function circle(framefloor,r){//半径 var r = r||300;//构造上下半球 for(var j=0;j<floor;j++){half(1);if(j == 0) continue;half(-1)}function half(flag){for(var i = 0;i < framefloor[j];i++){$("<div class='ball'></div>").css({//注意这里 先变化x在变化Y 和先变化Y在变化X 最后呈现的是两种不同的结果 "transform":"rotateY("+360 / framefloor[j] * i+"deg) rotateX("+90/(floor-1) * j*flag+"deg) translateZ("+r+"px)","background":"rgb("+parseInt(Math.random() * 255)+","+parseInt(Math.random() * 255)+","+parseInt(Math.random() * 255)+")"}).appendTo($unit)}}}// 拖拽函数 var drag=function(obj){$document.bind("mousedown",start);function start(event){if(event.button==0){//判断是否点击鼠标左键 //movemove事件必须绑定到$(document)上,鼠标移动是在整个屏幕上的 gapx = event.clientX;gapy = event.clientY;$(document).bind("mousemove",move);//此处的$(document)可以改为obj $(document).bind("mouseup",stop)}return false;//阻止默认事件或冒泡}function move(event){console.log(event.clientX) console.log(event.clientY) obj.css({"transform":"rotateX("+(event.clientX-gapx)/10+"deg) rotateY("+(event.clientY-gapy)/10+"deg)",});return false;//阻止默认事件或冒泡}function stop(){//解绑定,这一步很必要 $(document).unbind("mousemove",move);$(document).unbind("mouseup",stop)}}drag($unit);//传入的必须是jQuery对象,否则不能调用jQuery的自定义函数 console.log($unit) $document.mousewheel(function(event,delta){event.preventDefault();$(".stage").css({"perspective":(a-=delta*15)+"px",})}) // for(var i = 0;i < 10;i++){// $("<div class=\"ball\"></div>").css({// "transform":"rotateX("+(-45)+"deg) rotateY("+36 * i+"deg) translateZ("+300+"px)",// "background":"rgb("+parseInt(Math.random() * 256)+","+"parseInt(Math.random()*256)"+","+parseInt(Math.random() * 256)+")",//}).appendTo($(".unit")) // $("<div class=\"ball\"></div>").css({// "transform":"rotateX("+(45)+"deg) rotateY("+36 * i+"deg) translateZ("+300+"px)",// "background":"rgb("+parseInt(Math.random() * 256)+","+"parseInt(Math.random()*256)"+","+parseInt(Math.random() * 256)+")",//}).appendTo($(".unit")) //}</script></body></html>