如何使用HTML5实现3D衣服摇摆动画特效
发表于:2025-01-16 作者:千家信息网编辑
千家信息网最后更新 2025年01月16日,今天就跟大家聊聊有关如何使用HTML5实现3D衣服摇摆动画特效,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。这又是一款基于HTML5 Canv
千家信息网最后更新 2025年01月16日如何使用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安全错误
数据库的锁怎样保障安全
陕西酷轻网络技术有限公司
网络安全法知情同意原则是什么
河北什么是网络技术经验丰富
校园网络安全性
如何看待和应对网络安全问题
河北省首届企事业网络安全
数据库中如何查询日志记录
正当防卫4显示服务器当前不可用
游戏软件开发培训机构排名
奇异果互联网科技
首次网络安全大赛
干软件开发需要考证书吗
web端访问小程序数据库
网络安全工作的意义
无线网络安全与防护论文
泰山服务器鲲鹏9203d
如何提高学生网络安全
tdsql修改数据库表结构
软件开发科学与技术
《网络安全法》自 实施
学网络技术说是后期要学费
数据库中如何查询日志记录
这种数据库
数据库新用户可访问表
网络安全的儿童图片
供电公司网络安全保障
网络安全系统都有什么
三大数据库文献
网络安全建设进行时
神武4服务器等级开放120