在画布上为草制作动画的有效方法
Efficient way to animate grass in canvas
我一直在尝试画布元素的 2d 上下文的功能来尝试创建相对逼真的 3d 场景,并且目前正在尝试按照小提琴创建 3d 'ish' 草的平原:
http://jsfiddle.net/PlacidCow/j6h7sajz/
我的问题是,让草动画化以吸收风/物理等效果的最有效方法是什么?
目前我刚刚绘制到屏幕上 - 我尝试将每个刀片的尺寸存储在一个大数组中,然后 ofc 需要很长时间才能循环播放动画(因此滞后且毫无意义)。有没有一种有效的方法来绘制每个刀片?或者人们会建议按块制作动画(但是如何修复,因为清除补丁会弄乱前面的刀片)?重复刀片以便它们批量制作动画?
在网上看过(也许我缺乏谷歌搜索技能......),但我要么什么也没找到,狡猾的 webgl 演示或 C 等示例,但这使用了不适用于 2d 画布的着色器。
c = document.getElementsByTagName('canvas')[0];
ctx = c.getContext('2d');
var v = {
w: c.clientWidth,
h: c.clientHeight
};
c.width = v.w;
c.height = v.h;
var base = {
c: [
[-1, -1, 0],
[-1, -1, -1],
[1, -1, -1],
[1, -1, 0]
],
f: 'brown',
d: -3
};
draw(base.c, base.f, base.d);
for (var j=1; j<120; j++) {
for (var k=1; k<200; k++) {
var z = -1 + 2*j/199;
var x = -1 + (2*Math.random())/1.01;
var y = 0.06+Math.random()*0.04;
var fl = Math.pow(-1, (Math.random()*1000)|0) * Math.random()/20;
var blade = {
c: [
[x, -1, z-Math.random()/1000],
[x+0.002+fl, -1+y, z-Math.random()/1000],
[x+0.007+fl, -1+y, z-Math.random()/1000],
[x+0.02, -1, z-Math.random()/1000]
],
f: 'green',
d: 2
};
draw(blade.c, blade.f, blade.d);
}
}
function draw(cds, fill, d) {
var v = {
w: c.clientWidth,
h: c.clientHeight
};
ctx.beginPath();
ctx.moveTo(((cds[0][0] * (1 / (1 - cds[0][2])) + 1) * v.w / 2)|0, ((v.h - (cds[0][1] + 1) * v.h / 2) * (1 / (1 - cds[0][2])))|0);
for (var i = 1; i < cds.length; i++) {
ctx.lineTo(((cds[i][0] * (1 / (1 - cds[i][2])) + 1) * v.w / 2)|0, ((v.h - (cds[i][1] + 1) * v.h / 2) * (1 / (1 - cds[i][2])))|0);
}
ctx.lineTo(((cds[0][0] * (1 / (1 - cds[0][2])) + 1) * v.w / 2)|0, ((v.h - (cds[0][1]+1) * v.h / 2) * (1 / (1 - cds[0][2])))|0);
if (Math.abs(d) == 1) {
grd = ctx.createLinearGradient((200-200*d/Math.abs(d))/2, 0, (200+200*d/Math.abs(d))/2,0);
} else if (Math.abs(d) == 2) {
grd = ctx.createLinearGradient(0,((v.h - (cds[1][1] + 1) * v.h / 2) * (1 / (1 - cds[1][2])))|0,0,((v.h - (cds[0][1] + 1) * v.h / 2) * (1 / (1 - cds[0][2])))|0+v.h/100);
} else if (Math.abs(d) == 3) {
grd = ctx.createLinearGradient(0,(200-200*d/Math.abs(d))/2, 0, (200+200*d/Math.abs(d))/2);
}
grd.addColorStop(0, fill);
grd.addColorStop(1, '#000');
ctx.fillStyle = grd;
ctx.fill();
}
我要做的是预先生成每个草叶可能的所有形状。我不熟悉弯曲草背后的数学原理,但让我们假设每种形状的草都可以用 2 个变量来描述:bentX 和 bentZ。因此,我将绘图过程分解为2个:为草地生成图像帧并进行渲染。
用于生成帧的伪代码:
var frames = [];
for (var i = min possible of bentX, l = max possible of bentX; i<=l; i += precision for bentX)
for (var j = ... bentZ .... )
frames[i][j] = image of grass at (i,j);
然后对于渲染:
for each grassObj:
bentX, bentZ = mathCalcs(grassObj);
bentX, bentZ = clampToValidValue(bendX, bentZ);
frames[bendX][bentZ].draw();
相关文章:
- 如何设置html元素填充的动画
- 如何使用动画实现纸张推车
- 如何在生成下载文件时显示加载动画
- 剑道网格jQuery动画()问题
- EaseJS拖放;放下(动画CC)电影剪辑的鼠标坐标
- jQuery Lazy加载动画滚动
- jquery动画可以通过编程链接吗
- Javascript将数学动画化
- 动画.CSS重播
- 制作一个不带HTML a标记但在动画播放完毕后指向其他页面的超链接
- 如何使用jQuery在动画中期加速动画
- 使用数据上的角度更改设置集合的第一个元素的动画
- 如何有效地将游戏数据存储在URL查询字符串中
- 什么's是为网页编写动画标题的最有效方法
- 如何在运动路径上有效地反转 SVG (SMIL) 动画
- SVG 动画在以编程方式设置样式时有效,但在仅使用样式表时无效
- 在画布上为草制作动画的有效方法
- 为什么许多Jquery动画或效果在Internet Explorer的较低版本中有效
- 动画永远循环在Chrome中有效,但在IE中无效
- 我的jQuery动画很有效,但我想进一步改进它