建站学习网,专业提供各类建站教程,网页素材,SEO资讯等建站资源!

网站模板_网站源码_网站素材_建站教程_建站学习网

当前位置:建站学习网 > 网页设计 > HTML5教程 >

HTML5实验:JavaScript模拟流体效果

更新时间:2017-04-11整理编辑:建站学习网阅读:0

第1页绘制椭圆

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

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

绘制椭圆

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

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

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

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

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

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

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

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

var canvas;

var ctx;

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

ctx.strokeStyle = “#fff“;

function drawEllipse(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.border=“1″ 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).

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

第2页旋转椭圆

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

html>

head>

script src=“http://files.cnblogs.com/iamzhanglei/jscex.jscexRequire.min.js“ type=“text/javascript“>script>

head>

body>

style type=“text/css“>

input.css3btn

background: -moz-linear-gradient(270deg, #d2ebf8, #0c8ab5);

background: -webkit-linear-gradient(top, #d2ebf8, #0c8ab5);

background: -o-linear-gradient(top, #d2ebf8, #0c8ab5);

filter: progid:DXImageTransform.Microsoft.Gradient(GradientType=0, StartColorStr=“#000099CC“, EndColorStr=“#FF0087B4″);

border-top: 1px solid #38538c;

border-right: 1px solid #1f2d4d;

border-bottom: 1px solid #151e33;

border-left: 1px solid #1f2d4d;

border-radius: 4px;

box-shadow: inset 0 1px 10px 1px #5c8bee, 0px 1px 0 #1d2c4d, 0 2px 0px #1f3053, 0 4px 4px 1px #111111;

color: #f0f0f0;

font: bold 20px “helvetica neue“ , helvetica, arial, sans-serif;

padding: 10px 0 10px 0;

text-align: center;

text-shadow: 0px -1px 1px #1e2d4d;

width: 150px;

background-clip: padding-box;

input.css3btn:hover

box-shadow: inset 0 0px 20px 1px #87adff, 0px 1px 0 #1d2c4d, 0 3px 0px #1f3053, 0 4px 4px 1px #111111;

cursor: pointer;

input.css3btn:active

box-shadow: inset 0 1px 10px 1px #5c8bee, 0 1px 0 #1d2c4d, 0 2px 0 #1f3053, 0 4px 3px 0 #111111;

style>

canvas width=“350″ border=“1″ height=“350″ style=“border: solid 15px #222; background-color: #111;

color: #CCC;“>

Your browser does not support the canvas element.

canvas>

script>

var canvas;

var ctx;

var px = 0;

var py = 0;

function init() {

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

ctx.strokeStyle = “#fff“;

ctx.translate(70, 70);

init();

var i = 0;

function drawEllipse(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.translate(x + 70, y + 100);

px = -70;

py = -100;

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

var ct;

var drawAsync = eval(Jscex.compile(“async“, function (ct) {

while (true) {

drawEllipse(px, py, 140, 200)

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

}))

function Button1_onclick() {

ct.cancel();

function Button2_onclick() {

ct = new Jscex.Async.CancellationToken();

drawAsync(ct).start();

script>

br />

input type=“button“ value=“run“ onclick=“return Button2_onclick()“ />

input type=“button“ value=“stop“ onclick=“return Button1_onclick()“ />

body>

html>

第3页绘制水滴

 

绘制水滴

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

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

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

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

function drawEllipse(x, y, w, h) {

ctx.clearRect(-canvas.width, -canvas.border=“1″ Height, 2 * canvas.width, 2 * canvas.border=“1″ 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));

}))

会是什么效果呢?

在线演示效果查看

http://www.cnblogs.com/iamzhanglei/archive/2011/12/12/2284188.html

现在大家可以看到一个晃动的水珠了

本文网址:https://www.dedexuexi.com/wysj/html5/2677.html

本站部分文章搜集与网络,如有侵权请联系本站,转载请说明出处。

标签:前端
收藏此文 赞一下!() 打赏本站

如本文对您有帮助,就请建站学习网抽根烟吧!

支付宝打赏
微信打赏
HTML5 Web开发:防止浏览器假死的方法
« 上一篇2017年04月11日
Html5新标签的使用
2017年04月11日下一篇 »
  • CSS代码鼠标经过图片变换图片的几种方法
    0阅读
    CSS代码鼠标经过图片变换图片方法如下:方法一:在css中,可以利用“:hover”选择器和“background-image”属性实现鼠标滑过改变图片效果,只需要给图片元素添加“图片元素:hover{background-image:url(新的图片路径);”样式即可。
  • 如何利用html+css设置菜单栏缓慢下拉效果?
    0阅读
    如何利用html+css设置菜单栏缓慢下拉效果?解决方法和相关代码分享如下:方法一:过渡(transition)对forum_box开启绝对定位(absolute),让里面的li从其父元素中脱离出去,不然会把之后的内容往右挤,并且设置overflow:hidden,设置高度为0,鼠标移入后再设置相应...
  • 纯css3实现下拉箭头、关闭按钮旋转效果
    0阅读
    说起css3的旋转效果,那就要说为什么不用js去实现,CSS3的动画效果,能够减少对JavaScript和Flash文件的HTTP请求这是原因之一。但是css3可能要求浏览器执行很多的工作来完成这个动画效果的渲染,这有可能导致浏览器响应缓慢,因此,在使用一些复杂的特效时,大家需要考虑清楚。不过这样的...
  • 使用HTML5的Canvas绘制曲线的简单方法
    0阅读
    Canvas2D自带的曲线方法 最近在研究3D柔体的计算,所以在狂补一些知识。经常会涉及到一些数值分析方面的东西,主要是曲线的各种插值算法。突然想起了Canvas2D本身也是可以绘制曲线的,使用
  • html两个文字之间有一个空格的解决办法
    0阅读
    碰到过这样一位朋友,在编写的html代码里面出现两个文字间有空格的情况,两个文字之间他没有加空格符,也没有代码。 这个情况在html编码使用不太多或不太熟练的情况下,很难找出问题。
 
QQ在线咨询