Reputation: 626
the example of the code below can be viewed here - http://dev.touch-akl.com/celebtrations/
What I have been trying to do is draw 2 images onto the canvas (glow and then flare. links for these images are below)
http://dev.touch-akl.com/celebtrations/wp-content/themes/beanstalk/img/flare.jpg
http://dev.touch-akl.com/celebtrations/wp-content/themes/beanstalk/img/blue-background.jpg
The goal is for the 'blue-background' image to sit on the canvas at the height and width of the container, and for the 'flare' image to be drawn ontop of this image with a blending mode and rotated with an animation to create a kind of twinkle effect.
My problem is that because the images I am using are rectangular when the 'flare' rotates at certain points you can see the edges of the layer underneath...
What I tried to do was find the diagonal width of the container using trigonometry and draw the 'flare' image at that width so that it always covered the whole canvas but alas you can still see the background layer at some points (but much less than before).
I need a way for the flare image to always cover the whole canvas, can anyone point me in the right direction please?
var banner = $('#banner'),
flare = document.getElementById('flare'),
glow = document.getElementById('glow'),
canvas = document.getElementById("canvas"),
ctx = canvas.getContext("2d"),
blendMode = "multiply";
$window.load(function(){
_canvasWidth = banner.outerWidth(),
_canvasHeight = banner.outerHeight();
canvas.width = _canvasWidth;
canvas.height = _canvasHeight;
var _flareSum = (_canvasWidth * _canvasWidth) + (_canvasHeight * _canvasHeight);
_flareWidth = Math.sqrt(_flareSum);
_angle = 0;
setInterval(function() {
_angle = _angle +0.25;
// draw the bg without a blend mode
ctx.globalCompositeOperation = "source-over";
ctx.drawImage(glow, 0, 0, _canvasWidth, _canvasHeight);
ctx.save();
// clear the canvas
// ctx.clearRect(0, 0, _canvasWidth, _canvasHeight);
ctx.translate( _canvasWidth/2, _canvasHeight); // move to center point
ctx.globalCompositeOperation = blendMode;
ctx.rotate(Math.PI / 180 * (_angle)); // 1/2 a degree
ctx.drawImage(flare, -_flareWidth/2, -_flareWidth/2, _flareWidth, _flareWidth); // redraw ia=mages
ctx.restore();
//console.log(_angle)
}, 1);
Upvotes: 0
Views: 131
Reputation: 105035
If I understand correctly, you need the shortest part of the flare to still cover the canvas when the flare is rotated at any angle.
Since you're only showing half the flare at any time, the shortest part of the flare is the distance from the flare center to the top of the flare:
var flareMinHeight = flare.height/2;
The longest length the flare must cover is from the flare rotation point to the top-left of the canvas.
var dx=rotationPointX;
var dy=rotationPointY;
var requiredLength=Math.sqrt(dx*dx+dy*dy);
So you will need to scale the flare to be at least the length computed above:
var minScale = requiredLength / flareMinHeight;
Upvotes: 1