FadeIn FadeOut in Html5 canvas - javascript

I ve got an canvas with an image and i want to fadein and fade out the image constantly. I ve used the above code:
<!DOCTYPE HTML>
<html>
<head>
<script>
var canvas;
var context;
var ga = 0.0;
var timerId = 0;
var timerId1 = 0;
function init()
{
canvas = document.getElementById("myCanvas");
context = canvas.getContext("2d");
timerId = setInterval("fadeIn()", 300);
console.log(timerId);
}
function fadeIn()
{
context.clearRect(0,0, canvas.width,canvas.height);
context.globalAlpha = ga;
var photo = new Image();
photo .onload = function()
{
context.drawImage(photo , 0, 0, 450, 500);
};
photo .src = "photo .jpg";
ga = ga + 0.1;
if (ga > 1.0)
{
fadeOut();
goingUp = false;
clearInterval(timerId);
}
}
function fadeOut()
{
context.clearRect(0,0, canvas.width,canvas.height);
context.globalAlpha = ga;
var photo = new Image();
photo .onload = function()
{
context.drawImage(photo , 0, 0, 450, 500);
};
photo .src = "photo .jpg";
ga = ga - 0.1;
if (ga < 0)
{
goingUp = false;
clearInterval(timerId);
}
}
</script>
</head>
<body onload="init()">
<canvas height="500" width="500" id="myCanvas"></canvas>
</body>
Is it possible to insert two functions into setIntervals?? I want to trigger fadeOut after fadeIn function. How is it possible??

Here is one way of doing this:
var alpha = 0, /// current alpha value
delta = 0.1; /// delta = speed
In the main loop then increase alpha with current alpha. When alpha has reached wither 0 or 1 reverse delta. This will create the ping-pong fade:
function loop() {
alpha += delta;
if (alpha <= 0 || alpha >= 1) delta = -delta;
/// clear canvas, set alpha and re-draw image
ctx.clearRect(0, 0, demo.width, demo.height);
ctx.globalAlpha = alpha;
ctx.drawImage(img, 0, 0);
requestAnimationFrame(loop); // or use setTimeout(loop, 16) in older browsers
}

Related

Canvas Taking too much time to move a picture up

I am trying to move a image on <canvas> to jump.
index.html
<!DOCTYPE html>
<html>
<head>
<title>Ball Jump</title>
</head>
<body>
<img src="./assets/ball.png" height="0px" width="0px" id="ball">
<br>
<br>
<canvas height="210px" width="350px" id="paper" onclick="play()"></canvas>
<script type="text/javascript" src="./main.js"></script
</body>
</html>
main.js
'use strict'
var paper = document.getElementById('paper');
var ball = document.getElementById('ball');
var brush = paper.getContext('2d');
brush.drawImage(dino, 0, 150, 70, 50);
var y = 150;
function play() {
up();
function up() {
if (y > 50) {
brush.clearRect(0, y-1, 70, y+50);
brush.drawImage(ball, 0, y, 70, 50);
y--;
}
else { clearInterval(jump); }
}
var jump = setInterval(up, 10);
function down() {
if (y < 150) {
brush.clearRect(0, y-1, 70, y+50);
brush.drawImage(ball, 0, y, 70, 50);
y++;
}
else { clearInterval(fall); }
}
var fall = setInterval(down, 10);
}
But the problem is that the ball is lagging and taking more time to go up, however it is coming down fine even if both functions are set to 10ms.
Please help!!!
I think you should use requestAnimationFrame instead of setInterval
Example
const canvas = document.querySelector('#canvas');
const context = canvas.getContext('2d');
const image = new Image();
image.src = "https://picsum.photos/seed/picsum/50/50";
image.addEventListener("load", load);
function load(event) {
loop();
}
let x = 0;
let y = 0;
let t = 0;
let r = 50;
const inc = Math.PI/90;
function loop() {
const width = canvas.width;
const height = canvas.height;
context.clearRect(0, 0, width, height);
context.drawImage(image, x, y, image.width, image.height);
x = 100 + r * Math.cos(t);
y = 100 + r * Math.sin(t);
t = t + inc;
requestAnimationFrame(loop);
}
<canvas height="400px" width="400px" id="canvas"></canvas>
I would not use multiple setInterval just one should do...
Here is an example:
var paper = document.getElementById('paper');
var brush = paper.getContext('2d');
var y = 100;
var speed = 1;
function draw() {
if ((y < 10) || (y > 150)) {
speed *= -1
}
y += speed
brush.clearRect(0, 0, 160, 300);
brush.fillRect(10, y, 10, 10);
}
function play() {
setInterval(draw, 10);
}
draw()
<canvas height="160" width="300" id="paper" onclick="play()"></canvas>
In your code, both intervals are running simultaneously that could create the strange behavior you are seeing where the object is lagging and taking more time to go up but coming down is fine.
Instead of the two setInterval I introduced the variable speed that will determine the direction of the movement and we will "flip" it speed *= -1 when the position exceeds our boundaries
... with this pattern in your canvas animation it's easy to transition to requestAnimationFrame if performance becomes critical, but for simple practice code like this, setInterval works fine.
For animations running smoothly on the browser, you should really use a requestAnimationFrame loop instead of setInterval
checkout the example here:
https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Basic_animations
here is why:
Why is requestAnimationFrame better than setInterval or setTimeout.

Create smooth animation in canvas

I have a canvas object which is rendering an image. When the user click on button the image will move to right. My problem is this movement is not smooth. The image is simply jumping to the specified position. How can I make this movement smooth? This is the codepen example Can anyone please help me?
$(window).on('load', function () {
myCanvas();
});
function myCanvas() {
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var x = 0;
function fly() {
ctx.clearRect(0, 0, c.width, c.height);
ctx.closePath();
ctx.beginPath();
var img = new Image();
img.onload = function () {
ctx.drawImage(img, x, 0);
};
img.src = 'http://via.placeholder.com/200x200?text=first';
}
fly();
$('#movebutton').click(function () {
for (i = 0; i < 200; i++) {
x = i;
requestAnimationFrame(fly);
}
});
}
<canvas id="myCanvas" width="960" height="600"></canvas>
<button id="movebutton">Move</button>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
First of all, why are you loading your image in your frame rendering function - if cache is disabled, it will request an image every frame!
I rewrote the script so that the animation is linear and smooth, you can edit the speed variable to adjust the movement speed.
$(window).on('load', function () {
var img = new Image();
img.onload = function () {
myCanvas(img);
};
img.src = 'http://via.placeholder.com/200x200?text=first';
});
function myCanvas(img) {
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var x = 0;
var last_ts = -1
var speed = 0.1
function renderScene() {
ctx.clearRect(0, 0, c.width, c.height);
ctx.closePath();
ctx.beginPath();
ctx.drawImage(img, x, 0);
}
function fly(ts) {
if(last_ts > 0) {
x += speed*(ts - last_ts)
}
last_ts = ts
if(x < 200) {
renderScene()
requestAnimationFrame(fly);
}
}
renderScene()
$('#movebutton').click(function () {
x = 0;
requestAnimationFrame(fly);
});
}

Animating images with javascript

I am trying to make the images race each other and once one of the images passes the finish line display the winner.
I have some old code I used for the animation but i don't know how to implement the images with it.
<html>
<head>
<title>Canvas Race</title>
<script src="jquery-2.2.3.js"></script>
<style type="text/css">
canvas {
border: 1px solid black;
background-image: url("http://www.gamefromscratch.com/image.axd?picture=road2048v2.png");
background-size: 200px 300px;
background-position-y: -81px;
}
</style>
</head>
<body>
<canvas id="canvas" width="1100" height="150" >
<script>
var blueCar = new Image();
var redCar = new Image();
// images
function image(){
blueCar.src = "http://worldartsme.com/images/car-top-view clipart-1.jpg";
redCar.src = "http://images.clipartpanda.com/car-clipart-top-view-free-vector-red-racing-car-top-view_099252_Red_racing_car_top_view.png";
}
window.onload = function draw(){
var ctx = document.getElementById('canvas').getContext('2d');
ctx.globalCompositeOperation = 'destination-over';
window.requestAnimationFrame(draw);
window.requestAnimationFrame(animate);
// finish line
ctx.beginPath();
ctx.moveTo(1020, 150);
ctx.lineTo(1020, 0);
ctx.strokeStyle = "#FFEF0E";
ctx.stroke();
//blue car
ctx.save();
if(blueCar.complete){
ctx.drawImage(blueCar, 10, 10, 100, 60);
}
// red car
if(redCar.complete){
ctx.drawImage(redCar, 10, 80, 100, 60);
}
}
image();
</script>
</canvas>
<div id="winner"></div>
</body>
</html>
Old code:
I want to use this old code but i don't know what to remove and how to add the images that i have above for the cars. As you can see for this code i created squares instead of images.
window.requestAnimFrame = (function(callback) {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 1000 / 60);
};
})();
// drawing red square
function drawRedRect(redCar, ctx) {
ctx.beginPath();
ctx.drawImage(redCar, 5, 5);
}
// finish line
function drawFinishLine(ctx){
ctx.beginPath();
ctx.moveTo(1040, 150);
ctx.lineTo(1040, 0);
ctx.stroke();
}
// this is drawing the blue square
function drawBlueRect(blueRectangle, ctx){
ctx.beginPath();
ctx.rect(blueRectangle.x, blueRectangle.y, blueRectangle.width, blueRectangle.height);
ctx.fillStyle = 'blue';
ctx.fill();
}
// red square animation
function animate(lastTime, redCar, blueRectangle, runAnimation, canvas, ctx) {
if(runAnimation.value) {
// update
var time = (new Date()).getTime();
var timeDiff = time - lastTime;
// pixels / second
var redSpeed = Math.floor((Math.random() * 400) + 1);
var blueSpeed = Math.floor((Math.random() * 400) + 1);
var linearDistEachFrameRed = redSpeed * timeDiff / 1000;
var linearDistEachFrameBlue = blueSpeed * timeDiff / 1000;
var currentX = redRectangle.x;
var currentZ = blueRectangle.x;
if(currentX < canvas.width - redRectangle.width - redRectangle.borderWidth / 2) {
var newX = currentX + linearDistEachFrameRed;
redRectangle.x = newX;
}
if(currentZ < canvas.width - blueRectangle.width - blueRectangle.borderWidth / 2) {
var newZ = currentZ + linearDistEachFrameBlue;
blueRectangle.x = newZ;
}
console.log(redSpeed);
console.log(blueSpeed);
// clear
ctx.clearRect(0, 0, canvas.width, canvas.height);
// draw
drawFinishLine(ctx);
drawRedRect(redRectangle, ctx);
drawBlueRect(blueRectangle, ctx);
//winner(win);
// request new frame
requestAnimFrame(function() {
animate(time, redRectangle, blueRectangle, runAnimation, canvas, ctx);
});
}
}
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
var win = document.getElementById('Winner')
//blue square
var blueRectangle = {
x: 5, y: 30, width: 45, height: 25, borderWidth:5
};
//red square
var redRectangle = {
x: 5,
y: 90,
width: 45,
height: 25,
borderWidth: 5
};
/!*
* define the runAnimation boolean as an obect
* so that it can be modified by reference
*!/
var runAnimation = {
value: false
};
// add click listener to canvas
document.getElementById('myCanvas').addEventListener('click', function() {
// flip flag
runAnimation.value = !runAnimation.value;
if(runAnimation.value) {
var date = new Date();
var time = date.getTime();
animate(time, redRectangle, blueRectangle, runAnimation, canvas, ctx);
}
});
drawFinishLine(ctx);
drawRedRect(redRectangle, ctx);
drawBlueRect(blueRectangle, ctx);
//winner(win);
Here is some of your code refactored to race car images:
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
// game vars
var redRectangle={x:5,y:40,width:62,height:21};
var goldRectangle={x:5,y:75,width:62,height:21};
var finishX=450;
// animation vars
var nextTime=0;
var delay=1000/60;
// image vars and call start() when all images are loaded
var red=new Image();
red.onload=start;
red.src='https://dl.dropboxusercontent.com/u/139992952/multple/car1.png';
var gold=new Image();
gold.onload=start;
gold.src='https://dl.dropboxusercontent.com/u/139992952/multple/car2.png';
var imageCount=2;
function start(){
// return if all the images aren't loaded
if(--imageCount>0){return;}
// start the animation loop
requestAnimationFrame(animate);
}
function animate(time){
// has the desired time elapsed?
if(time<nextTime){requestAnimationFrame(animate);return;}
nextTime=time+delay;
// update the car positions
redRectangle.x+=Math.random()*5;
goldRectangle.x+=Math.random()*5;
// draw the current scene
ctx.clearRect(0,0,canvas.width,canvas.height);
drawFinishLine(ctx);
drawRedRect(redRectangle, ctx);
drawgoldRect(goldRectangle, ctx);
// request another animation loop
hasRedWon=redRectangle.x+redRectangle.width>finishX;
hasGoldWon=goldRectangle.x+goldRectangle.width>finishX;
// alert if race is over
if(hasRedWon){ alert('Red wins'); return; }
if(hasGoldWon){ alert('Gold wins'); return; }
// race is still going, request another animation loop
requestAnimationFrame(animate);
}
// draw images instead of rects
function drawRedRect(redRectangle, ctx){
ctx.drawImage(red, redRectangle.x, redRectangle.y, redRectangle.width, redRectangle.height);
}
// draw images instead of rects
function drawgoldRect(goldRectangle, ctx){
ctx.drawImage(gold, goldRectangle.x, goldRectangle.y, goldRectangle.width, goldRectangle.height);
}
// draw finish line
function drawFinishLine(){
ctx.fillRect(finishX,0,5,ch);
}
body{ background-color: ivory; }
#canvas{border:1px solid red; }
<canvas id="canvas" width=500 height=300></canvas>

Unable to put one canvas under another

I want to put a canvas under another. I am pretty new at javascript so i apologize in advance if the following code looks a bit messy. I want to make the canvas called "myCanvas" appear behind "coinAnimation". All responses are extremely appreciated.
HTML
<div id="wrapper">
<canvas id="coinAnimation" height="500" width="500"></canvas>
<canvas id="myCanvas" height="500" width="600"></canvas>
</div>
Javascript
<script type="text/javascript">
(function () {
var coin,
coinImage,
canvas;
function gameLoop () {
window.requestAnimationFrame(gameLoop);
coin.update();
coin.render();
}
function sprite (options) {
var that = {},
frameIndex = 0,
tickCount = 0,
ticksPerFrame = options.ticksPerFrame || 0,
numberOfFrames = options.numberOfFrames || 1;
that.context = options.context;
that.width = options.width;
that.height = options.height;
that.image = options.image;
that.update = function () {
tickCount += 1;
if (tickCount > ticksPerFrame) {
tickCount = 0;
// If the current frame index is in range
if (frameIndex < numberOfFrames - 1) {
// Go to the next frame
frameIndex += 1;
} else {
frameIndex = 0;
}
}
};
that.render = function () {
// Clear the canvas
that.context.clearRect(0, 0, that.width, that.height);
// Draw the animation
that.context.drawImage(
that.image,
frameIndex * that.width / numberOfFrames,
-110,
that.width / numberOfFrames,
that.height,
0,
0,
that.width / numberOfFrames,
that.height);
};
return that;
}
// Get canvas
canvas = document.getElementById("coinAnimation");
canvas.width = 600;
canvas.height = 300;
// Create sprite sheet
coinImage = new Image();
// Create sprite
coin = sprite({
context: canvas.getContext("2d"),
width: 1000,
height: 300,
image: coinImage,
numberOfFrames: 10,
ticksPerFrame: 7
});
// Load sprite sheet
coinImage.addEventListener("load", gameLoop);
coinImage.src = "images/test2.png";
} ());
</script>
<script type="text/javascript">
window.addEventListener('load', function () {
var
img = new Image,
ctx = document.getElementById('myCanvas').getContext('2d');
img.src = "images/back.png";
img.addEventListener('load', function () {
var interval = setInterval(function() {
var x = 0, y = 0;
return function () {
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
ctx.drawImage(img, x, y);
x += -1;
if (x > ctx.canvas.width) {
x = 0;
}
};
}(), 1000/40);
}, false);
}, false);
</script>
See here: jsfilddle.net. I added the background colors to demonstrate positioning and z-index.
First, make the wrapper div position relative. This is the position that the container divs will be based off. Then make the container divs absolute positioned to (0,0). Then, set the z-index so that myCanvas is behind coinAnimation.
CSS:
#wrapper
{
position:relative;
}
#coinAnimation
{
background-color:blue;
position:absolute;
z-index:1;
}
#myCanvas
{
background-color:red;
position:absolute;
top:0px;
left:0px;
z-index:0;
}
HTML:
<div id="wrapper">
<canvas id="coinAnimation" height="500" width="500"></canvas>
<canvas id="myCanvas" height="500" width="600"></canvas>
</div>

jQuery Make image rotating interval decrease smoothly

here is my site:
I'm trying to get the CD to slowly stop spinning or slowly start up again when I click a button or press the spacebar, but setTimeout() hasn't worked for me.
Thanks.
Below is the js in my body.
var diskCenter = [480, 480];
var disk = new Image;
disk.src = 'disk.jpg';
window.onload = function () {
var ang = 0;
var c = document.getElementsByTagName('canvas')[0];
var ctx = c.getContext('2d');
setInterval(function () {
ctx.save();
ctx.clearRect(0, 0, c.width, c.height);
ctx.translate(c.width, 0);
ctx.rotate(Math.PI / 180 * (ang += 5));
ctx.drawImage(disk, -diskCenter[0], -diskCenter[1]);
ctx.restore();
}, 25);
};
Here's the code I used to get it to work (I have two buttons, one that slows down the animation (and reverses it) and one that speeds it up:
(function ($) {
var ang = 0;
var speed = 5;
var minSpeed = -10;
var maxSpeed = 10;
var c = $('#discCanvas')[0];
var ctx = c.getContext('2d');
var diskCenter = [480, 480];
var disk = new Image;
disk.src = 'http://swellgarfo.com/9/disk.jpg';
$(function () {
setInterval(function () {
ctx.save();
ctx.clearRect(0, 0, c.width, c.height);
ctx.translate(c.width, 0);
ctx.rotate(Math.PI / 180 * (ang += speed));
ctx.drawImage(disk, -diskCenter[0], -diskCenter[1]);
ctx.restore();
}, 25);
});
$('#slowButton').on('click', function () {
speed = Math.max(minSpeed, speed - 1);
});
$('#fastButton').on('click', function () {
speed = Math.min(maxSpeed, speed + 1);
});
})(jQuery);
You will have to use clearInterval() function for stopping your CD. Since you have rotated the CD using setInterval().
Here you go.
HTML :
Include a link :
Stop
Javascript : I am using Jquery here.
So include :
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
var my = setInterval(function(){
ctx.save();
ctx.clearRect( 0 , 0, c.width, c.height );
ctx.translate( c.width , 0 );
ctx.rotate(Math.PI / 180 * (ang += 5));
ctx.drawImage( disk, -diskCenter[0], -diskCenter[1] );
ctx.restore();
},25);
$(document).ready(function(){
$("#stop").click(function(e){
e.preventDefault();
window.clearInterval(my);
});
});
I believe it will make sense.

Categories