[英]Animated particles in shape (canvas + kineticjs)
I use KineticJS to perform a wave motion within a shape. 我使用KineticJS在形状内执行波动。
I would now insert in my wave particles that are moving too. 现在,我也将要移动的波动粒子插入其中。
Currently I'm doing this: ( JSFiddle ) 目前,我正在这样做:( JSFiddle )
window.requestAnimFrame = (function() {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 1000 / 60);
};
})();
// Wave functions
var w = 205;
var h = 100;
var osc1 = new osc(),
osc2 = new osc(),
osc3 = new osc(),
horizon = h * 0.5;
count = 40,
step = Math.ceil(w / count),
buffer = new ArrayBuffer(count * 4),
points = new Float32Array(buffer);
osc1.max = 20;
osc2.max = 20;
osc2.speed = 0.015;
function fill() {
for(var i = 0; i < count; i++) {
points[i] = mixer(osc1, osc2, osc3);
}
}
fill();
function osc() {
this.variation = 0.1;
this.max = 30;
this.speed = 0.030;
var me = this,
a = 0,
max = getMax();
this.getAmp = function() {
a += this.speed;
if (a >= 2.0) {
a = 0;
max = getMax();
}
return max * Math.sin(a * Math.PI);
};
function getMax() {
return Math.random() * me.max * me.variation +
me.max * (1 - me.variation);
}
return this;
}
function mixer() {
var d = arguments.length,
i = d,
sum = 0;
if (d < 1) return 0;
while(i--) sum += arguments[i].getAmp();
return sum / d + horizon;
}
// End wave functions
// Particles functions
var inWave = [];
var particlesInWave = 15;
var cw = 200;
var ch = 200;
function createParticlesInWave() {
for (var i = 0; i < particlesInWave; i++)
inWave.push(new inParticle());
}
function updateParticlesInWave() {
for (var i = 0; i < inWave.length - 1; i++) {
inWave[i].x -= inWave[i].vx;
inWave[i].y += inWave[i].vy;
if (inWave[i].x > cw)
inWave[i].x = 0;
if (inWave[i].x < 0)
inWave[i].x = cw;
if (inWave[i].y < 0)
inWave[i].y = ch;
switch (inWave[i].oSwitch) {
case true:
inWave[i].opacity += 0.01;
if (inWave[i].opacity >= 1)
inWave[i].oSwitch = false;
break;
case false:
inWave[i].opacity -= 0.01;
if (inWave[i].opacity <= 0)
inWave[i].oSwitch = true;
break;
default:
break;
}
}
}
var inParticle = function() {
this.x = Math.random() * cw;
this.y = Math.random() * ch;
this.radius = Math.random() * 2;
this.vx = -2 + Math.random() * 4;
this.vy = -4 + Math.random() * 2;
this.opacity = Math.random();
this.oSwitch = true;
};
function renderParticlesInWave() {
for (var i = 0; i < inWave.length - 1; i++) {
tp = inWave[i];
if (inWave[i].y > 0 && inWave[i] != NaN || !inWave[i])
{
ctx.beginPath();
ctx.fillStyle = 'blue';
ctx.arc(tp.x, tp.y, tp.radius, 0, Math.PI * 2, false);
ctx.fill();
ctx.closePath();
}
ctx.restore();
}
}
// End particles functions
var stage = new Kinetic.Stage({
container: "myCanvas",
width: 200,
height: 200
});
var layer = new Kinetic.Layer();
var ctx = layer.getContext();
stage.add(layer);
var rect = new Kinetic.Rect({
height: 200,
width: 200,
stroke: "#4679BD",
fill: "#fff",
strokeWidth: 3,
});
var wave = new Kinetic.Shape({
drawFunc: function(context){
context.clip();
context.beginPath();
context.moveTo(0, points[0]);
for(i = 1; i < count; i++) {
context.lineTo(i * step, points[i]);
}
context.lineTo(w, h);
context.lineTo(0, h);
context.closePath();
context.fillStrokeShape(this);
context.restore();
},
fill: "#4679BD",
y: 50
});
layer.add(rect);
layer.add(wave);
stage.add(layer);
createParticlesInWave();
var anim = new Kinetic.Animation(function(frame) {
updateParticlesInWave();
var i;
for(i = 0; i < count - 1; i++) {
points[i] = points[i + 1];
}
points[count - 1] = mixer(osc1, osc2, osc3);
wave.setDrawFunc(function(context) {
context.clip();
context.beginPath();
context.moveTo(0, points[0]);
for(i = 1; i < count; i++) {
context.lineTo(i * step, points[i]);
}
context.lineTo(200, 200);
context.lineTo(0, 200);
context.closePath();
context.fillStrokeShape(this);
context.restore();
});
}, layer);
function loop() {
renderParticlesInWave();
requestAnimFrame( loop );
}
anim.start();
loop();
How can I make my particles move only in my wave? 如何使粒子仅在波浪中移动?
Thanks a lot for your help :) 非常感谢你的帮助 :)
To do this you have to test if a bubble touches the water when it goes up. 为此,您必须测试气泡上升时是否接触到水。
if (y < 50 + points[0 | (x / step)]) thisPart.y = ch;
http://jsfiddle.net/gamealchemist/2Y8KU/1/ http://jsfiddle.net/gamealchemist/2Y8KU/1/
function updateParticlesInWave() {
var thisPart = null;
for (var i = 0; i < inWave.length - 1; i++) {
thisPart = inWave[i];
thisPart.x -= thisPart.vx;
thisPart.y += thisPart.vy;
var x = thisPart.x,
y = thisPart.y;
if (y < 50 + points[0 | (x / step)]) thisPart.y = ch;
if (x > cw) thisPart.x = 0;
else if (x < 0) thisPart.x = cw;
if (y < 0) thisPart.y = ch;
if (thisPart.oSwitch) {
thisPart.opacity += 0.01;
if (thisPart.opacity >= 1) thisPart.oSwitch = false;
} else {
thisPart.opacity -= 0.01;
if (thisPart.opacity <= 0) thisPart.oSwitch = true;
}
}
}
For the performances : 1) yes, try avoiding using both animationFrame and the anim of Kinetics : set the bubbles as another layer, and have all done by Kinetics. 对于性能:1)是,请尝试避免同时使用animationFrame和Kinetics的动画:将气泡设置为另一层,并全部由Kinetics完成。 2) you redefine the renderParticlesInWave() each tick, which is bad for performances : try to define it clean once and for all.
2)在每个刻度上重新定义renderParticlesInWave(),这对性能不利:请尝试将其定义为一劳永逸。
let me know when you did this, and i'll throw an eye for performances. 让我知道您什么时候做的,我会关注表演的。
i drawfunc of wave : 我wave的函数:
: context.lineTo(w, 2*h); :context.lineTo(w,2 * h); context.lineTo(0, 2*h);
context.lineTo(0,2 * h);
so you don't have to set it again and again in animate. 因此您无需一次又一次地设置动画。
speed up also in draw bubbles : color not set. 在绘制气泡时也加快速度:颜色未设置。 opacity seems of no effect (?)
不透明似乎没有效果(?)
You forgot to save the context before clipping. 您在剪切之前忘记保存上下文。
and a few speed up here and there. 还有一些在这里和那里加速。
http://jsfiddle.net/gamealchemist/2Y8KU/5/ http://jsfiddle.net/gamealchemist/2Y8KU/5/
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.