J'adopte l'approche suivante pour animer un champ d'étoiles à travers l'écran, mais je suis bloqué pour la partie suivante.
JS
var c = document.getElementById('stars'),
ctx = c.getContext("2d"),
t = 0; // time
c.width = 300;
c.height = 300;
var w = c.width,
h = c.height,
z = c.height,
v = Math.PI; // angle of vision
(function animate() {
Math.seedrandom('bg');
ctx.globalAlpha = 1;
for (var i = 0; i <= 100; i++) {
var x = Math.floor(Math.random() * w), // pos x
y = Math.floor(Math.random() * h), // pos y
r = Math.random()*2 + 1, // radius
a = Math.random()*0.5 + 0.5, // alpha
// linear
d = (r*a), // depth
p = t*d; // pixels per t
x = x - p; // movement
x = x - w * Math.floor(x / w); // go around when 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
<canvas id="stars"></canvas>
CSS
canvas {
background: black;
}
Pour l'instant, il anime chaque étoile avec un delta X qui prend en compte l'opacité et la taille de l'étoile, de sorte que les plus petites semblent se déplacer plus lentement.
Utilice p = t;
pour que toutes les étoiles se déplacent à la même vitesse.
QUESTION
Je cherche un modèle clairement défini où les vitesses donnent l'illusion des étoiles. tournant autour de l'expectative définie en fonction du centre de rotation. cX, cY
et l'angle de vision v
ce qui correspond à la fraction de 2π que l'on peut voir (si le centre du cercle n'est pas le centre de l'écran, le rayon devrait être au moins la plus grande partie). J'ai du mal à trouver un moyen qui applique ce cosinus à la vitesse de déplacement des étoiles, même pour un cercle centré avec une rotation de π.
Ces diagrammes pourraient expliquer davantage ce que je recherche :
Cercle centré :
Non centré :
Un angle de vision différent :
Je suis vraiment perdue quant à la façon d'avancer. Je me suis déjà un peu fatigué pour en arriver là. Pouvez-vous m'aider à faire les premiers pas ?
Merci
UPDATE
J'ai fait quelques progrès avec ce code :
// linear
d = (r*a)*z, // depth
v = (2*Math.PI)/w,
p = Math.floor( d * Math.cos( t * v ) ); // pixels per t
x = x + p; // movement
x = x - w * Math.floor(x / w); // go around when x < 0
Dónde p
est la coordonnée x d'une particule en mouvement circulaire uniforme et v
est la vitesse angulaire, mais cela génère un effet de pendule. Je ne sais pas comment modifier ces équations pour créer l'illusion que l'observateur tourne au contraire.
UPDATE 2 :
On y est presque. Un utilisateur du canal ##Math freenode a eu la gentillesse de proposer le calcul suivant :
// linear
d = (r*a), // depth
p = t*d; // pixels per t
x = x - p; // movement
x = x - w * Math.floor(x / w); // go around when 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;
L'effet est obtenu visuellement, mais il ne suit pas un modèle clairement défini en termes de variables (il ne fait que "bidouiller" l'effet). Je ne vois donc pas de moyen direct de réaliser différentes implémentations (changer le centre, l'angle de vision). Le modèle réel pourrait être très similaire à celui-ci.
MISE À JOUR 3
Suite à la réponse d'Iftah, j'ai pu utiliser Sylvester pour appliquer une matrice de rotation aux étoiles, qui doivent d'abord être enregistrées dans un tableau. De plus, les données de chaque étoile z
est maintenant déterminée et le rayon r
et l'opacité a
en sont dérivés à la place. Le code est substantiellement différent et plus long donc je ne le posterai pas, mais il pourrait être un pas dans la bonne direction. Je n'arrive pas encore à obtenir une rotation continue. L'utilisation d'opérations matricielles sur chaque image semble coûteuse en termes de performances.