Reputation: 411
Trying to create a function that can dynamically oscillate properties of an object. I've already managed to create it outside of a function, but I can't make it work in one. It's because of the angle variable, which increases each frame. Here's an example to make an object oscillate x and y props in a circle.
Initialization...
var obj = new Ball(arguments...),
target = {
x: 100,
y: 100
},
angle = 0,
radius = 50,
speed = 0.1;
Loop...
// clear canvas
obj.x = target.x + Math.cos(angle) * radius;
obj.y = target.y + Math.sin(angle) * radius;
angle += speed;
// rAF
That works just fine, but when I try to make it reusable and turn it into a function, it doesn't work.
function oscillate(obj, target, angle, radius, speed) {
obj.x = target.x + Math.cos(angle) * radius;
obj.y = target.y + Math.sin(angle) * radius;
angle += speed;
}
How do I make it work in a function?
Upvotes: 0
Views: 968
Reputation: 288590
That's because angle
is not passed by reference. JS does not have pass by reference.
You can just modify the outer variable by not declare a local one:
var map = document.getElementById('map'),
fx = map.getContext('2d');
var ball = {
x: 50,
y: 50,
radius: 50
},
target = {
x: map.width / 2,
y: map.height / 2,
},
angle = 0,
radius = 50,
speed = 0.1;
ball.draw = function(fx) {
fx.beginPath();
fx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, false);
fx.fill();
};
function oscillate(obj, target, radius, speed) {
obj.x = target.x + Math.cos(angle) * radius;
obj.y = target.y + Math.sin(angle) * radius;
angle += speed;
}
(function update() {
fx.clearRect(0, 0, map.width, map.height);
oscillate(ball, target, radius, speed)
ball.draw(fx);
requestAnimationFrame(update);
}());
<canvas id='map'></canvas>
Alternatively, pass an object:
var map = document.getElementById('map'),
fx = map.getContext('2d');
var ball = {
x: 50,
y: 50,
radius: 50
},
data = {
obj: ball,
target: {
x: map.width / 2,
y: map.height / 2,
},
angle: 0,
radius: 50,
speed: 0.1
};
ball.draw = function(fx) {
fx.beginPath();
fx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, false);
fx.fill();
};
function oscillate(data) {
data.obj.x = data.target.x + Math.cos(data.angle) * data.radius;
data.obj.y = data.target.y + Math.sin(data.angle) * data.radius;
data.angle += data.speed;
}
(function update() {
fx.clearRect(0, 0, map.width, map.height);
oscillate(data)
ball.draw(fx);
requestAnimationFrame(update);
}());
<canvas id='map'></canvas>
Upvotes: 3