canvas教程

Having fun with Html5 Canvas(2)

字号+ 作者:H5之家 来源:H5之家 2017-04-13 14:05 我要评论( )

this.phi0 = alpha; // 在时间t=0,将此齿轮旋转角度newGear.phi0 = alpha + Math.PI + (Math.PI / newTeeth);// 同时(t=0),旋转新齿轮角度(180-),对着第一个齿轮// 并且加上一半的齿轮旋转使它们的轮齿能够啮

this.phi0 = alpha; // 在时间t=0,将此齿轮旋转角度α newGear.phi0 = alpha + Math.PI + (Math.PI / newTeeth); // 同时(t=0),旋转新齿轮角度(180-α),对着第一个齿轮 // 并且加上一半的齿轮旋转使它们的轮齿能够啮合 newGear.createdAt = this.createdAt; // 当然,还得同步它们的时钟

上面的做法是有效的。然而,这种方法的缺点是我们在一直改变 this.phi ,这意味着以前与之同步的任何其他齿轮将不再同步。

每次 this.phi 都被一些 delta 更新,那么 newGear.phi 应该被更新多少?答案是 delta * (newGear.angularSpeed / this.angularSpeed) ,因为要考虑齿轮转速之比。了解到这个之后,我们可以把两个齿轮都更新一下: delta = (this.phi0 - alpha) ,以消除这种影响:

// 在时间t=0,将此齿轮旋转角度α this.phi0 = alpha + (this.phi0 - alpha); // this.phi0,没啥用,仅供展示。 newGear.phi0 = alpha + Math.PI + (Math.PI / newTeeth) + (this.phi0 - alpha) * (newGear.angularSpeed / this.angularSpeed); // 同时(t=0),旋转新齿轮角度(180-α),对着第一个齿轮 // 并且加上一半的齿轮旋转使它们的轮齿能够啮合 newGear.createdAt = this.createdAt; // 当然,还得同步它们的时钟

通过这样的处理, this.phi0 保持不变,不过另一个齿轮却得以同步:

See the Pen Gear-2-3 by molunerfinn ( @molunerfinn ) on CodePen .

第三部分 3D齿轮

在上一个部分,我们已经展示了如何通过HTML5 Canvas渲染出啮合的齿轮对。本部分,我们将会探索通过使用Three.js这个库,渲染出完全3D的JavaScript齿轮,同时也会进一步扩大视图的复杂性。

3D渲染

Three.js是一个用于3D图形渲染的JavaScript库,是基于WebGL的。它是免费,开放,并且不断更新的。我们将从移植我们的渲染代码开始,首先试着描绘出2D平面里的齿轮轮廓。

var shape = new THREE.Shape(); // 跳转到齿轮顶部的起始位置 var x0 = this.radius; var y0 = 0; shape.moveTo(x0, y0); for (var i = 0; i < this.legs * 2; i++) { var alpha = 2 * Math.PI * (i / (this.legs * 2)) + this.phi; var x = Math.cos(alpha) * this.radius; var y = Math.sin(alpha) * this.radius; createArc(shape, x, y, this.connectionRadius, -Math.PI / 2 + alpha, // 起始角度 Math.PI / 2 + alpha, // 结束角度 i % 2 == 0, // 顺时针还是逆时针 3 // 每段弧的离散段数 ); } return shape;

我用了一个辅助函数把弧形段分割成离散的段:

function createArc(shape, x, y, radius, from, to, sign, parts) { var src = sign ? from : to; // 确保我们总是沿着一个方向移动 var trg = sign ? to : from; var delta = sign ? 0 : Math.PI; // 但在需要的时候可以反转角度 for (var i = 1; i < parts; i++) { var t = i / parts; var cx = x + radius * Math.cos(delta + (src * (1 - t) + trg * t)); var cy = y + radius * Math.sin(delta + (src * (1 - t) + trg * t)); shape.lineTo(cx, cy); } }

当前的代码里有一个问题——啮合的齿轮会从一个小角度phi开始旋转,而不是恰好在 (r,0) 。要正确地获取 (x0,y0) 需要进行以下调整:

var sign = this.legs % 2; var from = -Math.PI / 2 + this.phi; var to = Math.PI / 2 + this.phi; var src = sign ? from : to; var trg = sign ? to : from; var delta = sign ? 0 : Math.PI; var x0 = Math.cos(this.phi)*this.radius + this.connectionRadius*Math.cos(delta + src); var y0 = Math.sin(this.phi)*this.radius + this.connectionRadius*Math.sin(delta + src);

现在,让我们增加一些代码来渲染齿轮中心的孔:

var holePath = new THREE.Path(); holePath.moveTo(this.connectionRadius, 0); createArc(holePath, 0, 0, this.connectionRadius, 0, 2 * Math.PI, true, 10); this.shape.holes.push(holePath);

一旦我们齿轮的轮廓被描绘,我们可以使用Three.js的拉伸功能使其变得更加真实起来:

var extrudeSettings = { steps: 1, amount: gearDepth, bevelEnabled: false, }; var geometry = new THREE.ExtrudeGeometry(shape, extrudeSettings); var material = new THREE.MeshPhongMaterial({ color: color, polygonOffset: true, polygonOffsetFactor: 1.0, polygonOffsetUnits: 4.0 }); var mesh = new THREE.Mesh(geometry, material); scene.add(mesh);

这里是结果:

See the Pen Gear-3-1 by molunerfinn ( @molunerfinn ) on CodePen .

生成更复杂的场景

使用第二部分的代码我们可以生成一对互相啮合的齿轮,为了生成更复杂的场景,只要我们避免碰撞,可以一次添加一个齿轮。

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • HTML5画布中的变换

    HTML5画布中的变换

    2017-04-13 14:03

  • Canvas实现放射线动画效果

    Canvas实现放射线动画效果

    2017-04-13 10:01

  • HTML5 Canvas绘制圆点虚线实例_html5教程技巧

    HTML5 Canvas绘制圆点虚线实例_html5教程技巧

    2017-04-13 10:01

  • canvas实现简易的圆环进度条效果

    canvas实现简易的圆环进度条效果

    2017-04-13 10:00

网友点评
-