html流体效果网页,HTML5实验:JavaScript模拟流体效果

【IT168 技术】把现实世界当中的物体模拟到计算机当中,一些简单的物理实验、碰撞旋转等等难度还是不算很大,难度较大的应当算流体模拟。

本文将在Canvas当中模拟出一个2D平面内的水珠,涉及的知识点和技巧包括:Jscex基础知识,贝塞尔曲线的绘制,合理利用CanvasRenderingContext2D的translate和rotate等API。

绘制椭圆

在模拟水滴之前,我们先思考一下怎么在canvas当中绘制一个椭圆。

大家可以很容易想到 下面几种方案:

1.根据椭圆笛卡尔坐标系方程绘制

2.根据椭圆极坐标方程绘制

3.根据椭圆曲率变化绘制

4.利用四条贝塞尔曲线绘制

第四中,也是性能最好的一种,这样可以避免复杂的计算,充分利用CanvasRenderingContext2D的API(API的性能是通过严格测试,一般情况下比较靠谱).

所以我们采用第四种方式来绘制椭圆。

var canvas;

var ctx;

canvas=document.getElementById("myCanvas1");

ctx=canvas.getContext("2d");

ctx.strokeStyle="#fff";functiondrawEllipse(x, y, w, h) {

var k=0.5522848;

var ox=(w/2)*k;

var oy=(h/2)*k;

var xe=x+w;

var ye=y+h;

var xm=x+w/2;

var ym=y+h/2;

ctx.beginPath();

ctx.moveTo(x, ym);

ctx.bezierCurveTo(x, ym-oy, xm-ox, y, xm, y);

ctx.bezierCurveTo(xm+ox, y, xe, ym-oy, xe, ym);

ctx.bezierCurveTo(xe, ym+oy, xm+ox, ye, xm, ye);

ctx.bezierCurveTo(xm-ox, ye, x, ym+oy, x, ym);

ctx.stroke();

}

ctx.clearRect(0,0,canvas.width,canvas.height);

drawEllipse(10,10,40,82);

(改变drawEllipse的四个参数试试)

旋转椭圆

这里的旋转不是绕上面的drawEllipse的前两个参数x,y旋转,二是绕椭圆的中心旋转。所以仅仅CanvasRenderingContext2D.rotate是不够的,因为CanvasRenderingContext2D.rotate是绕画布的左上角(0,0)旋转。所以我们先要把(0,0)通过CanvasRenderingContext2D.translate到椭圆的中心,然后再drawEllipse(-a/2, –b/2, a, b).

上面这句话,就是绕中心旋转的核心。这里还可以推广到任意图形或者图片(假设有约定的中心)。如图:

f706166b5dfae1e04d63b36bb1c80770.png

然后我们就可以先绘制一个鸟巢出来:

Your browser doesnotsupport the canvas element.

ee7aacd2d41049d7e54312775218645f.png

绘制水滴

旋转的椭圆和鸟巢神马的和水滴有什么关系呢?

我们通过改变椭圆的长轴和短轴,令其非常接近圆形(只能接近,不能等于圆形),然后每次旋转擦除画布,就可以达你预想不到的效果!

这里需要注意的是,擦除画布不再是一句CanvasRenderingContext2D.clearRect(0,0,canvas.width,canvas.height)就可以,因为画布已经旋转和画布原点已经translate,所以我们使用 ctx.clearRect(-canvas.width, -canvas.height, 2 * canvas.width, 2 * canvas.height)来擦除画布。

我们画一个长轴42,短轴40的椭圆,旋转并擦除画布:

functiondrawEllipse(x, y, w, h) {

ctx.clearRect(-canvas.width,-canvas.height,2*canvas.width,2*canvas.height);

var k=0.5522848;

var ox=(w/2)*k;

var oy=(h/2)*k;

var xe=x+w;

var ye=y+h;

var xm=x+w/2;

var ym=y+h/2;

ctx.beginPath();

ctx.moveTo(x, ym);

ctx.bezierCurveTo(x, ym-oy, xm-ox, y, xm, y);

ctx.bezierCurveTo(xm+ox, y, xe, ym-oy, xe, ym);

ctx.bezierCurveTo(xe, ym+oy, xm+ox, ye, xm, ye);

ctx.bezierCurveTo(xm-ox, ye, x, ym+oy, x, ym);

ctx.stroke();

ctx.translate(x+20, y+21);

px=-20;

py=-21;

ctx.rotate(10*Math.PI*2/360);

}

var ct;

var drawAsync=eval(Jscex.compile("async",function(ct) {while(true) {

drawEllipse(px, py,40,42)

$await(Jscex.Async.sleep(10, ct));

}

}))

会是什么效果呢?

现在大家可以看到一个晃动的水珠了,流体实验刚刚开始,这篇只是一个起点····

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值