Canvas deletes it's self after resizing HTML5/JavaScript [duplicate] - javascript

This question already has answers here:
HTML canvas - drawing disappear on resizing
(7 answers)
Closed 10 months ago.
I made canvas that you can draw on it. And it's also responsive to screen size. But if I resize the browser even with one pixel... Canvas clears it's self. Is there any way to prevent this? Fot the heads up, in my code you'll see code that prevents user from scrolling while he/she is on canvas(drawing). You'll also see code for mobile devices(to make possible for mobile users to draw on canvas). But "scroll prevent" isn't working on IOS devices for some reason.
#pen {
background-color: rgba(0, 0, 0, .2);
}
#paper {
display: grid;
column-count: 1;
}
#canvasORG {
width: 97.5vw;
height: 90vh;
cursor: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='40' height='48' viewport='0 0 100 100' style='fill:black;font-size:24px;'><text y='50%'>✍️</text></svg>") 5 27, auto;
}
#colors {
padding-top: 5px;
display: flex;
flex-wrap: wrap;
flex-direction: row;
}
#black {
width: 30px;
height: 30px;
background: black;
}
#black:hover {
background: rgba(0, 0, 0, .1);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="shortcut icon" type="image/icon" href="images/IYN_logo.png" />
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="styles.css">
<script src="script.js"></script>
</head>
<body>
<div id="paper">
<div id="canvasORG">
<canvas id="canvas" style="background-color: white; border:2px solid;"></canvas>
</div>
<div id="colors">
 
<div id="black" onclick="color(this)"></div>
 
<button id="pen" style="height: 50px; font-size: 25px; padding-bottom: 5px;">✍🏻</button>
</div>
</div>
<script>
const points = [];
const canvas = document.getElementById("canvas");
const mouse = { x: 0, y: 0, button: false }
const ctx = canvas.getContext("2d");
canvas.addEventListener("mousemove", mouseEvents);
canvas.addEventListener("mousedown", mouseEvents);
canvas.addEventListener("mouseup", mouseEvents);
var x = "black",
y = 5 * 4;
const canvasORG = document.getElementById("canvasORG");
(function () {
window.addEventListener("resize", resizeCanvas, false);
canvas.width = canvasORG.clientWidth;
canvas.height = canvasORG.clientHeight;
function resizeCanvas() {
canvas.width = canvasORG.clientWidth;
canvas.height = canvasORG.clientHeight;
//DRAW ALL
//ctx.fillStyle = 'white';
//ctx.fillRect(0, 0, canvas.width, canvas.height)
}
resizeCanvas();
})();
function mouseEvents(e) {
mouse.x = e.pageX - 1;
mouse.y = e.pageY - 1;
const lb = mouse.button;
mouse.button = e.type === "mousedown" ? true : e.type === "mouseup" ? false : mouse.button;
if (mouse.button) {
if (!lb) { points.length = 0 }
points.push({ x: mouse.x, y: mouse.y });
drawPoints();
}
}
function drawPoints() {
$(this).scrollTop(0);
ctx.strokeStyle = x;
ctx.lineWidth = y;
ctx.lineCap = "round";
ctx.lineJoin = "round";
ctx.beginPath();
if (mode == "pen") {
ctx.globalCompositeOperation = "source-over";
for (const p of points) { ctx.lineTo(p.x, p.y); }
ctx.stroke();
} else {
ctx.globalCompositeOperation = "destination-out";
ctx.arc(mouse.x, mouse.y, 8, 0, Math.PI * 2, false);
ctx.stroke();
ctx.fill();
}
}
function color(obj) {
switch (obj.id) {
case "black":
x = "black";
break;
}
}
canvas.addEventListener("touchstart", function (e) {
mousePos = getTouchPos(canvas, e);
var touch = e.touches[0];
var mouseEvent = new MouseEvent("mousedown", {
clientX: touch.clientX,
clientY: touch.clientY
});
canvas.dispatchEvent(mouseEvent);
}, false);
canvas.addEventListener("touchend", function (e) {
var mouseEvent = new MouseEvent("mouseup", {});
canvas.dispatchEvent(mouseEvent);
}, false);
canvas.addEventListener("touchmove", function (e) {
var touch = e.touches[0];
var mouseEvent = new MouseEvent("mousemove", {
clientX: touch.clientX,
clientY: touch.clientY
});
canvas.dispatchEvent(mouseEvent);
}, false);
// Get the position of a touch relative to the canvas
function getTouchPos(canvasDom, touchEvent) {
var rect = canvasDom.getBoundingClientRect();
return {
x: touchEvent.touches[0].clientX - rect.left,
y: touchEvent.touches[0].clientY - rect.top
};
}
document.getElementById("canvas").onwheel = function (event) {
event.preventDefault();
};
document.getElementById("canvas").onmousewheel = function (event) {
event.preventDefault();
};
canvas.addEventListener("touchstart", function (event) { event.preventDefault() })
canvas.addEventListener("touchmove", function (event) { event.preventDefault() })
canvas.addEventListener("touchend", function (event) { event.preventDefault() })
canvas.addEventListener("touchcancel", function (event) { event.preventDefault() })
var mode = "pen";
$("#pen").click(function () {
mode = "pen";
});
$("#eraser").click(function () {
mode = "eraser"
});
</script>
</body>
</html>

I would change the resize handler to redraw the image after the change:
const temp = ctx.getImageData(0, 0, canvas.width, canvas.height);
canvas.width = canvasORG.clientWidth;
canvas.height = canvasORG.clientHeight;
ctx.putImageData(temp, 0, 0);
The problem with this is that if the resize is smaller than the drawing, then the portion that is now off the canvas is destroyed.
#pen {
background-color: rgba(0, 0, 0, .2);
}
#paper {
display: grid;
column-count: 1;
}
#canvasORG {
width: 97.5vw;
height: 90vh;
cursor: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='40' height='48' viewport='0 0 100 100' style='fill:black;font-size:24px;'><text y='50%'>✍️</text></svg>") 5 27, auto;
}
#colors {
padding-top: 5px;
display: flex;
flex-wrap: wrap;
flex-direction: row;
}
#black {
width: 30px;
height: 30px;
background: black;
}
#black:hover {
background: rgba(0, 0, 0, .1);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="shortcut icon" type="image/icon" href="images/IYN_logo.png" />
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="styles.css">
<script src="script.js"></script>
</head>
<body>
<div id="paper">
<div id="canvasORG">
<canvas id="canvas" style="background-color: white; border:2px solid;"></canvas>
</div>
<div id="colors">
 
<div id="black" onclick="color(this)"></div>
 
<button id="pen" style="height: 50px; font-size: 25px; padding-bottom: 5px;">✍🏻</button>
</div>
</div>
<script>
const points = [];
const canvas = document.getElementById("canvas");
const mouse = { x: 0, y: 0, button: false }
const ctx = canvas.getContext("2d");
canvas.addEventListener("mousemove", mouseEvents);
canvas.addEventListener("mousedown", mouseEvents);
canvas.addEventListener("mouseup", mouseEvents);
var x = "black",
y = 5 * 4;
const canvasORG = document.getElementById("canvasORG");
(function () {
window.addEventListener("resize", resizeCanvas, false);
canvas.width = canvasORG.clientWidth;
canvas.height = canvasORG.clientHeight;
function resizeCanvas() {
const temp = ctx.getImageData(0, 0, canvas.width, canvas.height);
canvas.width = canvasORG.clientWidth;
canvas.height = canvasORG.clientHeight;
ctx.putImageData(temp, 0, 0);
}
resizeCanvas();
})();
function mouseEvents(e) {
mouse.x = e.pageX - 1;
mouse.y = e.pageY - 1;
const lb = mouse.button;
mouse.button = e.type === "mousedown" ? true : e.type === "mouseup" ? false : mouse.button;
if (mouse.button) {
if (!lb) { points.length = 0 }
points.push({ x: mouse.x, y: mouse.y });
drawPoints();
}
}
function drawPoints() {
$(this).scrollTop(0);
ctx.strokeStyle = x;
ctx.lineWidth = y;
ctx.lineCap = "round";
ctx.lineJoin = "round";
ctx.beginPath();
if (mode == "pen") {
ctx.globalCompositeOperation = "source-over";
for (const p of points) { ctx.lineTo(p.x, p.y); }
ctx.stroke();
} else {
ctx.globalCompositeOperation = "destination-out";
ctx.arc(mouse.x, mouse.y, 8, 0, Math.PI * 2, false);
ctx.stroke();
ctx.fill();
}
}
function color(obj) {
switch (obj.id) {
case "black":
x = "black";
break;
}
}
canvas.addEventListener("touchstart", function (e) {
mousePos = getTouchPos(canvas, e);
var touch = e.touches[0];
var mouseEvent = new MouseEvent("mousedown", {
clientX: touch.clientX,
clientY: touch.clientY
});
canvas.dispatchEvent(mouseEvent);
}, false);
canvas.addEventListener("touchend", function (e) {
var mouseEvent = new MouseEvent("mouseup", {});
canvas.dispatchEvent(mouseEvent);
}, false);
canvas.addEventListener("touchmove", function (e) {
var touch = e.touches[0];
var mouseEvent = new MouseEvent("mousemove", {
clientX: touch.clientX,
clientY: touch.clientY
});
canvas.dispatchEvent(mouseEvent);
}, false);
// Get the position of a touch relative to the canvas
function getTouchPos(canvasDom, touchEvent) {
var rect = canvasDom.getBoundingClientRect();
return {
x: touchEvent.touches[0].clientX - rect.left,
y: touchEvent.touches[0].clientY - rect.top
};
}
document.getElementById("canvas").onwheel = function (event) {
event.preventDefault();
};
document.getElementById("canvas").onmousewheel = function (event) {
event.preventDefault();
};
canvas.addEventListener("touchstart", function (event) { event.preventDefault() })
canvas.addEventListener("touchmove", function (event) { event.preventDefault() })
canvas.addEventListener("touchend", function (event) { event.preventDefault() })
canvas.addEventListener("touchcancel", function (event) { event.preventDefault() })
var mode = "pen";
$("#pen").click(function () {
mode = "pen";
});
$("#eraser").click(function () {
mode = "eraser"
});
</script>
</body>
</html>

Related

How to translate and make canvas responsive?

I am trying to move to translate the canvas to (100,100) but it is not moving.
And the canvas is not responsive, when I try to change the size of canvas using CSS the circles are shrinking.
How can I add a button to toggle the drawing on canvas by the circle (i.e.: when button pressed don't draw then the circle should not draw on canvas, when pressed draw it should draw)
requestAnimationFrame(animate);
var ctx = canvas1.getContext('2d');
ctx.translate(100,100);
canvas1.width = innerWidth;
canvas1.height = innerHeight;
const bgCan = copyCanvas(canvas1);
const redSize = 6, blueSize = 5; // circle sizes on pixels
const drawSpeed = 1; // when button down draw speed in pixels per frame
var X = 50, Y = 50;
var angle = 0;
var mouseButtonDown = false;
document.addEventListener('mousedown', () => mouseButtonDown = true);
document.addEventListener('mouseup', () => mouseButtonDown = false);
function copyCanvas(canvas) {
const can = Object.assign(document.createElement("canvas"), {
width: canvas.width, height: canvas.height
});
can.ctx = can.getContext("2d");
return can;
}
function circle(ctx){
ctx.fillStyle = 'black';
ctx.beginPath();
ctx.arc(X, Y, redSize, 0, Math.PI*2);
ctx.fill();
}
function direction(ctx){
const d = blueSize + redSize + 3;
ctx.fillStyle = 'blue';
ctx.beginPath();
ctx.arc(d * Math.sin(angle) + X, d * Math.cos(angle) + Y, blueSize, 0, Math.PI*2);
ctx.fill();
}
function animate(){
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
ctx.drawImage(bgCan, 0, 0);
if (mouseButtonDown) {
circle(bgCan.ctx);
X += Math.sin(angle) * drawSpeed;
Y += Math.cos(angle) * drawSpeed;
} else {
angle += 0.1;
circle(ctx);
}
direction(ctx);
requestAnimationFrame(animate);
}
#canvas1{
position: absolute;
top:0;
left: 0;
width: 100%;
height: 100%;
border-width: 1px;
border-style: solid;
border-color: Black;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Canvas basics</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<canvas id="canvas1"></canvas>
<input onclick="change()" type="button" value="Write" id="mybutton1"></input>
<script src="script.js"></script>
</body>
</html>
the translate(100, 100) gets reset by new width/height of the canvas. It just needs to be executed after width/height is set
The easiest way is to have a window resize listener and update canvas style width/height
I'm not sure why, but for some reason canvas has a higher z-index therefor button's onclick() never fired
In the code below I've added boundaries restriction, it's affected by translate(100, 100).
requestAnimationFrame(animate);
var ctx = canvas1.getContext('2d');
canvas1.width = innerWidth;
canvas1.height = innerHeight;
ctx.translate(100, 100);
const bgCan = copyCanvas(canvas1);
const redSize = 6,
blueSize = 5; // circle sizes on pixels
const drawSpeed = 1; // when button down draw speed in pixels per frame
const drawButton = document.getElementById("mybutton1");
var draw = true;
var X = 50,
Y = 50;
var angle = 0;
var mouseButtonDown = false;
document.addEventListener('mousedown', onMouseEvent);
document.addEventListener('mouseup', onMouseEvent);
function copyCanvas(canvas) {
const can = Object.assign(document.createElement("canvas"), {
width: canvas.width,
height: canvas.height
});
can.ctx = can.getContext("2d");
return can;
}
function circle(ctx, mousedown) {
if (mousedown && !draw)
return;
ctx.fillStyle = 'black';
ctx.beginPath();
ctx.arc(X, Y, redSize, 0, Math.PI * 2);
ctx.fill();
}
function direction(ctx) {
const d = blueSize + redSize + 3;
ctx.fillStyle = draw ? 'blue' : 'red';
ctx.beginPath();
ctx.arc(d * Math.sin(angle) + X, d * Math.cos(angle) + Y, blueSize, 0, Math.PI * 2);
ctx.fill();
}
function animate() {
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
ctx.drawImage(bgCan, 0, 0);
if (mouseButtonDown) {
circle(bgCan.ctx, mouseButtonDown);
const x = X + Math.sin(angle) * drawSpeed,
y = Y + Math.cos(angle) * drawSpeed;
if (x > (blueSize + redSize) * 2 && x < canvas1.width - (blueSize + redSize) * 2 &&
y > (blueSize + redSize) * 2 && y < canvas1.height - (blueSize + redSize) * 2)
{
X = x;
Y = y;
}
} else {
angle += 0.1;
circle(ctx);
}
direction(ctx);
requestAnimationFrame(animate);
}
function onMouseEvent(e) {
if (e.target === drawButton) {
if (e.type == "mouseup")
{
draw = !draw;
document.getElementById("mybutton1").value = draw ? "Write" : "Move";
}
return;
}
mouseButtonDown = e.type == "mousedown";
}
window.addEventListener("resize", handleResize)
function handleResize ()
{
const ratio = canvas1.width / canvas1.height;
let h = window.innerHeight,
w = h * ratio;
if (w > window.innerWidth) {
w = window.innerWidth;
h = w / ratio;
}
canvas1.style.width = w + 'px';
canvas1.style.height = h + 'px';
};
handleResize(); // First draw
#canvas1 {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border-width: 1px;
border-style: solid;
border-color: Black;
z-index: -1; /* let other elements receive events */
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Canvas basics</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<canvas id="canvas1" scaleMode='fill'></canvas>
<input type="button" value="Write" id="mybutton1" />
<script src="script.js"></script>
</body>
</html>

How can I make two circle objects (inside the canvas ) movable?

I have one circle that movable in canvas, and the circle is not the set position. It is created in any place when the mouse is clicked. I am trying to create two circles (pink and yellow) in a set position, and I want to create the circles drag-gable (mouse click -> able to move X, Y positions ) to any places on the canvas. How can I attempt this?
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
ctx.beginPath();
canvas.addEventListener('mousedown', function(e) {
this.down = true;
this.X = e.pageX;
this.Y = e.pageY;
}, 0);
canvas.addEventListener('mouseup', function() {
this.down = false;
}, 0);
canvas.addEventListener('mousemove', function(e) {
if (this.down) {
// clear canvas
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.beginPath();
ctx.arc(this.X, this.Y, 50, 0, 2 * Math.PI, true);
ctx.fillStyle = "#FF6A6A";
ctx.fill();
ctx.stroke();
this.X = e.pageX;
this.Y = e.pageY;
}
}, 0);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Canvas</title>
</head>
<body>
<canvas id="canvas" style='background-color:#EEE;' width='500px' height='200px'></canvas>
</body>
</html>
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var model = {
circle1: { x: 200, y: 200 },
circle2: { x: 200, y: 200 }
};
var radius = 50;
function view(ctx, model) {
function circle(c) {
ctx.beginPath();
ctx.beginPath();
ctx.arc(c.x, c.y, radius, 0, 2 * Math.PI, true);
ctx.fillStyle = "#FF6A6A";
ctx.fill();
ctx.stroke();
}
// clear canvas
ctx.clearRect(0, 0, canvas.width, canvas.height);
circle(model.circle1);
circle(model.circle2);
}
function redraw() {
view(ctx, model);
}
redraw();
function getCircleForPosition(x, y) {
function intersect(a, b) {
var d2 = Math.pow(a.x - b.x, 2) + Math.pow(a.y - b.y, 2);
r2 = Math.pow(radius, 2);
return d2 < r2;
}
return [model.circle1, model.circle2].find(circle => intersect(circle, { x, y }));
}
canvas.addEventListener('mousedown', function(e) {
model.dragging = getCircleForPosition(e.pageX, e.pageY);
}, 0);
canvas.addEventListener('mouseup', function() {
model.dragging = undefined;
}, 0);
canvas.addEventListener('mousemove', function(e) {
if (model.dragging) {
model.dragging.x = e.pageX;
model.dragging.y = e.pageY;
redraw();
}
}, 0);
<canvas id="canvas" style='background-color:#EEE;' width='500px' height='500px'></canvas>
fiddle: https://jsfiddle.net/eguneys/qgwtaL2p/18/

Why the last rectangle isnt delete?

I want do box selection of window desk as shown for the image below but then with my canvas code.
I'm a newbie on canvas, and I had assumed that drawing the image with requestAnimationFrame would be the same as clearRect () and thus eliminate the previously drawn rectangles.
My problem is that all the previous rectangles are not deleted, how can this be achieved?
My code:
window.addEventListener("load", _init);
function _init(w = window, d = document) {
var canvas = d.getElementsByTagName("CANVAS")[0],
ctx = canvas.getContext("2d");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
var cW = canvas.width,
cH = canvas.height,
flag = 0,
obj = {
initX: null,
initY: null,
curX: null,
curY: null
};
canvas.addEventListener("mousedown", e => {
flag = 1;
obj.initX = e.clientX;
obj.initY = e.clientY;
});
canvas.addEventListener("mouseup", e => {
console.log("Mouseup!");
flag = 0;
});
canvas.addEventListener("mousemove", e => {
if(flag === 1) {
flag = 2;
}
if(flag === 2) {
obj.curX = e.clientX;
obj.curY = e.clientY;
}
});
function scene() {
drawBackground();
if(flag === 2) drawRectangle(obj);
requestAnimationFrame(scene);
}
function drawBackground() {
var image = new Image();
image.src = "http://wallpaperswide.com/download/background_logon_default_windows_7-wallpaper-1920x1200.jpg";
image.onload = _ => {
ctx.drawImage(image, 0, 0, cW, cH);
};
}
function drawRectangle(data) {
ctx.save();
ctx.strokeStyle = "rgba(48, 242, 62, 0.75)";
ctx.moveTo(data.initX, data.initY);
ctx.lineTo(data.curX, data.initY);
ctx.lineTo(data.curX, data.curY);
ctx.lineTo(data.initX, data.curY);
ctx.lineTo(data.initX, data.initY);
ctx.stroke();
ctx.restore();
}
requestAnimationFrame(scene);
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title> Square Generator </title>
<script src="square.js"></script>
<style>
body,html {
padding: 0; border: 0; margin: 0; top: 0; left: 0; overflow: hidden;
}
</style>
</head>
<body>
<canvas></canvas>
</body>
</html>
You need to call the ctx.beginPath() function
The CanvasRenderingContext2D.beginPath() method of the Canvas 2D API starts a new path by emptying the list of sub-paths. Call this method when you want to create a new path.
//Call that function within your `drawRectangle`logic
function drawRectangle(data) {
ctx.beginPath();
ctx.strokeStyle = "rgba(48, 242, 62, 0.75)";
....
}
window.addEventListener("load", _init);
function _init(w = window, d = document) {
var canvas = d.getElementsByTagName("CANVAS")[0],
ctx = canvas.getContext("2d");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
var cW = canvas.width,
cH = canvas.height,
flag = 0,
obj = {
initX: null,
initY: null,
curX: null,
curY: null
};
canvas.addEventListener("mousedown", e => {
flag = 1;
obj.initX = e.clientX;
obj.initY = e.clientY;
});
canvas.addEventListener("mouseup", e => {
flag = 0;
});
canvas.addEventListener("mousemove", e => {
if (flag === 1) {
flag = 2;
}
if (flag === 2) {
obj.curX = e.clientX;
obj.curY = e.clientY;
}
});
function scene() {
drawBackground();
if (flag === 2) drawRectangle(obj);
requestAnimationFrame(scene);
}
function drawBackground() {
var image = new Image();
image.src = "http://wallpaperswide.com/download/background_logon_default_windows_7-wallpaper-1920x1200.jpg";
image.onload = _ => {
ctx.drawImage(image, 0, 0, cW, cH);
};
}
function drawRectangle(data) {
ctx.beginPath();
ctx.strokeStyle = "rgba(48, 242, 62, 0.75)";
ctx.moveTo(data.initX, data.initY);
ctx.lineTo(data.curX, data.initY);
ctx.lineTo(data.curX, data.curY);
ctx.lineTo(data.initX, data.curY);
ctx.lineTo(data.initX, data.initY);
ctx.stroke();
ctx.restore();
}
requestAnimationFrame(scene);
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title> Square Generator </title>
<script src="square.js"></script>
<style>
body,
html {
padding: 0;
border: 0;
margin: 0;
top: 0;
left: 0;
overflow: hidden;
}
</style>
</head>
<body>
<canvas></canvas>
</body>
</html>

Drawing app : turn pixels to grayscale or erase them

I have a drawing app which consists of a container with a background image in grayscale and over it, there's another image (the same but not in grayscale).
When I draw on my image, I would to erase where I drawn or turn in grayscale (to reproduce the image in background).
How can I achieve that ?
Here is my code :
<!DOCTYPE html>
<html>
<head>
<title>TODO supply a title</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
#wrapper {
width: 600px;
height: 400px;
border: 1px solid black;
margin: 0 auto;
background-image: url('elephant-nb-400.jpg');
}
</style>
</head>
<body>
<div id="wrapper">
<canvas width="600" height="400"></canvas>
</div>
<script>
window.onload = function() {
var wrapper = document.querySelector("#wrapper");
var canvas = document.querySelector("#wrapper canvas");
var context = canvas.getContext("2d");
var image = document.createElement("img");
image.setAttribute("src", "elephant-400.jpg");
image.onload = function() {
context.drawImage(image, 0, 0, 600, 400);
};
var positionsX = new Array();
var positionsY = new Array();
var movements = new Array();
var imageData = context.getImageData(0, 0, canvas.width, canvas.height);
var data = imageData.data;
var isErasing;
canvas.addEventListener("mousedown", function(e) {
var mouseX = e.pageX - this.offsetLeft;
var mouseY = e.pageY - this.offsetTop;
isErasing = true;
addPositions(mouseX, mouseY);
draw();
});
canvas.addEventListener("mousemove", function(e) {
var mouseX = e.pageX - this.offsetLeft;
var mouseY = e.pageY - this.offsetTop;
if(isErasing) {
addPositions(mouseX, mouseY, true);
draw();
}
});
canvas.addEventListener("mouseup", function(e) {
isErasing = false;
});
var addPositions = function(x, y, isMoving) {
positionsX.push(x);
positionsY.push(y);
movements.push(isMoving);
}
var draw = function(){
//context.clearRect(0, 0, context.canvas.width, context.canvas.height); // Clears the canvas
for(var i=0; i < positionsX.length; i++) {
context.beginPath();
if(movements[i] && i){
}else{
}
context.lineTo(positionsX[i], positionsY[i]);
context.closePath();
context.stroke();
}
}
}
</script>
</body>
My problem is solved.
You need to get the image data : var imageData = context.getImageData(0, 0, canvas.width, canvas.height);
In function draw(), you need to add : context.putImageData(imageData, 0, 0, positionsX[i]-1, positionsY[i], 20, 20); after context.moveTo(positionsX[i-1], positionsY[i-1]);and context.moveTo(positionsX[i]-1, positionsY[i]);

Image not showing in javascript

When running my program I have an image I want to draw on the mouse's x position(clientX) and y position(clientY).
When running the program regularly by not using client x and y in the position for being drawn, it works just fine.
This is the image
//variables
var c = document.getElementById("canvas");
var ctx = c.getContext("2d");
var player = new Image();
player.src = "http://i.stack.imgur.com/P9vJm.png";
//functions
function start() {
setInterval(update, 10);
}
function update() {
clearRender();
render();
}
function clearRender() {
ctx.clearRect(0,0,1300,500);
}
function render() {
var mx = document.clientX;
var my = document.clientY;
ctx.drawImage(player, mx, my);
}
#canvas {
height: 500px;
width: 1300px;
background-color: black;
position: absolute;
left: 25px;
top: 50px;
}
body {
background-color: white;
}
<!DOCTYPE html>
<html>
<head>
<title> Space Invaders </title>
<link rel="stylesheet" type="text/css" href="invader.css">
</head>
<body>
<canvas id="canvas"> </canvas>
<script type="text/javascript" src="invader.js"></script>
</body>
</html>
To get you started, you would need an event handler to get your mouse position
c.addEventListener('mousemove', update, false);
JS:
//variables
var c = document.getElementById("canvas");
var ctx = c.getContext("2d");
var player = new Image();
player.src = "http://i.stack.imgur.com/P9vJm.png";
c.addEventListener('mousemove', update, false);
//functions
function start() {
setInterval(update, 10);
}
function update(e) {
//clearRender();
render(e);
}
function clearRender() {
ctx.clearRect(0, 0, 1300, 500);
}
function render(e) {
var pos = getMousePos(c, e);
posx = pos.x;
posy = pos.y;
ctx.drawImage(player, posx, posy);
}
function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect();
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}
Here's a fiddle: https://jsfiddle.net/vwbo8k6k/
This might help you understand more about mouse positions, but I hope the image shows this time.
http://stackoverflow.com/a/17130415/2036808

Categories

Resources