It seems like a very simple problem and i must just be overlooking something but with this code:
window.onresize = function(){
init.canvas.width = window.innerWidth;
init.canvas.height = window.innerHeight;
}
var init = {
canvas: new Object(),
ctx: new Object(),
constructCanvas: function(){
this.canvas = document.getElementById("canvas");
this.ctx = this.canvas.getContext("2d");
this.canvas.width = window.innerWidth;
this.canvas.height = window.innerHeight;
}
}
init.constructCanvas();
var a = 20;
var b = 20;
init.ctx.lineWidth = 4;
function loop(){
init.ctx.fillStyle = "Blue";
init.ctx.fillRect(0,0,init.canvas.width,init.canvas.height);
init.ctx.moveTo(a,b);
init.ctx.lineTo(a+=9,b);
init.ctx.stroke();
}
setInterval(loop,100);
What should be happening is I get little line segments of length 9 then when the next call happens that one should clear and another line segment should be placed down at the end of the previous one but what happens instead is I just get one long line and the fillRect call seems to do nothing.
This is one of the many Canvas problems that happen if you don't use beginPath():
The canvas does get cleared properly. However you never clear the path, so you always redraw the whole line, not just the section you want. By calling moveTo and lineTo you are merely adding the next section to the already created Path, that is then drawn on stroke. You need to begin a new path instead:
function loop(){
init.ctx.fillStyle = "Blue";
init.ctx.fillRect(0,0,init.canvas.width,init.canvas.height);
init.ctx.beginPath():
init.ctx.moveTo(a,b);
init.ctx.lineTo(a+=9,b);
init.ctx.stroke();
}
Related
I attempted to animate a sprite sheet using html and javascript to no avail. Here is my sprite sheet
Below is lines 36-59 of my code. I'm not getting any errors so I don't really know what's wrong. How do I fix/improve my code?
This is for a project I'm doing. I've tried using different methods I've found online but none really worked either. I've tried shifting the image as well.
<html>
<head>
<title>Tree Animation</title>
</head>
<body>
<canvas id='canvas'></canvas>
<script>
var canWidth = 400;
var canHeight = 100;
//position where the frame will be drawn
var x = 0;
var y = 0;
var srcX;
var srcY;
var sheetWidth = 230;
var sheetHeight = 79;
var frameCount = 5;
var width = sheetWidth/frameCount;
var height;
var currentFrame = 0;
var tree = new Image();
tree.src = "tree sprite.jpg"
var canvas = document.getElementById('canvas');
canvas.width = canWidth;
canvas.height = canHeight;
var ctx = canvas.getContext('2d');
function updateFrame(){
currentFrame = ++currentFrame%frameCount
srcX = currentFrame*width;
srcY = 0;
ctx.clearRect(x, y, width, height);
}
function draw(){
updateFrame();
}
setInterval(function(){
draw();
}, 100);
</script>
</body>
</html>
I expect the output to be an animation of a tree growing, but instead I'm getting a blank page.
you should provide more code or a snippet, there are several variables didn't show up in your code
and it's hard to debug your code if u use setInterval, you should make sure your code can work first.
maybe you can try step by step:
draw the whole img on the canvas first. if it works, go next
invoke your draw() function manually, check if the img drawed
invoke more, such assetTimout(draw, 1000), check the result
ok, and i think you can console.log these variables in draw
Im new to using canvas but wonder if i could get some help or advice on where to start with this. i currently have a circle drawn on canvas and have tried multiple ways i thought might work but cant get my head round it. When searching online i can only really find help where the shapes are drawn in canvas itself.
Here is what i have so far: JSFiddle
JavaScript:
var one = document.getElementById("canvOne");
var canvOne = one.getContext("2d");
var img = new Image();
img.onload = function(){
canvOne.drawImage(img, 10, 10);
};
img.src = "img/circle.jpg";
function oneStart(){
for(var i = 0; i < 300; i++){
img.style.left = i + 'px';
setTimeout(oneStart, 1000);
}
};
can anyone give me a hand with this please?
jsFiddle : http://jsfiddle.net/8eLL7L5L/3/
javascript
//canvas one
var one = document.getElementById("canvOne");
var canvOne = one.getContext("2d");
var img = new Image();
var animate = false;
var circlePosX = 10;
var circlePosY = 10;
img.onload = function () {
canvOne.drawImage(img, circlePosX, circlePosY);
};
img.src = "http://www.alexvolley.co.uk/other/circle.jpg";
var start = function()
{
animate = true;
}
var stop = function()
{
animate = false;
}
setInterval(function () {
// Only update circle position if animate is true
if (animate) {
circlePosX += 1;
canvOne.fillStyle = "#FFF";
canvOne.fillRect(0, 0, one.width, one.height);
canvOne.drawImage(img, circlePosX, circlePosY);
}
}, 3);
All I have done is created 3 variables and added a few little functions, the circle's XPos and YPos are now stored so we can access them, I have also created a bool variable animate which is used to check if we should animate the circle.
The start function simply sets animate to true
The stop function simple sets animate to false
the setInterval just keeps running the same code over and over every 3 miliseconds, all this does is clears the canvas and then redraws the circle. If we don't clear the canvas you would see multiple circles appear when animate is true.
I hope this helped
I am writing some basic code using the prototypal pattern. I am trying to draw an image to canvas but it is not working. I have debugged the code within Chrome and it is because the image.onload is not firing. I don't believe the image is being loaded.
Here are the two functions that control this.
var SimpleGame = function () {
self = this; //Reference to this function
//Canvas
this.canvas = document.createElement("canvas");
this.ctx = this.canvas.getContext("2d");
this.canvas.width = 251;
this.canvas.height = 217;
//Default objects
this.bgReady = false;
this.bgImage = new Image();
};
var simpleProto = SimpleGame.prototype; //Cache the prototype
//Draw the objects on the canvas
simpleProto.draw = function() {
//Draw/ Render the canvas
document.body.appendChild(self.canvas);
//Draw the background
self.bgImage.onload = function() {
self.bgReady = true;
};
self.bgImage.src = "images/background.png";
if(self.bgReady) {
self.ctx.drawImage(self.bgImage, 10, 10);
};
}
Any idea why?
Your if(self.bgReady) is being tested before the image has a chance to load.
So naturally it will be false and drawImage will not be executed.
Fix:
Put self.ctx.drawImage in self.bgImage.onload
Good luck with your project!
I am making a game and in it I would like to have the ability to use cached canvas's instead of rotating the image every frame. I think I made a function for adding images that makes sense to me, but I am getting an error every frame that tells me that the canvas object is no longer available.
INVALID_STATE_ERR: DOM Exception 11: An attempt was made to use an
object that is not, or is no longer, usable.
You might also need to know that I am using object.set(); to go ahead and add that image to a renderArray. That may be affecting whether the canvas object is still avaliable?
Here is the function that returns a cached canvas, (I took it from a post on this website :D)
rotateAndCache = function(image, angle){
var offscreenCanvas = document.createElement('canvas');
var offscreenCtx = offscreenCanvas.getContext('2d');
var size = Math.max(image.width, image.height);
offscreenCanvas.width = size;
offscreenCanvas.height = size;
offscreenCtx.translate(size/2, size/2);
offscreenCtx.rotate(angle + Math.PI/2);
offscreenCtx.drawImage(image, -(image.width/2), -(image.height/2));
return offscreenCanvas;
}
And here is some more marked up code:
var game = {
render:function(){
//gets called every frame
context.clearRect(0, 0, canvas.width, canvas.height);
for(i = 0; i < game.renderArray.length; i++){
switch(game.renderArray[i].type){
case "image":
context.save();
context.translate(game.renderArray[i].x, game.renderArray[i].y);
context.rotate(Math.PI*game.renderArray[i].rotation/180);
context.translate(-game.renderArray[i].x, -game.renderArray[i].y);
context.drawImage(game.renderArray[i].image, game.renderArray[i].x, game.renderArray[i].y);
context.restore();
break;
}
if(game.renderArray[i].remove == true){
game.renderArray.splice(i,1);
if(i > 1){
i--;
}else{
break;
}
}
}
},
size:function(width, height){
canvas.height = height;
canvas.width = width;
return height + "," + width;
},
renderArray:new Array(),
//initialize the renderArray
image:function(src, angle){
if(angle != undefined){
//if the argument 'angle' was given
this.tmp = new Image();
this.tmp.src = src;
//sets 'this.image' (peach.image) to the canvas. It then should get rendered in the next frame, but apparently it doesn't work...
this.image = rotateAndCache(this.tmp, angle);
}else{
this.image = new Image();
this.image.src = src;
}
this.x = 0;
this.y = 0;
this.rotation = 0;
this.destroy = function(){
this.remove = true;
return "destroyed";
};
this.remove = false;
this.type = "image";
this.set = function(){
game.renderArray.push(this);
}
}
};
var canvas, context, peach;
$(document).ready(function(){
canvas = document.getElementById("canvas");
context = canvas.getContext("2d");
//make the variable peach a new game.image with src of meme.jpg and an angle of 20.
peach = new game.image('meme.jpg', 20);
peach.set();
game.size(700,500);
animLoop();
});
If you want, here is this project hosted on my site:
http://keirp.com/zap
There are no errors on your page, at least not anymore or not that I can see.
It's quite possible that the problem is an image that is not done loading. For instance that error will happen if you try to make a canvas pattern out of a not-yet-finished-loading image. Use something like pxloader or your own image loading function to make sure all the images are complete before you start drawing.
Anyway, it's nigh impossible to figure out what was or is happening since your code isn't actually giving any errors (anymore).
I'm experimenting with the canvas element, but for some reason it doesn't display my image.
I use the following code:
function Canvas() {
this.field = function() {
var battlefield = document.getElementById('battlefield');
var canvas = battlefield.getElementsByTagName('canvas')[0];
return canvas.getContext('2d');
}
}
function Draw(canvas) {
if (!canvas) {
alert('There is no canvas available (yet)!');
return false;
}
this.canvas = canvas;
this.grass = function(pos_x, pos_y) {
var terrain = new Terrain();
var specs = terrain.grass();
var img = new Image();
img.onload = function(){
canvas.drawImage(img, specs.position_x, specs.position_y, specs.dimension_x, specs.dimension_y, pos_x, pos_y, specs.dimension_x, specs.dimension_y);
console.log('success???'); // this is being output
};
img.src = '/img/terrain.png';
}
}
(function() {
var canvas = new Canvas();
var draw = new Draw(canvas.field());
draw.grass();
})();
There are no errors, but the image just doesn't display. I've verified if the image exists and it does. I also verified the specs and they do contain what they should:
dimension_x: 25
dimension_y: 25
position_x: 0
position_y: 0
Any idea what I'm doing wrong?
http://jsfiddle.net/uwkfD/3/
pos_x and pos_y are undefined in your code. It works if you pass values for them to draw.grass():
draw.grass(0, 0);
DEMO
Tested in Chrome and Firefox.
This may be because you need a context to draw on.
Try:
this.context = canvas.getContext('2d')
Then call your draw functions on the context object not the canvas object:
this.context.drawImage(img, specs.position_x, specs.position_y, specs.dimension_x, specs.dimension_y, pos_x, pos_y, specs.dimension_x, specs.dimension_y);
It also appears that your reference to canvas is wrong too, it should be this.canvas (or this.context) not just canvas, at least as I understand scope in javascript.