您现在的位置是:网站首页> 编程资料编程资料
【HTML5】3D模型--百行代码实现旋转立体魔方实例html5+css3实现酷炫的3D立方体旋转动画特效源码html5实现的适用于手机端3D图片旋转木马特效源码html5基于插件实现的3D电子书翻页效果源码html5基于canvas实现的文字标签云3D旋转动画特效源码html5基于canvas实现的酷炫3D线条动画背景特效源码一款利用html5和css3实现的3D立方体旋转效果教程
2023-10-13
367人已围观
简介 本篇文章主要介绍【HTML5】3D模型--百行代码实现旋转立体魔方实例,具有一定的参考价值,有需要的可以了解一下。
最近研究魔方的玩法,就突然想用HMTL5写一个魔方的模型,由于魔方是一个3D的立方体,这次就试着用HTML5写了一个简单的3D模型。
下面是预览画面。

制作流程
首先你需要下载Html5开源库件lufylegend-1.4.0
魔方分为6个面,每个面由9个小矩形组成,现在我把每个小矩形当做一个类封装起来,
因为现在建立的是一个3D魔方,所以要画出每个小矩形,需要知道小矩形的4个定点,而这4个定点会根据空间的旋转角度而变换,所以为了计算出这4个定点坐标,需要知道魔方绕x轴和z轴旋转的角度。
所以,建立矩形类如下
function Rect(pointA,pointB,pointC,pointD,angleX,angleZ,color){ base(this,LSprite,[]); this.pointZ=[(pointA[0]+pointB[0]+pointC[0]+pointD[0])/4,(pointA[1]+pointB[1]+pointC[1]+pointD[1])/4,(pointA[2]+pointB[2]+pointC[2]+pointD[2])/4]; this.z = this.pointZ[2]; this.pointA=pointA,this.pointB=pointB,this.pointC=pointC,this.pointD=pointD,this.angleX=angleX,this.angleZ=angleZ,this.color=color; } Rect.prototype.setAngle = function(a,b){ this.angleX = a; this.angleZ = b; this.z=this.getPoint(this.pointZ)[2]; }; pointA,pointB,pointC,pointD是小矩形的四个顶点,angleX,angleZ分别是x轴和z轴旋转的角度,color是小矩形的颜色。
魔方分为6个面,先看一下最前面的一面,如果以立方体的中心作为3D坐标系的中心,那么9个小矩形的各个定点所对应的坐标如下图所示

所以,前面这个面的9个小矩形可以由下面的代码来建立
for(var x=0;x<3;x++){ for(var y=0;y<3;y++){ z = 3; var rect = new Rect([-3*step + x*2*step,-3*step + y*2*step,-3*step + z*2*step],[-step + x*2*step,-3*step + y*2*step,-3*step + z*2*step],[-step + x*2*step,-step + y*2*step,-3*step + z*2*step],[-3*step + x*2*step,-step + y*2*step,-3*step + z*2*step],0,0,"#FF0000"); backLayer.addChild(rect); } } 其中backLayer是一个LSprite类,step是半个小矩形的长,同样的道理,可以也得到其他5个面。
6个面都建立了,在绘制这6个面之前,首先要根据旋转的角度来计算各个定点的坐标,看下面的图

根据上面的图,用下面的公式即可得到变换后的定点坐标
Rect.prototype.getPoint = function(p){ var u2,v2,w2,u=p[0],v=p[1],w=p[2]; u2 = u * Math.cos(this.angleX) - v * Math.sin(this.angleX); v2 = u * Math.sin(this.angleX) + v * Math.cos(this.angleX); w2 = w; u = u2; v = v2; w = w2; u2 = u; v2 = v * Math.cos(this.angleZ) - w * Math.sin(this.angleZ); w2 = v * Math.sin(this.angleZ) + w * Math.cos(this.angleZ); u = u2; v = v2; w = w2; return [u2,v2,w2]; }; 最后根据小矩形的四个定点坐标,来绘制这个矩形,
Rect.prototype.draw = function(layer){ this.graphics.clear(); this.graphics.drawVertices(1,"#000000",[this.getPoint(this.pointA),this.getPoint(this.pointB),this.getPoint(this.pointC),this.getPoint(this.pointD)],true,this.color); }; 其中drawVertices是lufylegend.js库件中LGraphics类的一个方法,它可以根据传入的定点坐标数组来绘制一个多边形。
最后,给出完整代码,代码很少,JS代码一共91行。
一,index.html
3D魔方 loading……
二,Rect类
function Rect(pointA,pointB,pointC,pointD,angleX,angleZ,color){ base(this,LSprite,[]); this.pointZ=[(pointA[0]+pointB[0]+pointC[0]+pointD[0])/4,(pointA[1]+pointB[1]+pointC[1]+pointD[1])/4,(pointA[2]+pointB[2]+pointC[2]+pointD[2])/4]; this.z = this.pointZ[2]; this.pointA=pointA,this.pointB=pointB,this.pointC=pointC,this.pointD=pointD,this.angleX=angleX,this.angleZ=angleZ,this.color=color; } Rect.prototype.draw = function(layer){ this.graphics.clear(); this.graphics.drawVertices(1,"#000000",[this.getPoint(this.pointA),this.getPoint(this.pointB),this.getPoint(this.pointC),this.getPoint(this.pointD)],true,this.color); }; Rect.prototype.setAngle = function(a,b){ this.angleX = a; this.angleZ = b; this.z=this.getPoint(this.pointZ)[2]; }; Rect.prototype.getPoint = function(p){ var u2,v2,w2,u=p[0],v=p[1],w=p[2]; u2 = u * Math.cos(this.angleX) - v * Math.sin(this.angleX); v2 = u * Math.sin(this.angleX) + v * Math.cos(this.angleX); w2 = w; u = u2; v = v2; w = w2; u2 = u; v2 = v * Math.cos(this.angleZ) - w * Math.sin(this.angleZ); w2 = v * Math.sin(this.angleZ) + w * Math.cos(this.angleZ); u = u2; v = v2; w = w2; return [u2,v2,w2]; }; 三,Main.js
init(50,"mylegend",400,400,main); var a = 0,b=0,backLayer,step = 20,key = null; function main(){ backLayer = new LSprite(); addChild(backLayer); backLayer.x = 120,backLayer.y = 120; //后 for(var x=0;x<3;x++){ for(var y=0;y<3;y++){ z = 0; var rect = new Rect([-3*step + x*2*step,-3*step + y*2*step,-3*step + z*2*step],[-step + x*2*step,-3*step + y*2*step,-3*step + z*2*step],[-step + x*2*step,-step + y*2*step,-3*step + z*2*step],[-3*step + x*2*step,-step + y*2*step,-3*step + z*2*step],0,0,"#FF4500"); backLayer.addChild(rect); } } //前 for(var x=0;x<3;x++){ for(var y=0;y<3;y++){ z = 3; var rect = new Rect([-3*step + x*2*step,-3*step + y*2*step,-3*step + z*2*step],[-step + x*2*step,-3*step + y*2*step,-3*step + z*2*step],[-step + x*2*step,-step + y*2*step,-3*step + z*2*step],[-3*step + x*2*step,-step + y*2*step,-3*step + z*2*step],0,0,"#FF0000"); backLayer.addChild(rect); } } //上 for(var x=0;x<3;x++){ for(var z=0;z<3;z++){ y = 0; var rect = new Rect([-3*step + x*2*step,-3*step + y*2*step,-3*step + z*2*step],[-step + x*2*step,-3*step + y*2*step,-3*step + z*2*step],[-step + x*2*step,-3*step + y*2*step,-step + z*2*step],[-3*step + x*2*step,-3*step + y*2*step,-step + z*2*step],0,0,"#FFFFFF"); backLayer.addChild(rect); } } //下 for(var x=0;x<3;x++){ for(var z=0;z<3;z++){ y = 3; var rect = new Rect([-3*step + x*2*step,-3*step + y*2*step,-3*step + z*2*step],[-step + x*2*step,-3*step + y*2*step,-3*step + z*2*step],[-step + x*2*step,-3*step + y*2*step,-step + z*2*step],[-3*step + x*2*step,-3*step + y*2*step,-step + z*2*step],0,0,"#FFFF00"); backLayer.addChild(rect); } } //左 for(var y=0;y<3;y++){ for(var z=0;z<3;z++){ x = 0; var rect = new Rect([-3*step + x*2*step,-3*step + y*2*step,-3*step + z*2*step],[-3*step + x*2*step,-3*step + y*2*step,-step + z*2*step],[-3*step + x*2*step,-step + y*2*step,-step + z*2*step],[-3*step + x*2*step,-step + y*2*step,-3*step + z*2*step],0,0,"#008000"); backLayer.addChild(rect); } } //右 for(var y=0;y<3;y++){ for(var z=0;z<3;z++){ x = 3; var rect = new Rect([-3*step + x*2*step,-3*step + y*2*step,-3*step + z*2*step],[-3*step + x*2*step,-3*step + y*2*step,-step + z*2*step],[-3*step + x*2*step,-step + y*2*step,-step + z*2*step],[-3*step + x*2*step,-step + y*2*step,-3*step + z*2*step],0,0,"#0000FF"); backLayer.addChild(rect); } } backLayer.addEventListener(LEvent.ENTER_FRAME,onframe); } function onframe(){ a += 0.1 , b += 0.1; backLayer.childList = backLayer.childList.sort(function(a,b){return a.z - b.z;}); for(key in backLayer.childList){ backLayer.childList[key].setAngle(a,b); backLayer.childList[key].draw(backLayer); } } 这只是一个非常简陋的3D模型,希望对大家的学习有所帮助,也希望大家多多支持。
相关内容
- HTML5拖放API实现拖放排序的实例代码HTML5 拖放(Drag 和 Drop)详解与实例代码HTML5中的拖放实现详解HTML5拖放效果的实现代码HTML5 拖放功能实现代码 HTML5逐步分析实现拖放功能的方法
- Web前端页面跳转并取到值如何使用URL跳转解决Web服务80端口被屏蔽的问题?使用CSS中的meta实现web定时刷新或跳转的方法
- HTML5新特性 多线程(Worker SharedWorker)HTML5 Web Workers之网站也能多线程的实现浅谈Html5多线程开发之WebWorkers
- 全民英雄斧王卡牌好用吗 斧王卡牌属性介绍_手机游戏_游戏攻略_
- 全民英雄剑圣进化品质及升级条件说明 全民英雄剑圣怎么进化_手机游戏_游戏攻略_
- 全民英雄剑圣获得方法 全民英雄剑圣哪里出_手机游戏_游戏攻略_
- 全民英雄火女与死亡先知究竟哪个好_手机游戏_游戏攻略_
- 全民英雄1.5倍经验怎么购买 新手快速升级攻略心得_手机游戏_游戏攻略_
- 全民英雄怎么刷装备 全民英雄装备掉落攻略心得_手机游戏_游戏攻略_
- 全民英雄活力恢复及获取方法汇总_手机游戏_游戏攻略_
