I have a function that clears all drawings off of the background image in canvas when a button is clicked, but when you go to draw again, the old (previously cleared drawings) reappears. How can I make a hard delete so that I can draw again without reloading the page
'use strict';
function initCanvas() {
let bMouseIsDown = false;
let canvas = document.getElementById('cvs');
let ctx = canvas.getContext('2d');
let convert = document.getElementById('convert');
let sel = 'png';
let imgs = document.getElementById('imgs');
let imgW = 300;
let imgH = 200;
let background = new Image();
background.crossOrigin = '';
background.src = "http://i.imgur.com/yf6d9SX.jpg";
background.onload = function(){
ctx.drawImage(background,0,0,600,400);
}
bind(canvas,ctx,convert,sel,imgs,imgW,imgH,bMouseIsDown);
};
initCanvas()
function bind (canvas,ctx,convert,sel,imgs,imgW,imgH,bMouseIsDown) {
let iLastX = 0;
let iLastY = 0;
let iX;
let iY;
canvas.onmousedown = function(e) {
bMouseIsDown = true;
iLastX = e.clientX - canvas.offsetLeft + (window.pageXOffset||document.body.scrollLeft||document.documentElement.scrollLeft);
iLastY = e.clientY - canvas.offsetTop + (window.pageYOffset||document.body.scrollTop||document.documentElement.scrollTop);
}
canvas.onmouseup = function() {
bMouseIsDown = false;
iLastX = -1;
iLastY = -1;
}
canvas.onmousemove = function(e) {
if (bMouseIsDown) {
iX = e.clientX - canvas.offsetLeft + (window.pageXOffset||document.body.scrollLeft||document.documentElement.scrollLeft);
iY = e.clientY - canvas.offsetTop + (window.pageYOffset||document.body.scrollTop||document.documentElement.scrollTop);
ctx.moveTo(iLastX, iLastY);
ctx.lineTo(iX, iY);
ctx.stroke();
ctx.strokeStyle = "blue";
ctx.lineJoin = "round";
ctx.lineWidth = 5;
iLastX = iX;
iLastY = iY;
}
};
document.getElementById('clear').addEventListener('click', function() {
rerenderImg();
});
function rerenderImg() {
iY = [];
iX=[];
initCanvas()
}
};
You need to call ctx.beginPath(); before drawing on the canvas again.
The logical place to put this is just before your call to ctx.moveTo.
An explanation of why this is needed is given here.
You should actually run clearRect on the canvas:
ctx.clearRect(0, 0, canvas.width, canvas.height);
I'm trying to create background for every created particle.
Canvas pattern is not working properly. I'm getting this error >> "SyntaxError: An invalid or illegal string was specified"
HTML
<canvas id="canvas"></canvas>
JS
(function(){
window.onload = function(){
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d'),
particles = {},
particleIndex = 0,
particleNum = 1;
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
ctx.fillStyle = '#000';
ctx.fillRect(0, 0, canvas.width, canvas.width);
function Particle(){
this.x = canvas.width / 2;
this.y = 0;
this.vx = Math.random() * 10 - 5;
this.vy = Math.random() * 10 - 5;
this.gravity = 0.2;
particleIndex++;
particles[particleIndex] = this;
this.id = particleIndex;
this.test = 0;
this.maxLife = 100;
}
Particle.prototype.draw = function(){
this.x += this.vx;
this.y += this.vy;
this.vy += this.gravity;
this.test++;
if ( this.test >= this.maxLife ) {
delete particles[this.id];
};
var img = new Image();
img.src = 'img/aaa.png';
var pattern = ctx.createPattern(img,'repeat');
ctx.fillStyle = pattern;
ctx.fillRect(this.x, this.y, 20, 20);
};
setInterval(function(){
ctx.fillStyle = "#000";
ctx.fillRect(0, 0, canvas.width, canvas.height);
for (var i = 0; i < particleNum; i++) {
new Particle();
};
for(var i in particles) {
particles[i].draw();
}
},30)
}})();
I was trying to do this also with ctx.drawImage(), but picture was displayed one time only.
Any tips?:)
Fiddle
I think the issue is the image being loaded later than its used.
Inside your draw() you have:
var img = new Image();
img.src = 'img/aaa.png';
var pattern = ctx.createPattern(img,20,20);
It is a bad idea to create new images everytime you want to draw. I strongly suggest you create the img variable outside of the draw loop. Once you set the .src of an image, you have to wait until it is loaded to use it. There is an onload event you can use to let you know when its ready.
Here is an example:
var imgLoaded = false;
var img = new Image();
img.src = 'img/aaa.png';
img.onload = function() { imgLoaded = true; };
function draw() {
...
if (imgLoaded) {
var pattern = ctx.createPattern(img, 'repeat');
...
}
...
}
I'm trying to create a hover effect for a canvas image when a mousemove over the image, a transparent overlay shows up. Once a user mouseout am trying to restore the canvas back to it initial stage by making use of the Canvas restore method but it keeps failing. Below is the whole code
var images = [];
var halfCircle;
var ctx;
var canvas;
var effect = true;
jQuery(document).ready(function() {
canvas = document.getElementById("myCanvas");
canvas.style.backgroundColor = '#fafafa';
ctx = canvas.getContext("2d");
halfCircle = new HalfCircle();
halfCircle.doArch(ctx);
placeImages(ctx);
addEventListenersToCanvas(canvas, ctx);
});
function placeImages(ctx){
first_image = new Image();
first_image.src = 'http://example.com/media/features/0.png';
first_image.onload = function(){
ctx.drawImage(first_image, 20, 20);
images.push({x:20,y:20,link: "http://example.com/shoppinglist-infographic", img : first_image});
ctx.save();
}
second_image = new Image();
second_image.src = "http://example.com/media/features/1.png";
second_image.onload = function(){
ctx.drawImage(second_image, 130, 150);
images.push({x:130,y:150,link: "http://example.com/referral/invite?g=banner", img : second_image});
ctx.save();
}
third_image = new Image();
third_image.src = "http://example.com/media/features/2.png";
third_image.onload = function(){
ctx.drawImage(third_image, 230, 220);
images.push({x:230,y:220,link: "http://example.com/all-fast-delivery/", img : third_image});
ctx.save();
}
fourth_image = new Image();
fourth_image.src = "http://example.com/media/features/3.png";
fourth_image.onload = function(){
ctx.drawImage(fourth_image,460, 220);
images.push({x:460,y:220,link:"http://example.com/busyhomemaker/", img : fourth_image});
ctx.save();
}
fifth_image = new Image();
fifth_image.src = "http://example.com/media/features/4.png";
fifth_image.onload = function(){
ctx.drawImage(fifth_image,570, 150);
images.push({x:570,y:150,link:"#", img: fifth_image});
ctx.save();
}
sixth_image = new Image();
sixth_image.src = "http://example.com/media/features/5.png";
sixth_image.onload = function(){
ctx.drawImage(sixth_image,620, 20);
images.push({x:620,y:20,link:"#", img:sixth_image});
ctx.save();
}
text_image = new Image();
text_image.src = "http://example.com/media/features/text.png";
text_image.onload = function(){
ctx.drawImage(text_image,285, 20);
ctx.save();
}
}
function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect();
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}
function addEventListenersToCanvas(canvas, ctx){
ctx.save();
canvas.addEventListener('mousemove', function(evt) {
var mousePos = getMousePos(canvas, evt);
for(var i = 0; i < images.length; i++){
if( (mousePos.x > images[i].x) && (mousePos.x < (images[i].x + images[i].img.width)) &&
(mousePos.y > images[i].y) && (mousePos.y < (images[i].y + images[i].img.height))
){
document.body.style.cursor = "pointer";
if(effect) {
ctx.fillStyle = "#fafafa";
ctx.globalAlpha = 0.1;
ctx.fillRect(images[i].x, images[i].y, images[i].img.width, images[i].img.height);
effect = false;
}
}else{
document.body.style.cursor = "auto";
ctx.restore();
effect = true;
}
}
});
//
canvas.addEventListener('click', function(event){
var mousePos = getMousePos(canvas, event);
for(var i = 0; i < images.length; i++){
if(
(mousePos.x > images[i].x) && (mousePos.x < images[i].x + images[i].img.width) &&
(mousePos.y > images[i].y) && (mousePos.y < images[i].y + images[i].img.height)
){
// console.log('clicking on: ' + images[i].link);
window.open(images[i].link);
}
}
});
}
var HalfCircle = function(){
this.numOfArch = 6;
this.posX = 438;
this.posY = 20;
this.rad = 170;
this.color = [
{ start_color: 'rgb(255,182,54)', end_color: 'rgb(255,220,159)' },
{ start_color: 'rgb(240,97,38)', end_color: 'rgb(249,166,57)' },
{ start_color: 'rgb(254,107,108)', end_color: 'rgb(250,74,78)' },
{ start_color: 'rgb(0,131,195)', end_color: 'rgb(0,150,219)' },
{ start_color: 'rgb(115,174,14)', end_color: 'rgb(214,243,137)' },
{ start_color: 'rgb(133,29,250)', end_color: 'rgb(203,159, 255)' },
];
this.lineWidth = 5;
};
HalfCircle.prototype = {
smallDot: function (posX, posY, ctx, colr){
ctx.beginPath();
ctx.fillStyle = colr;
ctx.arc(posX, posY, 7, 0, Math.PI*2, false);
ctx.fill();
ctx.closePath();
},
bigDot : function (posX, posY, ctx, colr){
ctx.beginPath();
ctx.fillStyle = colr;
ctx.arc(posX, posY, 10, 0, Math.PI*2, false);
ctx.fill();
ctx.closePath();
},
getEndCord: function(startCord){
return startCord + Math.PI/this.numOfArch;
},
doArch : function (ctx){
var startCord = 0;
for( i = 0; i < this.numOfArch; i++ ){
dotStartX = this.rad * Math.cos(startCord) + this.posX;
dotStartY = this.rad * Math.sin(startCord) + this.posY;
this.smallDot(dotStartX, dotStartY, ctx , this.color[i].start_color);
ctx.lineWidth = this.lineWidth;
ctx.beginPath();
ctx.strokeStyle = this.color[i].start_color;
var endCord = this.getEndCord(startCord);
ctx.arc(this.posX, this.posY, this.rad, startCord, endCord , false);
ctx.stroke();
ctx.closePath();
startCord = endCord;
dotStartX = this.rad * Math.cos(endCord) + this.posX;
dotStartY = this.rad * Math.sin(endCord) + this.posY;
this.bigDot(dotStartX, dotStartY, ctx , this.color[i].end_color);
}
}
}
Am seriously would need someone input on these. Thanks
context.save only saves the context state (stylings, transformations, etc). It does not save anything you have drawn on the canvas. So context.restore will only restore the context state, not the drawings.
To remove something you have previously drawn on the canvas, you must clear the entire canvas and redraw everything that you do want on the 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;
function reOffset(){
var BB=canvas.getBoundingClientRect();
offsetX=BB.left;
offsetY=BB.top;
}
var offsetX,offsetY;
reOffset();
window.onscroll=function(e){ reOffset(); }
window.onresize=function(e){ reOffset(); }
//
var halfCircle;
var effect = true;
var overlayIndex=-1;
//
var images = [];
images.push({x:20,y:20, link: "http://example.com/shoppinglist-infographic"});
images.push({x:130,y:150,link: "http://example.com/referral/invite?g=banner"});
images.push({x:230,y:220,link: "http://example.com/all-fast-delivery/"});
images.push({x:460,y:220,link:"http://example.com/busyhomemaker/"});
images.push({x:570,y:150,link:"#"});
images.push({x:620,y:20, link:"#"});
images.push({x:285,y:20, link:"#"});
// Define HalfCircle
var HalfCircle = function(){
this.numOfArch = 6;
this.posX = 438;
this.posY = 20;
this.rad = 170;
this.color = [
{ start_color: 'rgb(255,182,54)', end_color: 'rgb(255,220,159)' },
{ start_color: 'rgb(240,97,38)', end_color: 'rgb(249,166,57)' },
{ start_color: 'rgb(254,107,108)', end_color: 'rgb(250,74,78)' },
{ start_color: 'rgb(0,131,195)', end_color: 'rgb(0,150,219)' },
{ start_color: 'rgb(115,174,14)', end_color: 'rgb(214,243,137)' },
{ start_color: 'rgb(133,29,250)', end_color: 'rgb(203,159, 255)' },
];
this.lineWidth = 5;
};
//
HalfCircle.prototype = {
smallDot: function (posX, posY, ctx, colr){
ctx.beginPath();
ctx.fillStyle = colr;
ctx.arc(posX, posY, 7, 0, Math.PI*2, false);
ctx.fill();
ctx.closePath();
},
bigDot : function (posX, posY, ctx, colr){
ctx.beginPath();
ctx.fillStyle = colr;
ctx.arc(posX, posY, 10, 0, Math.PI*2, false);
ctx.fill();
ctx.closePath();
},
getEndCord: function(startCord){
return startCord + Math.PI/this.numOfArch;
},
doArch : function (ctx){
var startCord = 0;
for( i = 0; i < this.numOfArch; i++ ){
dotStartX = this.rad * Math.cos(startCord) + this.posX;
dotStartY = this.rad * Math.sin(startCord) + this.posY;
this.smallDot(dotStartX, dotStartY, ctx , this.color[i].start_color);
ctx.lineWidth = this.lineWidth;
ctx.beginPath();
ctx.strokeStyle = this.color[i].start_color;
var endCord = this.getEndCord(startCord);
ctx.arc(this.posX, this.posY, this.rad, startCord, endCord , false);
ctx.stroke();
ctx.closePath();
startCord = endCord;
dotStartX = this.rad * Math.cos(endCord) + this.posX;
dotStartY = this.rad * Math.sin(endCord) + this.posY;
this.bigDot(dotStartX, dotStartY, ctx , this.color[i].end_color);
}
}
}
// preload all images
// put the paths to your images in imageURLs[]
var imageURLs=[];
imageURLs.push('http://example.com/media/features/0.png');
imageURLs.push('http://example.com/media/features/1.png');
imageURLs.push('http://example.com/media/features/2.png');
imageURLs.push('http://example.com/media/features/3.png');
imageURLs.push('http://example.com/media/features/4.png');
imageURLs.push('http://example.com/media/features/5.png');
imageURLs.push('http://example.com/media/features/text.png');
//
// the loaded images will be placed in imgs[]
var imgs=[];
var imagesOK=0;
startLoadingAllImages(imagesAreNowLoaded);
//
// Create a new Image() for each item in imageURLs[]
// When all images are loaded, run the callback (==imagesAreNowLoaded)
function startLoadingAllImages(callback){
// iterate through the imageURLs array and create new images for each
for (var i=0; i<imageURLs.length; i++) {
// create a new image an push it into the imgs[] array
var img = new Image();
imgs.push(img);
// when this image loads, call this img.onload
img.onload = function(){
// this img loaded, increment the image counter
imagesOK++;
// if we've loaded all images, call the callback
if (imagesOK>=imageURLs.length ) {
callback();
}
};
// notify if there's an error
img.onerror=function(){alert("image load failed");}
// set img properties
img.src = imageURLs[i];
}
}
//
function imagesAreNowLoaded(){
// the imgs[] array now holds fully loaded images
// the imgs[] are in the same order as imageURLs[]
halfCircle = new HalfCircle();
draw();
$("#canvas").mousemove(function(e){handleMouseMove(e);});
}
function draw(){
ctx.fillStyle='#fafafa';
ctx.fillRect(0,0,cw,ch);
halfCircle.doArch(ctx);
for(var i=0;i<imgs.length;i++){
ctx.drawImage(imgs[i], images[i].x,images[i].y);
if(i==overlayIndex){
ctx.fillStyle = "#fafafa";
ctx.globalAlpha = 0.35;
ctx.fillRect( images[i].x, images[i].y, imgs[i].width, imgs[i].height);
ctx.globalAlpha = 1.00;
}
}
}
function handleMouseMove(e){
// tell the browser we're handling this event
e.preventDefault();
e.stopPropagation();
mx=parseInt(e.clientX-offsetX);
my=parseInt(e.clientY-offsetY);
//
overlayIndex=-1;
for(var i=0;i<images.length;i++){
var img=images[i];
var image=imgs[i];
if(
mx>img.x && mx<img.x+image.width &&
my>img.y && my<img.y+image.height
){
overlayIndex=i;
}
}
draw();
}
body{ background-color: ivory; }
#canvas{border:1px solid red; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<canvas id="canvas" width=900 height=500></canvas>
hope it will helps you..
<!doctype html>
<html>
<head>
<meta charset="UTF-8" />
<title>Canvas Test</title>
</head>
<body>
<header> </header>
<nav> </nav>
<section>
<div>
<canvas id="canvas" width="320" height="200">
This text is displayed if your browser does not support HTML5 Canvas.
</canvas>
</div>
<script type="text/javascript">
var canvas;
var ctx;
function init() {
canvas = document.getElementById("canvas");
ctx = canvas.getContext("2d");
draw();
}
function draw() {
ctx.fillStyle = '#FA6900';
ctx.shadowOffsetX = 5;
ctx.shadowOffsetY = 5;
ctx.shadowBlur = 4;
ctx.shadowColor = 'rgba(204, 204, 204, 0.5)';
ctx.fillRect(0,0,15,150);
ctx.save();
ctx.fillStyle = '#E0E4CD';
ctx.shadowOffsetX = 10;
ctx.shadowOffsetY = 10;
ctx.shadowBlur = 4;
ctx.shadowColor = 'rgba(204, 204, 204, 0.5)';
ctx.fillRect(30,0,30,150);
ctx.save();
ctx.fillStyle = '#A7DBD7';
ctx.shadowOffsetX = 15;
ctx.shadowOffsetY = 15;
ctx.shadowBlur = 4;
ctx.shadowColor = 'rgba(204, 204, 204, 0.5)';
ctx.fillRect(90,0,45,150);
ctx.save();
ctx.restore();
ctx.beginPath();
ctx.arc(185, 75, 22, 0, Math.PI*2, true);
ctx.closePath();
ctx.fill();
ctx.restore();
ctx.beginPath();
ctx.arc(260, 75, 15, 0, Math.PI*2, true);
ctx.closePath();
ctx.fill();
ctx.restore();
ctx.beginPath();
ctx.arc(305, 75, 8, 0, Math.PI*2, true);
ctx.closePath();
ctx.fill();
}
init();
</script>
</section>
<aside> </aside>
<footer> </footer>
</body>
</html>
Why doesn't the updatePosition read the fall function in Square? Its suppose to be drawing a block falling from the top, but nothing is happening. Can't seem to wrap my head around the problem. It has something to do with invoking a function call within another.
var WIDTH = 300,
HEIGHT = 400,
c = document.getElementById('canvas'),
ctx = c.getContext('2d');
setInterval(function () {
clearCanvas();
updatePosition();
drawOnCanvas();
}, 1000 / 50);
var clearCanvas = function () {
ctx.fillStyle = 'White';
ctx.beginPath();
ctx.rect(0, 0, WIDTH, HEIGHT);
ctx.closePath();
ctx.fill();
}
var drawLine = function () {
ctx.beginPath();
ctx.moveTo(200, 0);
ctx.lineTo(200, 400);
ctx.stroke();
}
var updatePosition = function () {
Square.fall();
}
var drawOnCanvas = function () {
drawLine();
Square.draw();
}
var speedLevels = [20, 16, 12, 10, 8],
currSpeed = speedLevels[0];
var Square = function (speed) {
var self = this;
self.color = "Black";
self.vPosition = 0;
self.hPosition = 4;
self.speed = speed;
self.temp = 0;
self.fall = function () {
if (self.temp == self.speed) {
self.vPosition++;
self.temp = 0;
}
self.temp++;
}
self.draw = function () {
console.log(self.vPosition * squareLength);
ctx.fillStyle = self.color;
ctx.fillRect(self.hPosition * squareLength, self.vPosition * squareLength, squareLength, squareLength);
}
return self;
}
Firstly, you're calling Square.fall() and Square.draw() as if Square were an instance of an object - it's not, because you haven't done Square = new ... anywhere.
Secondly, you're using a variable squareLength which isn't defined anywhere.
var _Square = function(speed) {
var self = this;
self.color = "Black";
self.vPosition = 0;
self.hPosition = 4;
self.speed = speed;
self.temp = 0;
squareLength = 1;
self.fall = function() {
if (self.temp == self.speed) {
self.vPosition++;
self.temp = 0;
}
self.temp++;
}
self.draw = function() {
console.log(self.vPosition * squareLength);
ctx.fillStyle = self.color;
ctx.fillRect(self.hPosition * squareLength, self.vPosition * squareLength, squareLength, squareLength);
}
return self;
}
var WIDTH = 300,
HEIGHT = 400,
c = document.getElementById('canvas'),
ctx = c.getContext('2d');
var Square = new _Square(10);
setInterval(function() {
clearCanvas();
updatePosition();
drawOnCanvas();
}, 1000 / 50);
var clearCanvas = function() {
ctx.fillStyle = 'White';
ctx.beginPath();
ctx.rect(0, 0, WIDTH, HEIGHT);
ctx.closePath();
ctx.fill();
}
var drawLine = function() {
ctx.beginPath();
ctx.moveTo(200, 0);
ctx.lineTo(200, 400);
ctx.stroke();
}
var updatePosition = function() {
Square.fall();
}
var drawOnCanvas = function() {
drawLine();
Square.draw();
}
var speedLevels = [20, 16, 12, 10, 8],
currSpeed = speedLevels[0];
canvas {
border: 1px solid red;
width: 300px;
height: 400px;
}
<canvas id='canvas'></canvas>