CSS3实现3D球体运动

@CSS3实现3D球体运动

实现思路

本案例主要实现两个功能:

  • 鼠标拖拽使球体旋转;
  • 鼠标轮滚动进入球体内部;

核心:球体形成思路

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>
发布了9 篇原创文章 · 获赞 0 · 访问量 297

猜你喜欢

转载自blog.csdn.net/qq_41402809/article/details/99098597