- 浏览: 337300 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
327764984:
CommonSql里不知道把PreparedStatment和 ...
Connection.setAutoCommit使用的注意事项 -
netwelfare:
文章讲解的不详细啊,很多东西没有讲解出来。看到这篇文章讲解的挺 ...
java字符串的拆分 lang.String.split -
iceage1980:
博主你好 我用了你这个代码 为什么总是在 if (this. ...
MD5 码 校 验 -
wisdomtl:
最后一段代码有写小的错误最后一个具体工厂的实现应该返回Cowb ...
JAVA设计模式之工厂模式 -
jateide:
网上随便转载的东西,自己都没有经过使用,好意思发出来,而且还不 ...
正则表达式中后向引用、零宽断言、负向零宽断言的解释用法
把现实世界当中的物体模拟到计算机当中,一些简单的物理实验、碰撞旋转等等难度还是不算很大,难度较大的应当算流体模拟。
本文将在Canvas当中模拟出一个2D平面内的水珠,涉及的知识点和技巧包括:Jscex基础知识,贝塞尔曲线的绘制,合理利用CanvasRenderingContext2D的translate和rotate等API。
绘制椭圆
在模拟水滴之前,我们先思考一下怎么在canvas当中绘制一个椭圆。
大家可以很容易想到 下面几种方案:
1.根据椭圆笛卡尔坐标系方程绘制
2.根据椭圆极坐标方程绘制
3.根据椭圆曲率变化绘制
4.利用四条贝塞尔曲线绘制
第四中,也是性能最好的一种,这样可以避免复杂的计算,充分利用CanvasRenderingContext2D的API(API的性能是通过严格测试,一般情况下比较靠谱).
所以我们采用第四种方式来绘制椭圆。
var ctx;
canvas = document.getElementById("myCanvas1");
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.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).
上面这句话,就是绕中心旋转的核心。这里还可以推广到任意图形或者图片(假设有约定的中心)。如图:
然后我们就可以先绘制一个鸟巢出来:
<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;
margin-top: 1px;
}
</style>
<canvas id="myCanvas2" width="350" 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() {
canvas = document.getElementById("myCanvas2");
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 id="Button2" class="css3btn" type="button" value="run" onclick="return Button2_onclick()" />
<input id="Button1" class="css3btn" type="button" value="stop" onclick="return Button1_onclick()" />
</body>
</html>
绘制水滴
旋转的椭圆和鸟巢神马的和水滴有什么关系呢?
我们通过改变椭圆的长轴和短轴,令其非常接近圆形(只能接近,不能等于圆形),然后每次旋转擦除画布,就可以达你预想不到的效果!
这里需要注意的是,擦除画布不再是一句CanvasRenderingContext2D.clearRect(0,0,canvas.width,canvas.height)就可以,因为画布已经旋转和画布原点已经translate,所以我们使用 ctx.clearRect(-canvas.width, -canvas.height, 2 * canvas.width, 2 * canvas.height)来擦除画布。
我们画一个长轴42,短轴40的椭圆,旋转并擦除画布:
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));
}
}))
会是什么效果呢?
在线演示效果查看http://www.cnblogs.com/iamzhanglei/archive/2011/12/12/2284188.html
发表评论
-
js match 的简单用法 [转]
2014-06-05 14:41 1299/* js match 的用法 */var href,rs, ... -
JavaScript的replace方法与正则表达式结合应用讲解(转)
2013-09-27 17:02 905replace方法的语法是:stringObj.replac ... -
jquery内容过滤选择器、属性过滤选择器和jquery可见度过滤选择器(转)
2012-07-12 10:56 3439一、 jquery内容过滤选择器 根据内容进行选择 ... -
Jquery获取select,dropdownlist,checkbox 下拉列表框的值(转)
2012-07-11 16:18 1457jQuery获取Select选择的 ... -
Jquerr 中ajax和eche遍历等问题
2012-07-08 14:25 1479众所周知,jquery作为轻量级的js框架,已经应用到了很多方 ... -
利用jquery操作select下拉列表框(转)
2012-07-07 20:33 1106例: <select id=" ... -
HTML锚点(转)
2012-07-02 16:06 1400以前只是知道有锚点这么个东西,一直没有用到,昨天做毕设 ... -
jQuery.extend 函数详解(转)
2012-06-20 09:49 1049JQuery的extend扩展方法: ... -
jQuery Datepicker 选择指定日期【转】
2012-05-21 14:17 3956要求是日期只能选择每个月的1号,其它都不能选择。 ... -
DatePicker基本使用方法 【转】
2012-05-08 11:01 4269一个不错的地址,用来DIY jQuery UI界面效果的 ... -
使用 JSONP 实现跨域通信,第 2 部分: 使用 JSONP、jQuery 和 Yahoo! 查询语言构建 mashup(转)
2012-03-27 16:58 1583简介 在本系列的第 1 ... -
使用 JSONP 实现跨域通信,第 1 部分: 结合 JSONP 和 jQuery 快速构建强大的 mashup(转)
2012-03-27 16:57 962简介 Asynchronous JavaScript ... -
keyCode charCode 详解
2012-03-27 11:33 1561键盘事件拥有两个属性, keyCode 和 CharCo ... -
JavaScript 键盘键值大集合
2012-03-27 10:01 4218JavaScript【keyCode】 JavaSc ... -
document.createElement()的用法 (转)
2012-03-16 11:09 1231分析代码时,发现自己的盲点——document.createE ... -
红薯 50+ 个 JavaScript & HTML5 框架以及相关工具(转)
2012-03-16 09:58 2382全堆栈框架和工具包 jQuery License: ... -
正则表达式中后向引用、零宽断言、负向零宽断言的解释用法
2012-03-08 15:02 2286正则表达式中后向引用 ... -
JavaScript正则表达式基础
2012-03-08 13:40 1035创建一个正则表达式 第一种方法: var reg = /pat ... -
javascript 正则表达式(转)
2012-03-08 13:28 979一 javascript正则表达式的基本知识 1 ... -
弹出层页面
2011-12-20 11:11 1270弹出层的一个小例子 <head> ...
相关推荐
交互式微流体设计编辑器是一种先进的工具,它允许用户通过直观的图形用户界面来创建、模拟和设计微流体系统。在这个特定的压缩包"交互式微流体设计编辑器_JavaScript_HTML_下载.zip"中,我们可以推测其内容是基于...
1. **WaterSim2D**:这是一个二维水体模拟的示例程序,可能用于演示如何在2D环境中模拟流体动力学。学习者可以通过分析代码了解如何处理粒子系统、流体动态和碰撞检测,理解流体模拟的基本原理。 2. **CarSim**:...
在“流体力学智慧平台”中,网页设计的目标可能是为了提供一个交互式的平台,展示流体力学的相关知识,包括理论、实验数据以及模拟结果。这样的平台通常需要有良好的用户界面和用户体验设计,以确保信息的清晰传递和...
【标题】中的“纯CSS3实现网球比赛动画模拟效果源码”表明这是一个使用CSS3技术来创建网球比赛动画效果的项目。CSS3是层叠样式表的第三版,它引入了许多新的特性和功能,使得前端开发者能够创建更复杂、动态且交互性...
粒子系统易于实现,能模拟流体、烟雾等连续介质的行为。 2. **网格**:MPM利用四边形或三角形网格来存储物体的初始形状和结构。网格提供了一种方法来定义物体的表面和边界条件,同时也可以方便地应用各种物理定律。...
在这个项目中,用户可以练习和测试他们的HTML、JavaScript和CSS技能,而Maqueteo独奏可能提供了一种结构化的框架,让用户单独处理这三个技术,同时也能看到它们的交互效果。 【标签】:“HTML”标签表明这个项目...
在 ToxiTest 中,Toxiclibs 可能被用来实现高级的图形特效,如粒子碰撞、流体动力学模拟或者物理交互。 项目ToxiTest-master中的文件很可能是该项目的源代码和资源,包括HTML、CSS、JavaScript文件以及可能的图像或...
开发者可能利用JavaScript库,如Three.js或Pixi.js,结合HTML5 Canvas来创建实时的流体流动和加热效果的3D模型。用户可能能够通过交互控制加热参数,观察流体行为的变化。 3. **网格计算**: 网格计算是指将多个计算...
5. **可视化**:将模拟结果实时渲染出来,JavaScript提供了各种图形库,如Three.js或Pixi.js,可以将粒子位置转换为像素,创建出视觉上的液体流动效果。 6. **并行计算**:为了加速复杂的液体模拟,可能需要利用Web...
WebGL是一种在网页上实现3D图形渲染的技术,它基于OpenGL标准,并且完全融入到HTML5的Canvas元素中。WebGL使得开发人员可以利用JavaScript语言编写代码,无需插件即可在浏览器中展示复杂的三维场景和模型。这个...
前端源代码通常涉及用户交互的部分,如HTML、CSS和JavaScript,用于创建用户界面和控制数据流。而后端源代码则涉及服务器逻辑、数据库操作、业务规则以及与前端通信的接口,通常由编程语言如Python、Java或Node.js...
5. **结果可视化**:使用HTML和其他Web技术将模拟结果展示出来,便于分析和解释。 6. **验证与优化**:通过多次迭代,不断验证模型的准确性,并优化模型以提高预测能力。 在"krill-tank-code-master"目录下,我们...
为了实现这个模拟,开发者可能使用了JavaScript库,如D3.js或Chart.js,来绘制动态图表和图形,实时展示模拟的结果。JavaScript还负责处理用户输入、计算模拟结果以及更新页面显示。此外,如果涉及到复杂的计算,...
利用HTML,可以构建交互式网页,展示实验数据、模拟结果,甚至创建动态模型,帮助学生和研究人员更好地理解和探索热科学的原理。 在"ApplThermSci-master"这个压缩包中,可能包含了《应用热科学》的课程材料、代码...
着色器通常用于控制3D物体表面的颜色、光照、纹理等视觉效果,以及实现复杂的特效,如粒子系统、流体模拟和光追等。 描述中提到的“现场预览可以在这里找到:://www.shadertoy.com/user/LucaHofmann”,说明这些...
- **技术实现**:此类平台通常采用Web开发技术进行构建,如HTML、CSS和JavaScript等前端技术,以及Python、Java或.NET等后端开发语言。此外,还需要数据库管理系统来存储大量的会议数据。 ### 2. 自然科学研究领域 ...