Canvas 旋转的星空场景

11 浏览
0 Comments

Canvas 旋转的星空场景

我正在采取以下方法来在屏幕上播放星空动画,但我卡在了下一步。

JS

var c = document.getElementById('stars'),
    ctx = c.getContext("2d"),
    t = 0; // 时间
c.width = 300;
c.height = 300;
var w = c.width,
    h = c.height,
    z = c.height,
    v = Math.PI; // 视角
(function animate() {
    Math.seedrandom('bg');
    ctx.globalAlpha = 1;
    for (var i = 0; i <= 100; i++) {
        var x = Math.floor(Math.random() * w), // x坐标
            y = Math.floor(Math.random() * h), // y坐标
            r = Math.random()*2 + 1, // 半径
            a = Math.random()*0.5 + 0.5, // 透明度
            // 线性
            d = (r*a),       // 深度
            p = t*d;         // 每帧移动的像素数
        x = x - p;       // 移动
        x = x - w * Math.floor(x / w); // x<0时绕行
        (function draw(x,y) {
            var gradient = ctx.createRadialGradient(x, y, 0, x + r, y + r, r * 2);
            gradient.addColorStop(0, 'rgba(255, 255, 255, ' + a + ')');
            gradient.addColorStop(1, 'rgba(0, 0, 0, 0)');
            ctx.beginPath();
            ctx.arc(x, y, r, 0, 2*Math.PI);
            ctx.fillStyle = gradient;
            ctx.fill();
            return draw;
        })(x, y);
    }
    ctx.restore();
    t += 1;
    requestAnimationFrame(function() {
        ctx.clearRect(0, 0, c.width, c.height);
        animate();
    });
})();

HTML


CSS

canvas {
    background: black;
}

JSFiddle

现在它的功能是根据星星的不透明度和大小以及 delta X 来播放每个星星的动画,因此最小的星星看起来移动得更慢。

使用 p = t; 可以让所有的星星以相同的速度移动。

问题

我正在寻找一个明确定义的模型,其中速度可以给人以星星围绕观察者旋转的错觉,以圆心 cX, cY 和视角 v 来定义(如果圆的中心不是屏幕的中心,则半径应至少为最大部分)。我很难找到一种方法,将这个余弦应用到星星移动的速度上,即使是一个以π为旋转的中心的圆也是如此。

下面的图表可能会进一步解释我的要求:

居中的圆:

center of vision in x,y

非居中的:

shifted center

不同的视角:

different angle of vision

我真的不知道如何继续前进。我已经为了到达这里而努力了一点。你能帮我开始一些第一步吗?

谢谢


更新

我在这段代码中取得了一些进展:

        // 线性
        d = (r*a)*z,   // 深度
        v = (2*Math.PI)/w,
        p = Math.floor( d * Math.cos( t * v ) );     // 每帧移动的像素数
    x = x + p;       // 移动
    x = x - w * Math.floor(x / w); // x<0时绕行

JSFiddle

其中 p 是均匀圆周运动中粒子的 x 坐标,v 是角速度,但这会产生钟摆效应。我不确定如何改变这些方程来创建观察者转动的错觉。


更新2:

接近成功。在 ##Math freenode 频道的一位用户友情提供了以下计算方法:

        // 线性
        d = (r*a),       // 深度
        p = t*d;         // 每帧移动的像素数
    x = x - p;       // 移动
    x = x - w * Math.floor(x / w); // x<0时绕行
    x = (x / w) - 0.5;
    y = (y / h) - 0.5;
    y /= Math.cos(x);
    x = (x + 0.5) * w;
    y = (y + 0.5) * h;

JSFiddle

这实现了视觉效果,但在变量方面没有遵循明确定义的模型(它只是“破解”了效果),因此我无法找到一种直接的方法来进行不同的实现(更改中心,视角)。实际模型可能与这个模型非常相似。


更新3

根据Iftah的回答,我能够使用Sylvester将星星应用旋转矩阵,但首先需要将它们保存在一个数组中。现在每颗星星的z坐标已经确定,并从中派生出半径r和透明度a。代码有很大的不同和长度,所以我不会贴出来,但这可能是朝着正确方向迈出的一步。我还不能让它持续旋转。在每一帧上使用矩阵运算似乎在性能方面是昂贵的。

JSFiddle

0