A HTML5 canvas ERROR - javascript

I'am trying to write a puzzle game in canvas,so i need to give each part of puzzle block a background image.
but always a error "Uncaught TypeError: Cannot read property 'drawImage' of undefined "
any help will be appreciated!
(function(){
function Block(image, l, t, w, h){
this.image = image;
this.left = l;
this.top = t;
this.width = w;
this.height = h;
}
Block.prototype.draw = function(context){
context.drawImage(this.image, this.left, this.top, this.width, this.height, this.left, this.top, this.width, this.height);
}
window.Block = Block;
})();
var el = document.getElementById("puzzle_area");
var ctx = el.getContext("2d");
var image = new Image();
image.src = "background0.jpg";
image.onload = init;
var width = 100;
var height = width;
function init(){
for(var i = 0; i < 16; i++){
var x = (i % 4) * width;
var y = parseInt(i / 4) * height;
var block = new Block(image, x, y, width, height);
block.draw(ctx);
}
}

Your draw() function requires a context parameter which you're not passing to it when you're calling it from within your Block() function/object. Add a context parameter to that and use it when calling "this.draw()".

I haven't tested it, but here is what I changed your code to:
(function(){
function Block(context, image, l, t, w, h){
this.image = image;
this.left = l;
this.top = t;
this.width = w;
this.height = h;
this.context = context;
this.draw();
}
Block.prototype.draw = function(){
this.context.drawImage(this.image, -this.left, -this.top, this.width, this.height, this.left, this.top);
}
window.Block = Block;
})();
var el = document.getElementById("puzzle_area");
var ctx = el.getContext("2d");
var image = new Image();
image.src = "background0.jpg";
image.onload = init;
var block = null;
var width = 100;
var height = width;
function init(){
for(var i = 0; i < 9; i++){
var x = (i % 400) * width;
var y = parseInt(i / 400) * height;
block = new Block(ctx, image, x, y, width, height);
// block is drawn automatically, no need to draw it again
// block.draw();
}
}

Related

How to curve image in differnt shape, just like 'm'

I want to give curve to image just as shirt collar.
Curve image
I have image.Main image
I use below code
<script type="text/javascript">
function allcurve(event){
topcolrcurve(event);
}
function topcolrcurve(event){
var getImagePath = URL.createObjectURL(event.target.files[0]);
console.log(getImagePath)
temp_can1 = document.getElementById('f6258182013');
temp_can1_ctx = temp_can1.getContext('2d');
topcolrrotator(getImagePath, '-100');
}
function topcolrrotator(var2, var3)
{
var mr_rotator_var = document.getElementById('colrtop_can');
var mr_rotator_var_ctx = mr_rotator_var.getContext("2d");
mr_rotator_var.width = mr_rotator_var.width;
var imageObj_rotator3 = new Image();
var hpp='';
imageObj_rotator3.onload = function () {
var pattern_rotator3 = mr_rotator_var_ctx.createPattern(imageObj_rotator3, "repeat");
mr_rotator_var_ctx.fillStyle = pattern_rotator3;
mr_rotator_var_ctx.rect(0, 0, mr_rotator_var.width, mr_rotator_var.height);
mr_rotator_var_ctx.rotate(var3 * Math.PI / 180);
mr_rotator_var_ctx.fill();
hpp = mr_rotator_var.toDataURL('image/png');
rightcufover(hpp);
};
imageObj_rotator3.src = var2;
}
function rightcufover(event)
{
var getImagePath = event;
var ctx = e.getContext("2d");
var img = new Image;
img.onload = slice;
img.src = getImagePath;
function slice() {
var w = e.width = this.width;
var h = e.height = this.height;
var step = Math.PI * 1 / w;
var scale = -100;
for(var x = 0; x < w; x++) {
ctx.drawImage(this,
x, 0, 1, h,
x, Math.sin(step*x)*scale, 1, h);
}
var hp=e.toDataURL('image/png');
$('#collrtop').attr("value", hp);
}
}
Please help how to curve image.
I try it in different way but it not show proper, also I have to maintain quality of image.

Canvas rotation - fixed background, moving foreground

Goal
The stripes in the background remain fixed while the cones rotate about the center.
Current State
live demo:
https://codepen.io/WallyNally/pen/yamGYB
/*
The loop function is around line 79.
Uncomment it to start the animation.
*/
var c = document.getElementById('canv');
var ctx = c.getContext('2d');
var W = c.width = window.innerWidth;
var H = c.height = window.innerHeight;
var Line = function() {
this.ctx = ctx;
this.startX = 0;
this.startY = 0;
this.endX = 0;
this.endY = 0;
this.direction = 0;
this.color = 'blue';
this.draw = function() {
this.ctx.beginPath();
this.ctx.lineWidth = .1;
this.ctx.strokeStlye = this.color;
this.ctx.moveTo(this.startX, this.startY);
this.ctx.lineTo(this.endX, this.endY);
this.ctx.closePath();
this.ctx.stroke();
}
this.update = function() {
//for fun
if (this.direction == 1) {
this.ctx.translate(W/2, H/2);
this.ctx.rotate(-Math.PI/(180));
}
}//this.update()
}//Line();
objects=[];
function initLines() {
for (var i =0; i < 200; i++) {
var line = new Line();
line.direction = (i % 2);
if (line.direction == 0) {
line.startX = 0;
line.startY = -H + i * H/100;
line.endX = W + line.startX;
line.endY = H + line.startY;
}
if (line.direction == 1) {
line.startX = 0;
line.startY = H - i * H/100;
line.endX = W - line.startX;
line.endY = H - line.startY;
}
objects.push(line);
line.draw();
}
}
initLines();
function render(c) {
c.clearRect(0, 0, W, H);
for (var i = 0; i < objects.length; i++)
{
objects[i].update();
objects[i].draw();
}
}
function loop() {
render(ctx);
window.requestAnimationFrame(loop);
}
//loop();
What I have tried
The translate(W/2, H/2) should place the context at the center of the page, then this.ctx.rotate(-Math.PI/(180)) should rotate it one degree at a time. This is the part that is not working.
Using save()and restore() is the proper way to keep some parts of an animation static while others move. I placed the save and restore in different parts of the code to no avail. There are one of two types of result : Either a new entirely static image is produced, or some erratic animation happens (in the same vein of where it is now).
Here is the changed pen: http://codepen.io/samcarlinone/pen/LRwqNg
You needed a couple of changes:
var c = document.getElementById('canv');
var ctx = c.getContext('2d');
var W = c.width = window.innerWidth;
var H = c.height = window.innerHeight;
var angle = 0;
var Line = function() {
this.ctx = ctx;
this.startX = 0;
this.startY = 0;
this.endX = 0;
this.endY = 0;
this.direction = 0;
this.color = 'blue';
this.draw = function() {
this.ctx.beginPath();
this.ctx.lineWidth = .1;
this.ctx.strokeStlye = this.color;
this.ctx.moveTo(this.startX, this.startY);
this.ctx.lineTo(this.endX, this.endY);
this.ctx.closePath();
this.ctx.stroke();
}
this.update = function() {
//for fun
if (this.direction == 1) {
this.ctx.translate(W/2, H/2);
this.ctx.rotate(angle);
this.ctx.translate(-W/2, -H/2);
}
}//this.update()
}//Line();
objects=[];
function initLines() {
for (var i =0; i < 200; i++) {
var line = new Line();
line.direction = (i % 2);
if (line.direction == 0) {
line.startX = 0;
line.startY = -H + i * H/100;
line.endX = W + line.startX;
line.endY = H + line.startY;
}
if (line.direction == 1) {
line.startX = 0;
line.startY = H - i * H/100;
line.endX = W - line.startX;
line.endY = H - line.startY;
}
objects.push(line);
line.draw();
}
}
initLines();
function render(c) {
c.clearRect(0, 0, W, H);
for (var i = 0; i < objects.length; i++)
{
ctx.save();
objects[i].update();
objects[i].draw();
ctx.restore();
}
}
function loop() {
render(ctx);
window.requestAnimationFrame(loop);
angle += Math.PI/360;
}
loop();
First I added a variable to keep track of rotation and increment it in the loop
Second I save and restore for each individual line, alternatively if all lines were going to perform the same transformation you could move that code before and after the drawing loop
Third to get the desired affect I translate so the center point is in the middle of the screen, then I rotate so that the lines are rotated, then I translate back because all the lines have coordinates on the interval [0, H]. Instead of translating back before drawing another option would be to use coordinates on the interval [-(H/2), (H/2)] etc.

How do I get this HTML canvas animation to appear on top of my image?

new to stack and coding, trying to create a simplified detective game (definitely have bitten off more than I can chew, but I decided to give it a shot anyway).
Here's a codepen link to the code:
http://codepen.io/anon/pen/ZbZREp
*************** HTML *************************
None
************** CSS ***************************
body{
background:#000;
width: 100%;
height: 100%;
overflow:hidden;
}
****************JS ****************************
var canvas = document.createElement('canvas');
var w = canvas.width = 800,
h = canvas.height = 600;
var c = canvas.getContext('2d');
var img = new Image();
img.src = 'http://oi41.tinypic.com/4i2aso.jpg';
var background = new Image();
background.src = "https://i2.wp.com/i2.listal.com/image/2669447/500full.jpg";
var position = {x : w/3.2, y : h/2.5};
document.body.appendChild(canvas);
var particles = [];
var random = function(min, max){
return Math.random()*(max-min)*min;
};
/*canvas.onmousemove = function(e){
position.x = e.offsetX;
position.y = e.offsetY;
};*/
function Particle(x, y){
this.x = x;
this.y = y;
this.velY = -2;
this.velX = (random(1, 10)-5)/10;
this.size = random(3, 5)/10;
this.alpha = 1;
this.update = function(){
c.drawImage(background,0,0);
this.y += this.velY;
this.x += this.velX;
this.velY *= 0.99;
if(this.alpha < 0)
this.alpha = 0;
c.globalAlpha = this.alpha;
c.save();
c.translate(this.x, this.y);
c.scale(this.size, this.size);
c.drawImage(img, -img.width/2, -img.height/2);
c.restore();
this.alpha *= 0.96;
this.size += 0.02;//
};
}
var draw = function(){
var p = new Particle(position.x, position.y);
particles.push(p);
while(particles.length > 500) particles.shift();
c.globalAlpha = 2;
c.drawImage(background,0,0);
c.fillRect(0,0,w,h);
for(var i = 0; i < particles.length; i++)
{
particles[i].update();
}
};
setInterval(draw, 1000/60);
On codepen, if you comment out line 35 in the JS section, you'll see that there's a smoke animation BEHIND the detective's image (found it on codepen of course and thought it would make for a cool smoking animation). I was able to figure out how to get the detective image into the canvas, but I can't figure out how to get the smoke animation to appear in FRONT of detective's image. I've tried several methods including setting a Javascript picture onLoad, but out of all the methods, this is the closest I could get to my intended goal.
What am I doing wrong here?
Just draw the background image before you draw the particles:
var canvas = document.createElement('canvas');
var w = canvas.width = 800,
h = canvas.height = 600;
var c = canvas.getContext('2d');
var img = new Image();
img.src = 'http://oi41.tinypic.com/4i2aso.jpg';
var background = new Image();
background.src = "https://i2.wp.com/i2.listal.com/image/2669447/500full.jpg";
var position = {x : w/3.2, y : h/2.5};
document.body.appendChild(canvas);
var particles = [];
var random = function(min, max){
return Math.random()*(max-min)*min;
};
/*canvas.onmousemove = function(e){
position.x = e.offsetX;
position.y = e.offsetY;
};*/
function Particle(x, y){
this.x = x;
this.y = y;
this.velY = -2;
this.velX = (random(1, 10)-5)/10;
this.size = random(3, 5)/10;
this.alpha = 1;
this.update = function(){
//c.drawImage(background,0,0);
this.y += this.velY;
this.x += this.velX;
this.velY *= 0.99;
if(this.alpha < 0){this.alpha = 0;}
c.globalAlpha = this.alpha;
c.save();
c.translate(this.x, this.y);
c.scale(this.size, this.size);
c.drawImage(img, -img.width/2, -img.height/2);
c.restore();
this.alpha *= 0.96;
this.size += 0.02;//
};
}
var draw = function(){
var p = new Particle(position.x, position.y);
particles.push(p);
// draw the background image before you draw the particles
c.drawImage(background,0,0);
while(particles.length > 500) particles.shift();
for(var i = 0; i < particles.length; i++)
{
particles[i].update();
}
};
setInterval(draw, 1000/60);
body{ background-color: black; }
canvas{border:1px solid red; }

Instantiating object in a function gives "Uncaught TypeError: undefined is not a function"

I tried to look most of the suggested search results concerning the error message I receive, but unfortunately none is talking about a case that is similar to mine. So I believe this is not a duplicate.
(In particular I don't use jQuery, I don't want to use it. Besides, the accepted answer given is correct and it does not involve jQuery, it elaborates the understanding of hoisting in JavaScript.)
I wonder Why the code below (2nd code snippet) does not work? I can't figure that out.
This code works. I instantiate Cell objects outside the drawGrid function.
'use strict';
var dim = 20;
var side_length = 25;
var canvas = document.getElementById('world');
canvas.width = 500;
canvas.height = 500;
document.body.appendChild(canvas);
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
drawGrid(ctx);
}
var Cell = function(x, y, alive, context) {
this.x = x;
this.y = y;
this.alive = alive;
this.ctx = context;
};
Cell.prototype.draw = function() {
if (this.alive === true) {
this.ctx.beginPath();
this.ctx.arc(this.x + side_length / 2, this.y + side_length / 2, 10, 0, 2 * Math.PI);
this.ctx.fill();
}
};
for (var i = 0; i < dim; i++) {
for (var j = 0; j < dim; j++) {
var x = i * canvas.width / dim,
y = j * canvas.height / dim;
new Cell(x, y, true, ctx).draw();
}
}
function drawGrid(ctx) {
for (var i = 0; i < dim; i++) {
for (var j = 0; j < dim; j++) {
var x = i * canvas.width / dim,
y = j * canvas.height / dim;
ctx.strokeRect(x, y, side_length, side_length);
}
}
}
<canvas id='world'></canvas>
This code does not work. I instantiate the Cell objects inside the drawGrid function.
'use strict';
var dim = 20;
var side_length = 25;
var canvas = document.getElementById('world');
canvas.width = 500;
canvas.height = 500;
document.body.appendChild(canvas);
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
drawGrid(ctx);
}
var Cell = function(x, y, alive, context) {
this.x = x;
this.y = y;
this.alive = alive;
this.ctx = context;
};
Cell.prototype.draw = function() {
if (this.alive === true) {
this.ctx.beginPath();
this.ctx.arc(this.x + side_length / 2, this.y + side_length / 2, 10, 0, 2 * Math.PI);
this.ctx.fill();
}
};
function drawGrid(ctx) {
for (var i = 0; i < dim; i++) {
for (var j = 0; j < dim; j++) {
var x = i * canvas.width / dim,
y = j * canvas.height / dim;
ctx.strokeRect(x, y, side_length, side_length);
new Cell(x, y, true, ctx).draw();
}
}
}
<canvas id='world'></canvas>
The problem is here:
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
drawGrid(ctx);
}
var Cell = function(x, y, alive, context) {
You're assigning Cell after you call drawGrid. So, inside drawGrid, Cell is undefined.
Simple fix 1, use a standard function declaration to have the assignment hoisted along the variable declaration :
function Cell(x, y, alive, context) {
Simple (more readable) fix 2: just move the call to drawGrid at the end.

Loading Images from a Canvas

I'm trying to make a game in HTML5 and I'm having trouble loading image assets. My issue is that the onload event of the code isn't firing and so the boolean isn't changing.
var c = document.getElementById("gamearea");
var gs = c.getContext("2d");
var one_x = 0;
//Sprite Loading//
function sprite(src,x, y, width, height, frames, levels) {
this.sprite = Image();
this.sprite.src = src;
this.x = x;
this.y = y;
this.w = width;
this.h = height;
this.f = frames;
this.l = levels;
this.cf = 0;
this.cl = 0;
this.loaded = false;
this.src = src;
}
sprite.prototype.draw = function () {
if (this.loaded) {
document.getElementById("ass").innerHTML = "Ass";
gs.drawImage(this.src, this.x, this.y);
}
}
dog = new sprite("/images/sDog.png", 10, 10, 10, 10, 1, 1);
dog.sprite.onload = function () {
alex.loaded = true;
}
setInterval(alex.draw, 30);
I would suggest putting the onload event before the set event for your dog sprite image object. I see that you set everything in the constructor, but I would suggest against that.
In you current code you object is being loaded before the line that initializes the onload event.
I have seen this a lot with loading images, I would do something like this.
function sprite(src,x, y, width, height, frames, levels) {
var self = this;
self.sprite = new Image();
self.init = function(){
self.sprite.src = src;
self.x = x;
self.y = y;
self.w = width;
self.h = height;
self.f = frames;
self.l = levels;
self.cf = 0;
self.cl = 0;
self.loaded = false;
self.src = src;
}
}
dog = new sprite();
dog.sprite.onload = function () {
alex.loaded = true;
}
dog.init("/images/sDog.png", 10, 10, 10, 10, 1, 1);
setInterval(alex.draw, 30);
or, to get a little fancier
function sprite(src,x, y, width, height, frames, levels, onLoad) {
var self = this;
self.sprite = new Image();
self.sprite.onload = function(){
onLoad();
}
self.sprite.src = src;
self.x = x;
self.y = y;
self.w = width;
self.h = height;
self.f = frames;
self.l = levels;
self.cf = 0;
self.cl = 0;
self.loaded = false;
self.src = src;
}
dog = new Sprite("/images/sDog.png", 10, 10, 10, 10, 1, 1, function(){
alex.loaded = true;
});
setInterval(alex.draw, 30);
after looking at your fiddle
var c = document.getElementById("gamearea");
var gs = c.getContext("2d");
var one_x = 0;
//Sprite Loading//
function sprite(src, x, y, width, height, frames, levels, loaded) {
var self = this;
self.sprite = new Image();
self.sprite.onload = function(){
self.loaded = true;
}
self.sprite.src = src;
self.x = x;
self.y = y;
self.w = width;
self.h = height;
self.f = frames;
self.l = levels;
self.cf = 0;
self.cl = 0;
self.loaded = false;
self.src = src;
self.update = function () {
one_x += 1;
gs.fillStyle = "white";
gs.fillRect(0, 0, 1000, 10000);
gs.fillStyle = "black";
gs.fillRect(one_x, 20, 10, 10);
}
self.draw = function (){
if (self.loaded) {
document.getElementById("ass").innerHTML = "Ass";
gs.drawImage(self.sprite, self.x, self.y);
}
}
}
dog = new sprite("http://www.bit-101.com/blog/wp-content/uploads/2009/05/ball.png", 10, 10, 10, 10, 1, 1);
setInterval(dog.draw, 30);
You're missing new here:
this.sprite = Image();
Try:
this.sprite = new Image();
Also make sure that the image file actually exists in the given location.

Categories

Resources