Fade an image in - javascript

I am trying to fade an image in a canvas environment. Essientially what I want to do is while moving an image from left to right, I want to fade it from 0% alpha to 100% alpha. When I comment the globalAlpha and alpha info out in my code, it moves like I want it to, my only issue is getting it to fade. I am able to get the globalAlpha function to work, but it affects all the artwork in the canvas area. Is there a way I can just affect the one element? eventually I will want to fade in multiple elements at different times in the animation based on a timer, but if I can get this to work first I can go from there.
window.addEventListener('load', eventWindowLoaded, false);
function eventWindowLoaded()
{
canvasApp();
}
function canvasSupport ()
{
return Modernizr.canvas;
}
function canvasApp()
{
if (!canvasSupport())
{
return;
}
var pointImage = new Image();
pointImage.src = "images/barry.png";
var barry = new Image();
barry.src = "images/barry.png";
/*var alpha = 0;
context.globalAlpha = 1;*/
function drawScreen()
{
//context.globalAlpha = 1;
context.fillStyle = '#EEEEEE';
context.fillRect(0, 0, theCanvas.width, theCanvas.height);
//context.globalAlpha = alpha;
//Box
context.strokeStyle = '#000000';
context.strokeRect(1, 1, theCanvas.width-2, theCanvas.height-2);
if (moves > 0 )
{
moves--;
ball.x += xunits;
ball.y += yunits;
}
context.drawImage(barry, ball.x, ball.y);
/*context.restore();
alpha += .1;
if (alpha > 1)
{
alpha = 0;
}*/
}
var speed = 1;
var p1 = {x:20,y:250};
var p2 = {x:40,y:250};
var dx = p2.x - p1.x;
var dy = p2.y - p1.y;
var distance = Math.sqrt(dx*dx + dy*dy);
var moves = distance/speed;
var xunits = (p2.x - p1.x)/moves;
var yunits = (p2.y - p1.y)/moves;
var ball = {x:p1.x, y:p1.y};
var points = new Array();
theCanvas = document.getElementById("canvas");
context = theCanvas.getContext("2d");
ctx = theCanvas.getContext("2d");
setInterval(drawScreen, 10);
}
any suggestions are welcome!

I think this other question will give you a way to do so.
it shows how to load an element in the canvas context then how to fade it in..
How to change the opacity (alpha, transparency) of an element in a canvas element after it has been drawn?

Related

Make a shape move up on a canvas

Currently, I have a canvas which is the width and height of your browser. Using this code:
var requestAnimationFrame = window.requestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.msRequestAnimationFrame;
var canvas = document.getElementById("canvas");
var width = window.innerWidth;
var height = window.innerHeight;
var circle = canvas.getContext("2d");
canvas.width = width;
canvas.height = height;
for(var i = 0; i < numofcirc; i++)
{
name = "circleno" + i;
var name = new Array(3);
name = [height, rndwidth, rndradius, vel]
circles[i] = name;
}
var vel = 2;
var circles = [];
var numofcirc = 1;
var name;
function DrawCircle()
{
rndwidth = Math.floor((Math.random() * width) + 1);
height = height - 13;
rndradius = Math.floor((Math.random() * 15) + 5);
circle.beginPath();
circle.arc(rndwidth, height, rndradius, 0, 2*Math.PI);
circle.fillStyle = "white";
circle.fill();
circle.translate(0,6);
}
function Move()
{
circle.translate(0,6);
requestAnimationFrame(Move);
}
Move();
DrawCircle();
I am able to create a circle placed randomly at the bottom of your screen. The bit of the code that isn't working is this:
function Move()
{
circle.translate(0,6);
requestAnimationFrame(Move);
}
Fireworks();
When DrawCircle(); is called, the circle is drawn on the canvas. Then Move(); is called. Becuase it uses requestAnimationFrame the function Move(); repeats over and over again. I want this code to move that circle drawn ealier up by 6, so it looks like the circle moving up.
If I add the circle.translate(0,6); to the DrawCircle(); function and change the DrawCircle(); function to this:
function DrawCircle()
{
rndwidth = Math.floor((Math.random() * width) + 1);
height = height - 13;
rndradius = Math.floor((Math.random() * 15) + 5);
circle.beginPath();
circle.arc(rndwidth, height, rndradius, 0, 2*Math.PI);
circle.fillStyle = "white";
circle.fill();
circle.translate(0,6);
requestAnimationFrame(Move);
}
DrawCircle();
then it keeps on drawing rows of circles across the screen which are all separated by 6.
Is there any way I can just make one single circle move up on your screen when it is drawn?
Thank you for you help #HelderSepu !
You should look at examples and build from that...
Here is one simple case:
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
canvas.width = canvas.height = 170;
var circles = []
circles.push({color:"red", x:120, y:120, r:15, speed:{x: 0, y: -0.5}})
circles.push({color:"blue", x:80, y:120, r:20, speed:{x: -0.5, y: -2.5}})
circles.push({color:"green", x:40, y:120, r:5, speed:{x: -1.5, y: -1.0}})
function DrawCircle() {
context.clearRect(0, 0, canvas.width, canvas.height);
circles.forEach(function(c) {
c.x += c.speed.x;
c.y += c.speed.y;
context.beginPath();
context.arc(c.x, c.y, c.r, 0, 2 * Math.PI);
context.fillStyle = c.color;
context.fill();
if (c.x + c.r < 0) c.x = canvas.width + c.r
if (c.y + c.r < 0) c.y = canvas.height + c.r
});
window.requestAnimationFrame(DrawCircle);
}
DrawCircle();
<canvas id="canvas"></canvas>
But if you are going to do a lot more animations you should consider using a game engine, there are a lot of great open source ones:
https://github.com/collections/javascript-game-engines
Since you're getting a sequence of circles, it looks like you're not clearing the canvas when a frame is drawn. Simply draw a white rectangle that fills the canvas whenever a new frame is requested, then draw your circle.
The method you provide as an argument to requestAnimationFrame is responsible for drawing a complete image on the canvas which replaces whatever was there during the previous frame.

How do I add four rotating images to an animated background?

I am trying to add four rotating images to an animated background.
I can only get one image working correctly with my code below.
How can I add in the other three images?
var canvas = document.getElementById('c');
var ctx = canvas.getContext('2d');
var img = document.createElement('img');
img.onload = function(){
render();
}
img.src = 'nano3.png';
function drawImage(img,x,y,r,sx,sy){
sx=sx||0;
sy=sy||0;
r=(r*Math.PI/180)||0;
var cr = Math.cos(r);
var sr = Math.sin(r);
ctx.setTransform(cr,sr,-sr,cr,x-(cr*sx-sr*sy),y-(sr*sx+cr*sy));
ctx.drawImage(img,1,2);
}
var r = 1;
function render(){
requestAnimationFrame(render);
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.clearRect(0,0,800,800);
drawImage(img,50,50,r++,img.width/2,img.height/2);
}
This should help you out, I just created an object known as rotatingimage which stores a location, an image and its current rotation. We call the 'draw' method in a 'setInterval' function call which deals with rotating the canvas and then drawing the sprite correctly.
Just a note rotating many images can cause the canvas to lag also the CurrentRotation variable never gets reset to 0 when it reaches >359 so the CurrentRotation variable will keep going higher and higher, you may want to fix that in the RotatingImage.prototype.Draw function
jsFiddle:https://jsfiddle.net/xd8brfrk/
Javascript
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
function RotatingImage(x, y, spriteUrl, rotationSpeed) {
this.XPos = x;
this.YPos = y;
this.Sprite = new Image();
this.Sprite.src = spriteUrl;
this.RotationSpeed = rotationSpeed;
this.CurrentRotation = 0;
}
RotatingImage.prototype.Draw = function(ctx) {
ctx.save();
this.CurrentRotation += 0.1;
ctx.translate(this.XPos + this.Sprite.width/2, this.YPos + this.Sprite.height/2);
ctx.rotate(this.CurrentRotation);
ctx.translate(-this.XPos - this.Sprite.width/2, -this.YPos - this.Sprite.height/2);
ctx.drawImage(this.Sprite, this.XPos, this.YPos);
ctx.restore();
}
var RotatingImages = [];
RotatingImages.push(new RotatingImage(50, 75, "http://static.tumblr.com/105a5af01fc60eb94ead3c9b342ae8dc/rv2cznl/Yd9oe4j3x/tumblr_static_e9ww0ckmmuoso0g4wo4okosgk.png", 1));
RotatingImages.push(new RotatingImage(270, 25, "http://static.tumblr.com/105a5af01fc60eb94ead3c9b342ae8dc/rv2cznl/Yd9oe4j3x/tumblr_static_e9ww0ckmmuoso0g4wo4okosgk.png", 1));
RotatingImages.push(new RotatingImage(190, 180, "http://static.tumblr.com/105a5af01fc60eb94ead3c9b342ae8dc/rv2cznl/Yd9oe4j3x/tumblr_static_e9ww0ckmmuoso0g4wo4okosgk.png", 1));
RotatingImages.push(new RotatingImage(100, 270, "http://static.tumblr.com/105a5af01fc60eb94ead3c9b342ae8dc/rv2cznl/Yd9oe4j3x/tumblr_static_e9ww0ckmmuoso0g4wo4okosgk.png", 1));
setInterval(function() {
ctx.fillStyle = "#000"
ctx.fillRect(0, 0, canvas.width, canvas.height);
for (var i = 0; i < RotatingImage.length; i++) {
var rotatingImage = RotatingImages[i];
rotatingImage.Draw(ctx);
}
}, (1000 / 60));
you can use save and restore to apply different transform to your drawing
https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/save
https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/restore

Make canvas transparent

This is what my body looks like:
body
{
background-image:url('../images/bg.png');
background-repeat:no-repeat;
background-size:fixed 100vw;
background-position:center;
}
The issue is, the canvas is white instead of being transparent. Is there a way to make it transparent so I can place the dna wave on top of a background?
Codepen example
One easy way, is using an offscreen canvas.
First set its context's globalAlpha value to something between 0 and 1, this will determine how fast your previous drawings will disappear.
Then, in the animation loop, before doing the new drawings,
clear the offscreen context,
draw the visible canvas on the offscreen one,
clear the visible canvas
draw back the offscreen one on the visible one
In the process, your image will have lost opacity.
var clear = function(){
// clear the clone canvas
cloneCtx.clearRect(0,0,canvasWidth, canvasHeight)
// this should be needed at init and when canvas is resized but for demo I leave it here
cloneCtx.globalAlpha = '.8';
// draw ou visible canvas, a bit less opaque
cloneCtx.drawImage(context.canvas, 0,0)
// clear the visible canvas
context.clearRect(0,0,canvasWidth, canvasHeight)
// draw back our saved less-opaque image
context.drawImage(clone, 0,0)
}
var canvas = document.getElementById('canvas'),
context = canvas.getContext('2d'),
// create an offscreen clone
clone = canvas.cloneNode(),
cloneCtx = clone.getContext('2d'),
canvasWidth = canvas.width =
clone.width =window.innerWidth,
canvasHeight = canvas.height = clone.height = window.innerHeight,
globalTick = 0,
points = [],
pointCount = 12,
pointSpeed = 6,
spacing = canvasWidth / pointCount,
pointCount = pointCount + 2,
verticalPointRange = 60,
randomRange = function(min, max){
return Math.floor( (Math.random() * (max - min + 1) ) + min);
},
iPath,
iPoints;
var Point = function(x, y, alt){
this.x = x;
this.y = y;
this.yStart = y;
this.alt = alt;
}
Point.prototype.update = function(i){
var range = (this.alt) ? verticalPointRange : -verticalPointRange;
this.x += pointSpeed;
this.y = (this.yStart) + Math.sin(globalTick/14) * -range;
if(this.x > (canvasWidth + spacing)){
this.x = -spacing;
var moved = points.splice(i, 1);
points.unshift(moved[0]);
}
}
var updatePoints = function(){
var i = points.length;
while(i--){
points[i].update(i);
}
}
for(iPoints = 0; iPoints < pointCount; iPoints++){
var alt = (iPoints % 2 === 0);
var offset = (alt) ? verticalPointRange : -verticalPointRange;
points.push(new Point(spacing * (iPoints-1), canvasHeight/2, alt));
}
var renderPath = function(){
context.beginPath();
context.moveTo(points[0].x, points[0].y);
for(iPath = 1; iPath < pointCount; iPath++){
context.lineTo(points[iPath].x, points[iPath].y);
}
context.stroke();
}
var loop = function(){
requestAnimationFrame(loop, canvas);
clear();
updatePoints();
renderPath();
globalTick++;
};
loop();
canvas { display: block; }
body{
background-color: ivory;
}
<canvas id="canvas"></canvas>
Canvases are transparent by default.
Try setting a page background image, and then put a canvas over it. If nothing is drawn on the canvas, you can fully see the page background.
you should try
context.clearRect(0,0,width,height);
for more you can refer How do I make a transparent canvas in html5?

Convert squares to circles in canvas html

OK so I appreciate that this is a massively basic question but I'm totally new to canvas and I just need to do something simple. Basically I am using springy.js to draw force directed graphs. The nodes on the graph are squares and I just want them to be circles. Can someone show me what I should change in the code below and I can figure out the rest from there
I tried
ctx.arc(s.x - boxWidth/2, s.y - boxHeight/2, boxWidth, boxHeight,2*Math.PI);
ctx.stroke();
instead of the line with clearRect but the boxes remain and the connections between boxes stop being straight lines.
function drawNode(node, p) {
var s = toScreen(p);
ctx.save();
// Pulled out the padding aspect sso that the size functions could be used in multiple places
// These should probably be settable by the user (and scoped higher) but this suffices for now
var paddingX = 6;
var paddingY = 6;
var contentWidth = node.getWidth();
var contentHeight = node.getHeight();
var boxWidth = contentWidth + paddingX;
var boxHeight = contentHeight + paddingY;
// clear background
ctx.clearRect(s.x - boxWidth/2, s.y - boxHeight/2, boxWidth, boxHeight);
// fill background
if (selected !== null && selected.node !== null && selected.node.id === node.id) {
ctx.fillStyle = "#FFFFE0"; //when clicked
} else if (nearest !== null && nearest.node !== null && nearest.node.id === node.id) {
ctx.fillStyle = "#EEEEEE";//when hovered over
} else {
//if the node.FBScore >10 then ctx.fillStyle = "#F00909";
ctx.fillStyle = "#E34747";//normal colour
}
ctx.fillRect(s.x - boxWidth/2, s.y - boxHeight/2, boxWidth, boxHeight);
if (node.data.image == undefined) {
ctx.textAlign = "left";
ctx.textBaseline = "top";
ctx.font = (node.data.font !== undefined) ? node.data.font : nodeFont;
ctx.fillStyle = (node.data.color !== undefined) ? node.data.color : "#000000";
var text = (node.data.label !== undefined) ? node.data.label : node.id;
ctx.fillText(text, s.x - contentWidth/2, s.y - contentHeight/2);
} else {
// Currently we just ignore any labels if the image object is set. One might want to extend this logic to allow for both, or other composite nodes.
var src = node.data.image.src; // There should probably be a sanity check here too, but un-src-ed images aren't exaclty a disaster.
if (src in nodeImages) {
if (nodeImages[src].loaded) {
// Our image is loaded, so it's safe to draw
ctx.drawImage(nodeImages[src].object, s.x - contentWidth/2, s.y - contentHeight/2, contentWidth, contentHeight);
}
}else{
// First time seeing an image with this src address, so add it to our set of image objects
// Note: we index images by their src to avoid making too many duplicates
nodeImages[src] = {};
var img = new Image();
nodeImages[src].object = img;
img.addEventListener("load", function () {
// HTMLImageElement objects are very finicky about being used before they are loaded, so we set a flag when it is done
nodeImages[src].loaded = true;
});
img.src = src;
}
}
ctx.restore();
}
Instead of replacing the clearRect() method, you should replace the fillRect() with the arc(x, y, radius, startAngle, endAngle, anticlockwise); one :
var canvas = document.querySelector('canvas');
var ctx = canvas.getContext('2d');
function drawNode() {
var s = {
x: (Math.random() * 200) + 50,
y: (Math.random() * 200) + 50
};
var paddingX = 6;
var paddingY = 6;
var contentWidth = s.x / 5;
var contentHeight = s.y / 5;
var boxWidth = contentWidth + paddingX;
var boxHeight = contentHeight + paddingY;
ctx.fillStyle = '#AAFFAA';
// I modified it so the whole canvas will be cleared
ctx.clearRect(0, 0, canvas.width, canvas.height);
// We start a new path
ctx.beginPath();
// then we draw our circle, setting its radius to the max between contentWidth and contentHeight
ctx.arc(s.x, s.y , Math.max(boxWidth,boxHeight)/2, 0, 2 * Math.PI);
// and finally we fill it
ctx.fill();
}
document.addEventListener('click', drawNode);
drawNode();
canvas{cursor:pointer};
<canvas height="300" width="300" />
I have create a simple jsFiddle to show how to draw a curved corner rectangle
-- Updated so you can now simply change the roundedValue which will then change the smoothness of the corners.
http://jsfiddle.net/gHCJt/1127/
// Get canvas
var canvas = $("#canvas");
var context = canvas.get(0).getContext("2d");
// Draw simple rect
var rectX = 125;
var rectY = 125;
var rectWidth = 150;
var rectHeight = 150;
var roundedValue = 75;
// Apply corner
context.lineJoin = "round";
context.lineWidth = roundedValue;
// Apply the corner to the draw method for strokeRect and fillRect
context.strokeRect(rectX+(roundedValue/2), rectY+(roundedValue/2), rectWidth-roundedValue, rectHeight-roundedValue);
context.fillRect(rectX+(roundedValue/2), rectY+(roundedValue/2), rectWidth-roundedValue, rectHeight-roundedValue);

Chroma keying with javascript & jQuery

Okay, we need your help! We (with our informatics class) are building a digital scratchmap! Like this:
(source: megagadgets.nl)
With your mouse you should be able to scratch out the places you've been to. Now we're stuck. We have a canvas and we draw the image of a world map. Then when the user clicks and drags a stroke gets add on top of the world map.
Now we want to convert the (green drawn) strokes to transparency so we can reveal the image behind it. (Just like scratching out the places you've been to and revealing the map behind it (in colour)).
This is our html:
<body>
<h1>Scratchmap</h1>
<hr>
<canvas id="ball" width="600px" height ="600px">
</canvas>
<canvas id="ball2" width="600px" height ="600px">
</canvas>
</body>
And this is our javascript:
// Set variables
var a_canvas = document.getElementById("ball");
var context = a_canvas.getContext("2d");
var a_canvas2 = document.getElementById("ball2");
var context2 = a_canvas2.getContext("2d");
var img = new Image();
img.onload = function () {
context.drawImage(img, img_x, img_y);
}
img.src = "worldmap.png"
var mouse_pos_x = [];
var mouse_pos_y = [];
var thickness = 0;
var arraycount = 0;
var mouse_down = false;
var mouse_skip = [];
function update() {}
document.body.onmousedown = function () {
mouse_down = true;
var mouseX, mouseY;
if (event.offsetX) {
mouseX = event.offsetX;
mouseY = event.offsetY;
} else if (event.layerX) {
mouseX = event.layerX;
mouseY = event.layerY;
}
mouse_pos_x.push(mouseX);
mouse_pos_y.push(mouseY);
arraycount += 1;
}
document.body.onmouseup = function () {
if (mouse_down) {
mouse_down = false;
mouse_skip.push(arraycount);
}
}
document.body.onmousemove = function () {
if (mouse_down) {
var mouseX, mouseY;
if (event.offsetX) {
mouseX = event.offsetX;
mouseY = event.offsetY;
} else if (event.layerX) {
mouseX = event.layerX;
mouseY = event.layerY;
}
context.drawImage(img, 0, 0);
mouse_pos_x.push(mouseX);
mouse_pos_y.push(mouseY);
context.lineWidth = 2.5;
context.strokeStyle = "#00FF00";
context.moveTo(mouse_pos_x[arraycount - 1], mouse_pos_y[arraycount - 1]);
context.lineTo(mouse_pos_x[arraycount], mouse_pos_y[arraycount]);
context.stroke();
arraycount += 1;
var imgdata = context.getImageData(0, 0, a_canvas.width, a_canvas.height);
var l = imgdata.data.length / 4;
for (var i = 0; i < l; i++) {
var r = imgdata.data[i * 4 + 0];
var g = imgdata.data[i * 4 + 1];
var b = imgdata.data[i * 4 + 2];
if (g < 255) {
imgdata.data[i * 4 + 3] = 0;
}
}
context2.putImageData(imgdata, 0, 0);
}
}
setInterval(update, 10);
Now when we remove the draw_image() the green color becomes yellow on the other canvas. But with the draw_image() nothing gets drawn on the second canvas.
What's going wrong? Or do you have a way to do this with other Javascript or not in javascript at all?
Any help would be appreciated!
Luud Janssen & Friends
You can do this with a slightly different approach:
Set the hidden image as CSS background
Draw the cover image on top using context
Change composite mode to destination-out
Anything now drawn will erase instead of draw revealing the (CSS set) image behind
Live demo
The key code (see demo linked above for details):
function start() {
/// draw top image - background image is already set with CSS
ctx.drawImage(this, 0, 0, canvas.width, canvas.height);
/// KEY: this will earse where next drawing is drawn
ctx.globalCompositeOperation = 'destination-out';
canvas.onmousedown = handleMouseDown;
canvas.onmousemove = handleMouseMove;
window.onmouseup = handleMouseUp;
}
Then it's just a matter of tracking the mouse position and draw any shape to erase that area, for example a circle:
function erase(x, y) {
ctx.beginPath();
ctx.arc(x, y, radius, 0, pi2);
ctx.fill();
}
Random images for illustrative purposes

Categories

Resources