Javascript 在画布中设置草动画的有效方法

Javascript 在画布中设置草动画的有效方法,javascript,html,animation,canvas,Javascript,Html,Animation,Canvas,我一直在玩弄canvas元素的2d上下文功能,试图创建相对真实的3d场景,目前正在尝试根据fiddle创建一个3d“ish”草地平面: 我的问题是,什么是最有效的方式,以动画的草采取的影响,风/物理等 目前,我刚刚绘制到屏幕上——我尝试将每个刀片的尺寸存储在一个大数组中,然后ofc需要花费很长时间来循环制作动画(因此是滞后和无意义的)。是否有一种有效的方法来绘制每个刀片?或者,人们会建议为每个块设置动画(但如果清除一个补丁会弄乱前面的刀片,该如何修复)?重复刀片以便批量制作动画 我在网上看过(

我一直在玩弄canvas元素的2d上下文功能,试图创建相对真实的3d场景,目前正在尝试根据fiddle创建一个3d“ish”草地平面:

我的问题是,什么是最有效的方式,以动画的草采取的影响,风/物理等

目前,我刚刚绘制到屏幕上——我尝试将每个刀片的尺寸存储在一个大数组中,然后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();
}
c=document.getElementsByTagName('canvas')[0];
ctx=c.getContext('2d');
变量v={
w:c.clientWidth,
h:c.clientHeight
};
c、 宽度=v.w;
c、 高度=v.h;
var基={
c:[
[-1, -1, 0],
[-1, -1, -1],
[1, -1, -1],
[1, -1, 0]
],
f:‘棕色’,
d:-3
};
图纸(底图c、底图f、底图d);

对于(var j=1;j我要做的是预生成每片草可能的所有形状。我不熟悉弯曲草背后的数学,但让我们假设每片草的形状都可以用两个变量来描述: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);

我已经读过这篇文章,有一些简单的方法可以改变刀片(如果我没有回答,我会再看一遍)-我现在想知道的是一种有效的方法可以潜在地影响所有人(在小提琴上200x200=40000)由于风的原因,比如说,或者至少给人一种愚弄的印象。在2d画布上最有效的方法可能是为每片草生成图像帧并播放它们。你可以生成多组图像,并使用不同的起点来创建它们都是唯一的错觉。实际上,因为你需要40000个叶片每个刀片的图像绘制速度不够快(画布可以以30FPS的速度绘制10-15k的图像),因此您需要创建表示多个刀片的图像。为了提高效率,如果草的宽度为200px,则创建第二个300x5画布(仅在内存画布中)。然后通过将第二个画布重复绘制到可见画布上,每行随机X偏移,创建多个垂直草行。
for each grassObj:
    bentX, bentZ = mathCalcs(grassObj);
    bentX, bentZ = clampToValidValue(bendX, bentZ); 
    frames[bendX][bentZ].draw();