如何使用HTML5实现3D衣服摇摆动画特效
发表于:2024-09-22 作者:千家信息网编辑
千家信息网最后更新 2024年09月22日,今天就跟大家聊聊有关如何使用HTML5实现3D衣服摇摆动画特效,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。这又是一款基于HTML5 Canv
千家信息网最后更新 2024年09月22日如何使用HTML5实现3D衣服摇摆动画特效
今天就跟大家聊聊有关如何使用HTML5实现3D衣服摇摆动画特效,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。
这又是一款基于HTML5 Canvas的3D动画杰作,它是一个可以随风飘动的3D衣服摇摆动画特效,非常逼真。当我们将鼠标滑过衣服时,衣服将会出现摇摆的动画,点击鼠标时,衣服将会更加剧烈地摆动。
HTML代码
XML/HTML Code复制内容到剪贴板
"3D on 2D Canvas" demo
move cursor to pan / click to swing
3D衣服动画JS代码
JavaScript Code复制内容到剪贴板
function ClothApp() { this.canvas = document.getElementById("cv"); P3D.g = this.canvas.getContext("2d"); var tex = new Image(); this.texture1 = tex; tex.onload = function(){ _this.start(); }; tex.src = "20090226032826.gif"; tex = new Image(); this.texture2 = tex; tex.onload = function(){ _this.start(); }; tex.src = "20090226032825.png"; this.mLoadCount = 2; this.mTickCount = 0; this.G = 0.53; this.G1 = 0.45; this.mProjMat = null; this.mViewMat = null; this.mViewFrom = new Vec3(); this.mViewFrom.y = -150; this.mViewFrom.z = 1000; this.mViewFromA = (new Vec3()).copyFrom(this.mViewFrom); this.mViewAngle = 0; this.mNLen = 0; this.mNodes = []; this.mRenderTris = null; this.mLTNode = null; this.mRTNode = null; this.mLTNodeV = new Vec3(); this.mRTNodeV = new Vec3(); this.mWForce = new Vec3(); this.frate = 15; var _this = this; } ClothApp.zsortCmp = function(t1, t2) { return t2.sortKey - t1.sortKey; } ClothApp.prototype = { start: function() { if (--this.mLoadCount != 0) return; this.vUP = new Vec3(0, 1, 0); this.vAT = new Vec3(0, 80, 0); this.mViewport = {}; this.mViewport.w = 480; this.mViewport.h = 300; this.mViewport.ow = 240; this.mViewport.oh = 150; this.setupTransforms(); this.generateCloth(180); this.generateRenderTriangles(); var _this = this; this.canvas.addEventListener("mousemove", function(e){_this.onMouseMove(e);}, false); this.canvas.addEventListener("mousedown", function(e){_this.onClick(e);}, false); window.setTimeout(function(){_this.onInterval();}, this.frate); }, onInterval: function() { this.mTickCount++; // this.mLTNodeV.z = Math.cos(this.mTickCount*0.1) * 2; this.tick(); this.updatePosition(); this.draw(); var _this = this; window.setTimeout(function(){_this.onInterval();}, this.frate); }, onMouseMove: function(e) { if (e.clientX || e.clientX == 0) this.mViewAngle = (e.clientX - 240) * 0.004; if (e.clientY || e.clientY == 0) this.mViewFromA.y = 90 - (e.clientY - 0) * 0.8; }, onClick: function(e) { if (e.clientX || e.clientX == 0) { this.mWForce.z = -4; this.mWForce.x = (e.clientX - 240) * -0.03; } }, tick: function() { this.updateViewTrans(this.mViewAngle); var nlen = this.mNodes.length; var i, nd; for(i = 0;i < nlen;i++) { nd = this.mNodes[i]; nd.F.x = 0; nd.F.z = 0; if (nd.flags & 4) nd.F.y = -this.G1; else nd.F.y = -this.G; nd.F.add(this.mWForce); } this.mWForce.zero(); this.applyTension(); for(i = 0;i < nlen;i++) { nd = this.mNodes[i]; if ((nd.flags&1) != 0) { nd.F.sub(nd.F); } nd.velo.add(nd.F); } this.mLTNode.velo.copyFrom(this.mLTNodeV); this.mRTNode.velo.copyFrom(this.mRTNodeV); }, updatePosition: function() { var nlen = this.mNodes.length; var i, nd; for(i = 0;i < nlen;i++) { nd = this.mNodes[i]; if ((nd.flags&1) != 0) { nd.cv.x = 0; nd.cv.y = 0; nd.cv.z = 0; } nd.pos.add(nd.velo); nd.velo.sub(nd.cv); nd.cv.x = 0; nd.cv.y = 0; nd.cv.z = 0; nd.velo.smul(0.95); } }, draw: function() { P3D.clear("#000", this.mViewport.w, this.mViewport.h); this.transformPolygons(); this.mRenderTris.sort(ClothApp.zsortCmp); var len = this.mRenderTris.length; var t, sh; for (var i = 0;i < len;i++) { t = this.mRenderTris[i]; if (P3D.texture != t.texture) P3D.texture = t.texture; sh = undefined; if (t.lighting && t.shade > 0.01) sh = "rgba(0,0,0,"+t.shade+")"; P3D.drawTriangle(t.tposs, t.uvs, sh); } }, applyTension: function() { var i, k, nd; var v = new Vec3(); var nlen = this.mNodes.length; var naturalLen = this.mNLen; for (k = 0;k < nlen;k++) { nd = this.mNodes[k]; var F = nd.F; for (i = 0;i < 4;i++) { var nbr = nd.links[i]; if (!nbr) continue; var len = v.copyFrom(nbr.pos).sub(nd.pos).norm(); var dlen = len - naturalLen; if (dlen > 0) { v.smul(dlen * 0.5 / len); F.x += v.x; F.y += v.y; F.z += v.z; nd.cv.add(v.smul(0.8)); } } } }, setupTransforms: function() { this.mProjMat = new M44(); this.mProjMat.perspectiveLH(24, 15, 10, 9000); this.mViewMat = new M44(); this.updateViewTrans(0); }, updateViewTrans: function(ry) { this.mViewFromA.z = Math.cos(ry) * 380; this.mViewFromA.x = Math.sin(ry) * 380; this.mViewFrom.smul(0.7); this.mViewFrom.x += this.mViewFromA.x * 0.3; this.mViewFrom.y += this.mViewFromA.y * 0.3; this.mViewFrom.z += this.mViewFromA.z * 0.3; this.mViewMat.lookAtLH(this.vUP, this.mViewFrom, this.vAT); }, generateCloth: function(base_y) { var cols = 9; var rows = 8; var step = 22; this.mNLen = step*0.9; var w = (cols-1) * step; var i, k; for (k = 0;k < rows;k++) { for (i = 0;i < cols;i++) { var nd = new ClothNode(); nd.pos.x = -(w/2) + i*step; nd.pos.y = base_y -k*step/2; nd.pos.z = k*16; nd.uv.u = i / (cols-1); nd.uv.v = k / (rows-1); if (i > 0) { var prv_nd = this.mNodes[this.mNodes.length-1]; prv_nd.links[1] = nd; nd.links[0] = prv_nd; } if (k > 0) { var up_nd = this.mNodes[this.mNodes.length-cols]; up_nd.links[4] = nd; nd.links[3] = up_nd; } if (i != 0 && i != 4 && i != (cols-1)) nd.flags |= 4; this.mNodes.push(nd); } } // fix left-top and right-top this.mNodes[0 ].flags |= 1; this.mNodes[4 ].flags |= 1; this.mNodes[cols-1].flags |= 1; this.mLTNode = this.mNodes[0 ]; this.mRTNode = this.mNodes[cols-1]; }, generateRenderTriangles: function() { if (!this.mRenderTris) this.mRenderTris = []; var i; var nd; var nlen = this.mNodes.length; for(i = 0;i < nlen;i++) { nd = this.mNodes[i]; if (nd.links[1] && nd.links[1].links[4]) { var t = new RenderTriangle(); t.texture = this.texture1; t.poss[0] = nd.pos; t.poss[1] = nd.links[1].pos; t.poss[2] = nd.links[1].links[4].pos; t.uvs[0] = nd.uv; t.uvs[1] = nd.links[1].uv; t.uvs[2] = nd.links[1].links[4].uv; this.mRenderTris.push(t); t = new RenderTriangle(); t.texture = this.texture1; t.poss[0] = nd.pos; t.poss[1] = nd.links[1].links[4].pos; t.poss[2] = nd.links[4].pos; t.uvs[0] = nd.uv; t.uvs[1] = nd.links[1].links[4].uv; t.uvs[2] = nd.links[4].uv; this.mRenderTris.push(t); } } this.addBGTriangles(this.mNodes[0].pos.y); }, addBGTriangles: function(by) { var cols = 4; var t, x, y, sz = 110; var ox = -(cols*sz)/2; var oz = -(cols*sz)/2; for (y = 0;y < cols;y++) { for (x = 0;x < cols;x++) { var bv = ((x+y)&1) * 0.5; t = new RenderTriangle(); t.texture = this.texture2; t.poss[0] = new Vec3(ox + x*sz , by, oz + y*sz ); t.poss[1] = new Vec3(ox + x*sz + sz, by, oz + y*sz ); t.poss[2] = new Vec3(ox + x*sz , by, oz + y*sz + sz); t.uvs[0] = {u:0 , v:bv }; t.uvs[1] = {u:0.5, v:bv }; t.uvs[2] = {u:0 , v:bv+0.5}; if ((x==1 || x==2) && (y==1 || y==2)) this.modifyRoofUV(t, x == 2, bv); t.lighting = false; t.zBias = 0.5; this.mRenderTris.push(t); t = new RenderTriangle(); t.texture = this.texture2; t.poss[0] = new Vec3(ox + x*sz , by, oz + y*sz + sz); t.poss[1] = new Vec3(ox + x*sz + sz, by, oz + y*sz ); t.poss[2] = new Vec3(ox + x*sz + sz, by, oz + y*sz + sz); t.uvs[0] = {u:0 , v:bv+0.5}; t.uvs[1] = {u:0.5, v:bv }; t.uvs[2] = {u:0.5, v:bv+0.5}; if ((x==1 || x==2) && (y==1 || y==2)) this.modifyRoofUV(t, x == 2, bv); t.lighting = false; t.zBias = 0.5; this.mRenderTris.push(t); } } }, modifyRoofUV: function(t, rv, bv) { if (rv) { t.uvs[0].u = 0.5 - t.uvs[0].u; t.uvs[1].u = 0.5 - t.uvs[1].u; t.uvs[2].u = 0.5 - t.uvs[2].u; } t.uvs[0].u += 0.5; t.uvs[1].u += 0.5; t.uvs[2].u += 0.5; if (rv) { t.uvs[0].v = 0.5 - t.uvs[0].v + bv + bv; t.uvs[1].v = 0.5 - t.uvs[1].v + bv + bv; t.uvs[2].v = 0.5 - t.uvs[2].v + bv + bv; } }, transformPolygons: function() { var trans = new M44(); trans.mul(this.mViewMat, this.mProjMat); var hw = this.mViewport.ow; var hh = this.mViewport.oh; var len = this.mRenderTris.length; var t; var spos = [0, 0, 0, 0]; for (var i = 0;i < len;i++) { t = this.mRenderTris[i]; for (var k = 0;k < 3;k++) { trans.transVec3(spos, t.poss[k].x, t.poss[k].y, t.poss[k].z); var W = spos[3]; spos[0] /= W; spos[1] /= W; spos[2] /= W; spos[0] *= this.mViewport.w; spos[1] *= -this.mViewport.h; spos[0] += hw; spos[1] += hh; t.tposs[k].x = spos[0]; t.tposs[k].y = spos[1]; t.tposs[k].z = spos[2]; } var v1 = (new Vec3()).copyFrom(t.poss[1]).sub(t.poss[0]).normalize(); var v2 = (new Vec3()).copyFrom(t.poss[2]).sub(t.poss[1]).normalize(); var N = (new Vec3()).cp(v1, v2); trans.transVec3Rot(spos, N.x, N.y, N.z); if (t.lighting) { if (spos[2] > 0) t.shade = 0.8 else { t.shade = 0.1 - N.y * 0.6; if (t.shade < 0) t.shade = 0; } } t.sortKey = Math.floor( (t.tposs[0].z + t.tposs[1].z + t.tposs[2].z + t.zBias) *1000 ); } } } function ClothNode() { this.flags = 0; this.pos = new Vec3(); this.velo = new Vec3(); this.cv = new Vec3(); this.F = new Vec3(); this.links = [null, null, null, null]; this.uv = {u:0, v:0}; } function RenderTriangle() { this.texture = null; this.poss = new Array(3); this.tposs = [new Vec3(), new Vec3(), new Vec3()]; this.uvs = [{u:0, v:0}, {u:0, v:0}, {u:0, v:0}]; this.shade = 0; this.lighting = true; this.zBias = 0; this.sortKey = 0; }
看完上述内容,你们对如何使用HTML5实现3D衣服摇摆动画特效有进一步的了解吗?如果还想了解更多知识或者相关内容,请关注行业资讯频道,感谢大家的支持。
衣服
动画
内容
特效
代码
剪贴板
剪贴
鼠标
v.x
v.y
v.z
w.x
w.y
w.z
逼真
剧烈
又是
效果
更多
杰作
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
p6连接不上数据库
澳洲大学计算机软件开发
hnmr数据库查询免费
七台河网络安全宣传周活动
服务器安装redhat
苏州李晶任网络安全保卫支队政委
山西ios软件开发给您好的建议
求生之路搭服务器
双色球数据库分析
软件开发合同逾期违约赔偿标准
数据库 ppt 信息技术
网络安全技术 有前景吗
mes服务器上门维修
服务器的显示器接口长什么样
哪里可以看qq服务器
我的世界虚拟人生服务器
棋牌软件开发源码
网络技术以后好就业吗
超新星计算机网络技术考试答案
阿里云服务器部署网站
建立关系数据库模型的e-r图
电脑服务器由什么配件组成
java项目数据库的设计
我的世界如何做服务器
ei数据库是全文数据库
哈利波特服务器可以改吗
电路板的软件开发
中行软件开发中心合肥社招
盐池工业品网站服务器
广州诺特软件开发有限公司招聘