Im pretty new to the canvas element in HTML5.
What i want to do is move an image from the right hand side of the screen to the left, once it reaches the left i want it to begin again from the right hand side. I only want it to do this maybe 2/3 times and then stop.
I tried to add in a for loop so that it would limit the iterations but this was unsuccessful.
Any help at all would be appreciated.
Heres my code:
<canvas id="myCanvas" width="600" height="400"></canvas>
<script>
window.addEventListener('load', function () {
var
img = new Image,
ctx = document.getElementById('myCanvas').getContext('2d');
img.src = 'pies.png';
img.addEventListener('load', function () {
var interval = setInterval(function() {
var x = 650, y = 194;
return function () {
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
ctx.drawImage(img, x, y);
x -= 1;
if (x < -500) {
x = 650;
}
};
}(), 1000/40);
}, false);
}, false);
</script>
One way is to specify a maximum number of leftward moves:
// allow leftward moves = 2 1/2 time the canvas width
// (plus an allowance for the image width)
var maxMoves = (canvas.width+image.width) *2.5;
Then just countdown maxMoves until zero. At zero, stop your animation:
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
ctx.fillStyle='skyblue';
var currentX=cw;
var delay=16; // 16ms between moves
var continueAnimating=true;
var nextMoveTime,maxMoves;
var img=new Image();
img.onload=start;
img.src="https://dl.dropboxusercontent.com/u/139992952/multple/sun.png";
function start(){
maxMoves=(cw+img.width)*2.5;
nextMoveTime=performance.now();
requestAnimationFrame(animate);
}
function animate(currentTime){
if(continueAnimating){ requestAnimationFrame(animate); }
if(currentTime<nextMoveTime){return;}
nextMoveTime=currentTime+delay;
ctx.fillRect(0,0,cw,ch);
ctx.drawImage(img,currentX,50);
if(--currentX<-img.width){ currentX=cw; }
if(--maxMoves<0){continueAnimating=false;}
}
body{ background-color: ivory; padding:10px; }
#canvas{border:1px solid red;}
<p>Stop animating after 2 1/2 "sunrises"</p>
<canvas id="canvas" width=300 height=300></canvas>
Related
I have a HTML canvas in Ionic app.
<canvas id="canvas" color="{{ color }}" width="800" height="600" style="position:relative;"></canvas>
In this canvas, I am loading an image. Below is the code from controller
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
var img = new Image();
img.src = $stateParams.imageId;
img.onload = function() {
context.drawImage(img, 0, 0, canvas.width, canvas.height);
}
After the image is loaded, users need the ability to write on the image and circle/highlight certain areas of the image.
Doesn't HTML canvas provide this feature by default? Right now I am not able to annotate anything on the image. How can I achieve this?
You need to implement this yourself.
You can do it by hooking into the mouse click / move events. using your 2d context, draw small rectangle at the mouse's current position if the most moves and the left mouse button is down.
The effect is similar to a Windows paint pencil tool. Here's a simple example.
<html>
<head>
<style>
canvas{
border: 1px solid black;
}
</style>
</head>
<body>
<canvas id="myCanvas"></canvas>
<script>
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var isMouseDown = false;
canvas.onmousedown = function(e){
isMouseDown = true;
}
canvas.onmouseup = function(e){
isMouseDown = false;
}
canvas.onmousemove = function(e){
if(isMouseDown === false){
return;
}
var canvasPosition = canvas.getBoundingClientRect();
var x = e.clientX - canvasPosition.left;
var y = e.clientY - canvasPosition.top;
ctx.fillRect(x, y, 2, 2);
};
</script>
</body>
</html>
I am trying to create flip card effect using html canvas by drawing it in the canvas.
no ccs3 tricks needed. It should be done in a native manner;
this is my initial test using phaser.js by changing the scale
<html>
<head>
</head>
<body>
<div id="game_canvas">
</div>
<script src = "jquery.min.js"></script>
<script src = "phaser.min.js"></script>
<script>
var game;
var sprite;
$(document).ready(function(){
game = new Phaser.Game(640, 480, Phaser.AUTO, 'game_canvas', {
preload : preload,
create : create,
update : update
});
function preload () {
game.load.image('card','download.png');
}
function create() {
this.delay = 1000;
this.spawn = 0;
sprite = game.add.sprite(game.width/4, game.height/4, 'card');
}
function update() {
console.log(this.spawn > game.time.now);
if (this.spawn > game.time.now) {
return;
}
this.spawn = game.time.now + this.delay;
sprite.scale.x *= -1;
}
});
</script>
</body>
</html>
and what i want to attain is like this using the canvas
http://www.turnjs.com/#samples/steve-jobs/10
anyone has any idea on how to do it would be a great help
thanks in advance
here is the current demo
http://sopronioli713.github.io/test/
Here's a canvas based card flip (with rotation) that I did a while back for fun.
It works by scaling in just the X direction so that the card appears to be flipping.
Notes about the effect:
You can omit the rotations if they are not required.
This effect translates to the horizontal center of the card before scaling (flipping) which makes the card "spin". If you instead want a "dealers flip" then you would instead translate to the edge of the card.
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
var x=150;
var y=150;
var scaleX=100;
var angle=0;
var scaleDirection=-1;
var scaleDelta=1;
var PI2=Math.PI*2;
var backCanvas=document.createElement('canvas');
var backCtx=backCanvas.getContext('2d');
var imgCount=2;
var front=new Image();front.onload=start;front.src="https://dl.dropboxusercontent.com/u/139992952/multple/kingcard.png";
var back=new Image();back.onload=start;back.src="https://dl.dropboxusercontent.com/u/139992952/multple/kingcardback.png";
function start(){
if(--imgCount>0){return;}
animate();
}
function draw(x,y,scaleX,angle){
ctx.clearRect(0,0,cw,ch);
ctx.translate(x,y);
ctx.rotate(angle);
ctx.scale(scaleX,1);
if(scaleX>=0){
ctx.drawImage(front,-front.width/2,-front.height/2);
}else{
ctx.drawImage(back,-back.width/2,-back.height/2);
}
ctx.setTransform(1,0,0,1,0,0);
}
function animate(time){
draw(x,y,scaleX/100,angle);
angle+=PI2/720;
scaleX+=scaleDirection*scaleDelta;
if(scaleX<-100 || scaleX>100){
scaleDirection*=-1;
scaleX+=scaleDirection*scaleDelta;
}
requestAnimationFrame(animate);
}
body{ background-color: ivory; }
#canvas{border:1px solid red;}
<canvas id="canvas" width=300 height=300></canvas>
On the other hand...
You link to a page-turning demo--which is a totally different animal. If that's what your after Rick Barraza has done a nice writeup on how to do that here: http://rbarraza.com/html5-canvas-pageflip/
This question already has answers here:
Html5 canvas drawImage: how to apply antialiasing
(6 answers)
Closed 8 years ago.
I have a problem with Html5 canvas
i draw an image but its quality becomes very poor
after i draw it with canvas it becomes this
my code is here
<script type="text/javascript">
$canvasWidth = $('#canvas').width;
$canvasHeight = $('#canvas').height;
var alpha = 0.0;
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
function draw(){
var delta = 0.05;
ctx.clearRect(0,0,$canvasWidth, $canvasHeight);
ctx.globalAlpha = alpha;
var logo= new Image();
WandioLight.onload = function(){
ctx.drawImage(logo, 0, 0, 250, 167);
};
logo.src = "logo.png";
alpha += delta;
if(alpha > 1.0){
return false;
}
setTimeout(draw, 50);
}
You can incrementally scale your image down for better results.
Since your final size is 1/4 the original size, you could:
scale the 1000x669 image in half to 500x334 onto a temp canvas
scale the 500x335 canvas in half to 250x167 onto the main canvas
Here's example code and a Demo:
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
var img=new Image();
img.onload=start;
img.src="https://ictcluster.ge/wp-content/uploads/2018/09/wandio-logo-1-1024x724.png";
function start(){
// scale the 1000x669 image in half to 500x334 onto a temp canvas
var c1=scaleIt(img,0.50);
// scale the 500x335 canvas in half to 250x167 onto the main canvas
canvas.width=c1.width/2;
canvas.height=c1.height/2;
ctx.drawImage(c1,0,0,250,167);
}
function scaleIt(source,scaleFactor){
var c=document.createElement('canvas');
var ctx=c.getContext('2d');
var w=source.width*scaleFactor;
var h=source.height*scaleFactor;
c.width=w;
c.height=h;
ctx.drawImage(source,0,0,w,h);
return(c);
}
body{ background-color: ivory; padding:10px; }
canvas{border:1px solid red;}
<canvas id="canvas" width=300 height=300></canvas>
I wish to be able to move some images say 5/6 across the canvas. The position of the image will obviously change each time, simulating basic animation. The images will be on a timer/ delay so that they move every second or so. Is there a function that i can create so that i dont have to repeat the same code over and over again for the images. Also it would be good if the images were preloaded but im unsure on how to manipulate the image once it has been preloaded.
If there was also a way of using requestAnimationFrame instead of setTimeout then that would be even better.
Heres my current code:
window.addEventListener("load", eventWindowLoaded, false);
function eventWindowLoaded () {
images = new Array();
images[0] = "images/1.png";
images[1] = "images/2.png";
images[2] = "images/3.png";
images[3] = "images/4.png";
images[4] = "images/5.png";
imageObjs = [];
for(var i = 0; i <= 4; i++){
var imageObj = new Image();
imageObj.src = images[i];
imageObjs.push(imageObj);
}
drawFrame();
}
function drawFrame () {
setTimeout(function() {
image = new Image();
image.onload = function() {
ctx.drawImage(imageObjs[0], 0, 0);
}
image.src = "images/1.png";
}, 200);
setTimeout(function () {
image2 = new Image();
image2.onload = function() {
ctx.drawImage(imageObjs[1], 200, 0);
};
image2.src = "images/2.png";
}, 1000);
}
You expressed interest in having code do the following:
Preload all images.
Move images across the canvas.
Use an animation loop function so code is not repeated.
Use requestAnimationFrame instead of setTimeout for efficiency.
Here's example code and a Demo:
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
var images=[];
images.push({x:20,y:200,moveX:5,maxX:250,delay:100,nextTime:0,url:'https://dl.dropboxusercontent.com/u/139992952/multple/cars1.png'});
images.push({x:20,y:30,moveX:10,maxX:100,delay:500,nextTime:0,url:'https://dl.dropboxusercontent.com/u/139992952/multple/sun.png'});
var imageCount=images.length;
for(var n=0;n<images.length;n++){
var i=images[n];
i.img=new Image();
i.img.onload=start;
i.img.src=i.url;
}
function start(){
if(--imageCount>0){return;}
requestAnimationFrame(animate);
}
function animate(time){
requestAnimationFrame(animate);
var needsRedrawing=false;
for(var n=0;n<images.length;n++){
var i=images[n];
if(time>i.nextTime){
if(i.x+i.moveX<i.maxX){
i.x+=i.moveX;
i.nextTime+=i.delay;
needsRedrawing=true;
}
}
}
if(needsRedrawing){
ctx.clearRect(0,0,cw,ch);
for(var n=0;n<images.length;n++){
var i=images[n];
ctx.drawImage(i.img,i.x,i.y);
}
}
}
body{ background-color: ivory; padding:10px; }
#canvas{border:1px solid red;}
<canvas id="canvas" width=300 height=300></canvas>
I have a quite simple loop that draws an 8px by 8px image many times in a canvas in a tiling fashion. Currently it's drawing 7500 images each loop.
See the jsfiddle.
var img = new Image();
img.src = 'http://i.imgur.com/3dzaMlv.png';
var W = 8;
var H = 8;
var R = 800/W;
var C = 600/H
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var fps = document.getElementById('fps');
var timePrev = new Date().getTime();
var fpsInterval = 30;
var i = 0;
window.setInterval(function() {
ctx.clearRect(0, 0, 800, 600);
for (var r=0 ; r<R ; r++) {
for (var c=0 ; c<C ; c++) {
ctx.drawImage(img, r*W, c*H);
}
}
// fps
if (i % fpsInterval == 0) {
var timeNow = new Date().getTime();
var spf = (timeNow - timePrev) / fpsInterval / 1000;
fps.innerHTML = (1/spf).toFixed(2);
timePrev = timeNow;
}
i++;
}, 1000/60);
On my I7-2700K (3.5GHz) processor and ATI Radeon HD7970, I am getting the following framerates:
Chrome 36.0.1985.143 m : ~40 FPS
Firefox 30.0 : ~55 FPS
IE 11.0.9600.17239 : ~35 FPS
Is there any way to improve FPS performance here, assuming I do actually need to draw this many tiles on each update?
EDIT: To clarify, I'm requiring that they be drawn as individual tiles on each update. So, rendering them all to an off-screen canvas wouldn't work. I am essentially disappointed in the number of drawImage() calls that seems to perform well.
Use requestAnimationFrame instead of setInterval, see http://www.w3.org/TR/animation-timing/. Your code may be rewritten like this: http://jsfiddle.net/fv99o6jc/
Here's one way to use far fewer drawImage's:
// make a template column
for(var y=0;y<ch;y+=ih){
ctx.drawImage(img,0,y);
}
// flood-fill with the template column
for(var x=iw;x<cw;x+=iw){
ctx.drawImage(canvas,0,0,iw,ch,x,0,iw,ch);
}
A Demo:
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
var img=new Image();
img.onload=start;
img.src="http://i.imgur.com/3dzaMlv.png";
function start(){
var iw=img.width;
var ih=img.height;
// make a template column
for(var y=0;y<ch;y+=ih){
ctx.drawImage(img,0,y);
}
// flood-fill with the template column
for(var x=iw;x<cw;x+=iw){
ctx.drawImage(canvas,0,0,iw,ch,x,0,iw,ch);
}
}
body{ background-color: ivory; padding:10px; }
#canvas{border:1px solid red;}
<canvas id="canvas" width=300 height=300></canvas>