I tried to provide an eraser as if it was a brush, to erase distinctively. I have a black rect and a picture as canvas background. How can I erase parts of the rect?
"Erasing" in html5 canvas, did not work
my fiddle: http://jsfiddle.net/FgNQk/10/
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var width = window.innerWidth;
var height = window.innerHeight;
canvas.height = height;
canvas.width = width;
ctx.fillRect(100,100,100,100);
canvas.addEventListener('mousedown', function(e) {
this.down = true;
this.X = e.pageX ;
this.Y = e.pageY ;
this.color = rgb();
}, 0);
canvas.addEventListener('mouseup', function() {
this.down = false;
}, 0);
canvas.addEventListener('mousemove', function(e) {
if(this.down) {
with(ctx) {
beginPath();
moveTo(this.X, this.Y);
lineTo(e.pageX , e.pageY );
strokeStyle = "rgba(255,255,255,0.0)";
ctx.lineWidth=1;
stroke();
}
this.X = e.pageX ;
this.Y = e.pageY ;
}
}, 0);
The solution in the link actually works. Try:
with(ctx) {
beginPath();
moveTo(this.X, this.Y);
lineTo(e.pageX , e.pageY );
globalCompositeOperation = "destination-out";
strokeStyle = "rgba(0,0,0,1)";
ctx.lineWidth=1;
stroke();
}
Related
I have a video element playing a mp4 video.
When clicking the screenshot button, it draws the current video frame on the canvas. I would then like to draw on top of the canvas.
My problem is that I can't get the cursor to align with the drawing coordinates. I have a suspicion that this is because of the way I'm setting the height and the width of the canvas to be able to draw the video frame correctly.
Minimal repro:
https://codepen.io/stiba/pen/KEBRdy
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var video = document.getElementById('vid');
canvas.addEventListener('mousedown', mouseDown);
canvas.addEventListener('mouseup', mouseUp);
canvas.addEventListener('mousemove', mouseMove);
var isDrawing = false;
var prevX = 0;
var prevY = 0;
var currX = 0;
var currY = 0;
function buttonClick() {
console.log('Clicked!');
var height = video.videoHeight;
var width = video.videoWidth;
canvas.width = width;
canvas.height = height;
ctx.fillRect(0, 0, width, height);
ctx.drawImage(video, 0, 0, width, height);
}
function setCoordinates(e) {
prevX = currX;
prevY = currY;
var boundingClientRect = e.target.getBoundingClientRect();
var left = boundingClientRect.left;
var top = boundingClientRect.top;
currX = e.clientX - left;
currY = e.clientY - top;
}
function mouseDown(e) {
setCoordinates(e);
isDrawing = true;
}
function mouseUp(e) {
isDrawing = false;
}
function mouseMove(e) {
if (!isDrawing) {
return;
}
setCoordinates(e);
draw();
}
function draw() {
ctx.beginPath();
ctx.moveTo(prevX, prevY);
ctx.lineTo(currX, currY);
ctx.strokeStyle = "red";
ctx.lineWidth = 2;
ctx.stroke();
ctx.closePath();
}
Removing the css styles from your canvas will fix the issue. If you need your canvas to be larger use canvas.width and canvas.height properties. Using css to control your canvas size will only increase the html element size but not the drawing surface(pixels).
css to be removed:
flex: 1;
width: 100%;
I have html canvas where i dropped image on it i want to apply linear gradient effect on image. My scenario is that user can select some portion of image on canvas by mouse and he can select color from color picker. I want to apply effect on selected portion only.
That sounds like a job for createRadialGradient():
var mouse = {
down: false,
x1: null,
y1: null,
x2: null,
y1: null
};
var grad = 'transparent';
var ctx = canvas.getContext('2d');
var img = new Image();
img.onload = init;
img.src = "https://upload.wikimedia.org/wikipedia/commons/thumb/a/a1/D%C3%BClmen%2C_Kirchspiel%2C_B%C3%B6rnste%2C_Feld_--_2017_--_3171.jpg/500px-D%C3%BClmen%2C_Kirchspiel%2C_B%C3%B6rnste%2C_Feld_--_2017_--_3171.jpg";
function updateGrad() {
var cx = mouse.x1;
var cy = mouse.y1;
var dist = Math.hypot(mouse.x1-mouse.x2, mouse.y1-mouse.y2);
grad = ctx.createRadialGradient(cx, cy, 0, cx, cy, dist);
grad.addColorStop(1, 'black');
grad.addColorStop(0, 'transparent');
}
function draw() {
// draw the image
ctx.drawImage(img, 0,0);
// draw the gradient
ctx.fillStyle = grad;
ctx.fillRect(0,0,canvas.width,canvas.height);
// draw the line?
ctx.beginPath();
ctx.rect(mouse.x1 - 4, mouse.y1 - 4, 8, 8);
ctx.moveTo(mouse.x1, mouse.y1);
ctx.lineTo(mouse.x2, mouse.y2);
ctx.rect(mouse.x2 - 4, mouse.y2 - 4, 8, 8);
ctx.stroke();
}
function init() {
canvas.width = this.width;
canvas.height = this.height;
canvas.onmousedown = mousedown;
document.onmousemove = mousemove;
document.onmouseup = mouseup;
ctx.strokeStyle = 'white';
draw();
}
function mousedown(evt) {
var rect = canvas.getBoundingClientRect();
mouse.down = true;
mouse.x1 = evt.clientX - rect.left;
mouse.y1 = evt.clientY - rect.top;
}
function mousemove(evt) {
if(!mouse.down) return;
var rect = canvas.getBoundingClientRect();
mouse.x2 = evt.clientX - rect.left;
mouse.y2 = evt.clientY - rect.top;
updateGrad();
draw();
}
function mouseup(evt) {
mouse.down = false;
}
<canvas id="canvas"></canvas>
I'm creating a simple whiteboard using html5 canvas.
I need to give the canvas a width and height. This causes the whiteboard to not work properly.
If I remove the width and height from the canvas, it works fine!
This is my code:
var myCanvas = document.getElementById("myCanvas");
var ctx = myCanvas.getContext("2d");
// Fill Window Width and Height
myCanvas.width = window.innerWidth;
myCanvas.height = window.innerHeight;
// Set Background Color
ctx.fillStyle="#fff";
ctx.fillRect(0,0,myCanvas.width,myCanvas.height);
// Mouse Event Handlers
if(myCanvas){
var isDown = false;
var canvasX, canvasY;
ctx.lineWidth = 5;
$(myCanvas)
.mousedown(function(e){
isDown = true;
ctx.beginPath();
canvasX = e.pageX - myCanvas.offsetLeft;
canvasY = e.pageY - myCanvas.offsetTop;
ctx.moveTo(canvasX, canvasY);
})
.mousemove(function(e){
if(isDown !== false) {
canvasX = e.pageX - myCanvas.offsetLeft;
canvasY = e.pageY - myCanvas.offsetTop;
ctx.lineTo(canvasX, canvasY);
ctx.strokeStyle = "#000";
ctx.stroke();
}
})
.mouseup(function(e){
isDown = false;
ctx.closePath();
});
}
// Touch Events Handlers
draw = {
started: false,
start: function(evt) {
ctx.beginPath();
ctx.moveTo(
evt.touches[0].pageX,
evt.touches[0].pageY
);
this.started = true;
},
move: function(evt) {
if (this.started) {
ctx.lineTo(
evt.touches[0].pageX,
evt.touches[0].pageY
);
ctx.strokeStyle = "#000";
ctx.lineWidth = 5;
ctx.stroke();
}
},
end: function(evt) {
this.started = false;
}
};
// Touch Events
myCanvas.addEventListener('touchstart', draw.start, false);
myCanvas.addEventListener('touchend', draw.end, false);
myCanvas.addEventListener('touchmove', draw.move, false);
// Disable Page Move
document.body.addEventListener('touchmove',function(evt){
evt.preventDefault();
},false);
#myCanvas{
width:90%;
height:200px;
border:solid 1px #c8def0;
border-radius:10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<canvas id="myCanvas">
Sorry, your browser does not support HTML5 canvas technology.
</canvas>
basically, when I run the above code, the mouse doesn't go all the way down the canvas but if I remove the canvas width and height, it works fine.
Could someone please advice on this issue?
Thanks in advance.
I have a drawing interface which the drawings need to be saved at 1280x720px. However, I want the canvas to be able to be scalable in relation to that aspect ratio. A problem is that when I draw, the start of the path is not on the cursor.
I've looked everywhere and cannot find a solution. Here is the javascript:
var clearButton = document.getElementById('doodle-bin');
var canvascontainer = document.getElementById('doodle-canvas-container');
var canvas = document.getElementById('doodle-canvas');
var context = canvas.getContext('2d');
var radius = (document.getElementById('doodle-canvas-container').clientWidth + document.getElementById('doodle-canvas-container').clientHeight)/150;
var dragging = false;
context.mozImageSmoothingEnabled = false;
context.imageSmoothingEnabled = false;
canvas.width = 1280;
canvas.height = 720;
canvas.style.width = '100%';
canvas.style.height = '100%';
/* CLEAR CANVAS */
function clearCanvas() {
context.clearRect(0, 0, canvas.width, canvas.height);
}
clearButton.addEventListener('click', clearCanvas);
var putPoint = function (e) {
if (dragging) {
context.lineTo(e.offsetX, e.offsetY);
context.lineWidth = radius * 2;
context.stroke();
context.beginPath();
context.arc(e.offsetX, e.offsetY, radius, 0, Math.PI * 2);
context.fill();
context.beginPath();
context.moveTo(e.offsetX, e.offsetY);
}
};
var engage = function (e) {
dragging = true;
putPoint(e);
};
var disengage = function () {
dragging = false;
context.beginPath();
};
canvas.addEventListener('mousedown', engage);
canvas.addEventListener('mousemove', putPoint);
canvas.addEventListener('mouseup', disengage);
document.addEventListener('mouseup', disengage);
canvas.addEventListener('contextmenu', disengage);
Use the following function to get the proper mouse position even if the canvas is re-scaled. This will resolve the path start issue.
function getMouesPosition(e) {
var mouseX = e.offsetX * canvas.width / canvas.clientWidth | 0;
var mouseY = e.offsetY * canvas.height / canvas.clientHeight | 0;
return {x: mouseX, y: mouseY};
}
var clearButton = document.getElementById('doodle-bin');
var canvascontainer = document.getElementById('doodle-canvas-container');
var canvas = document.getElementById('doodle-canvas');
var context = canvas.getContext('2d');
var radius = (document.getElementById('doodle-canvas-container').clientWidth + document.getElementById('doodle-canvas-container').clientHeight) / 150;
var dragging = false;
context.mozImageSmoothingEnabled = false;
context.imageSmoothingEnabled = false;
canvas.width = 1280;
canvas.height = 720;
canvas.style.width = '100%';
canvas.style.height = '100%';
/* CLEAR CANVAS */
function clearCanvas() {
context.clearRect(0, 0, canvas.width, canvas.height);
}
clearButton.addEventListener('click', clearCanvas);
function getMouesPosition(e) {
var mouseX = e.offsetX * canvas.width / canvas.clientWidth | 0;
var mouseY = e.offsetY * canvas.height / canvas.clientHeight | 0;
return {x: mouseX, y: mouseY};
}
var putPoint = function (e) {
if (dragging) {
context.lineTo(getMouesPosition(e).x, getMouesPosition(e).y);
context.lineWidth = radius * 2;
context.stroke();
context.beginPath();
context.arc(getMouesPosition(e).x, getMouesPosition(e).y, radius, 0, Math.PI * 2);
context.fill();
context.beginPath();
context.moveTo(getMouesPosition(e).x, getMouesPosition(e).y);
}
};
var engage = function (e) {
dragging = true;
putPoint(e);
};
var disengage = function () {
dragging = false;
context.beginPath();
};
canvas.addEventListener('mousedown', engage);
canvas.addEventListener('mousemove', putPoint);
canvas.addEventListener('mouseup', disengage);
document.addEventListener('mouseup', disengage);
canvas.addEventListener('contextmenu', disengage);
body{margin:0;overflow:hidden}canvas{border:1px solid #ccc}
<button id="doodle-bin">Clear</button>
<div id="doodle-canvas-container">
<canvas id="doodle-canvas"></canvas>
</div>
Im trying to change a mask to an image in a html5 canvas when the mouse enters the canvas.
When the mouse enters the canvas i draw a shape thats gonna act as a mask. It draws as i want but it wont mask the image.
The function that draws the mask is drawLine();
What is wrong here?
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
var img = document.createElement('IMG');
var mY;
var mX;
img.onload = function () {
context.save();
context.beginPath();
context.moveTo(0, 0);
context.lineTo(160, 600);
context.rect(0, 0, 160, 600);
context.closePath();
context.clip();
context.drawImage(img, 0, 0);
context.restore();
};
img.src = "http://placekitten.com/160/600";
canvas.addEventListener('mouseenter', function(evt) {
var mousePos = getMousePos(canvas, evt);
var message = mousePos.y + ', ' + mousePos.x;
mY = mousePos.y;
mX = mousePos.x;
drawLine();
}, false);
function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect();
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}
function drawLine() {
if(mX > 80) {
context.restore();
context.fillStyle = "rgb(000,000,000)";
context.beginPath();
context.moveTo(160, mY);
context.lineTo(0,mY+setCutAngle());
context.lineTo(0,600);
context.lineTo(160,600);
context.fill();
context.closePath();
} else {
}
context.stroke();
}
function setCutAngle() {
return Math.floor(Math.random() * 45) + 10;
}
Is this what you are looking for? JSFIDDLE Updated so image loads at the start.
I believe your main problem was caused by not clearing the canvas. Thus your clip would not show
Updated JSFIDDLE to match your code. Remove that logic from your load event. It should only happen on your drawevent. You are also not clearling or clipping your image in the draw event.
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
var img = document.createElement('IMG');
var mY;
var mX;
img.onload = function () {
context.drawImage(img, 0, 0);
};
img.src = "http://placekitten.com/160/600";
canvas.addEventListener('mouseenter', function(evt) {
var mousePos = getMousePos(canvas, evt);
var message = mousePos.y + ', ' + mousePos.x;
mY = mousePos.y;
mX = mousePos.x;
drawLine();
}, false);
function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect();
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}
function drawLine() {
context.save();
context.clearRect(0, 0, canvas.width, canvas.height);
if(mX > 80) {
context.restore();
context.fillStyle = "rgb(000,000,000)";
context.beginPath();
context.moveTo(160, mY);
context.lineTo(0,mY+setCutAngle());
context.lineTo(0,600);
context.lineTo(160,600);
context.clip();
context.drawImage(img, 0, 0);
context.closePath();
} else {
}
context.stroke()
}
function setCutAngle() {
return Math.floor(Math.random() * 45) + 10;
}