Mask image in html canvas - javascript

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;
}

Related

How to create a (moving) clip mask with trails on a canvas

I succeed in coding a moving (visible) path with trails – as in
https://www.kirupa.com/canvas/follow_mouse_cursor.htm
But when I replace ctx.fill() with ctx.clip() nothing is seen … Here is my javascript code – see the complete code at https://codepen.io/j-raff/pen/JQxOPj
var jrCanvas = document.getElementById("jr-canvas");
var ctx = jrCanvas.getContext("2d");
var mouseX, mouseY;
var bgImageOnCanvas = new Image();
bgImageOnCanvas.src =
"http://www.graffik.de/wp-content/uploads/forgethers-abgesang-01.png";
bgImageOnCanvas.onload = function() {
ctx.drawImage(bgImageOnCanvas, 0, 0);
};
jrCanvas.addEventListener("mousemove", function(e){
mouseX = e.clientX;
mouseY = e.clientY;
}, false);
function update() {
ctx.save();
ctx.beginPath();
ctx.arc(mouseX, mouseY, 50, 0, Math.PI * 2, true);
ctx.clip();
requestAnimationFrame(update);
}
update();
I solved this in the meantime :)
Had to move the background image into update()
Added ctx.restore() in update()
See https://codepen.io/j-raff/pen/zVepOK
var jrCanvas = document.getElementById("jr-canvas");
var ctx = jrCanvas.getContext("2d");
var mouseX, mouseY;
var x, y;
var bgImageOnCanvas = new Image();
bgImageOnCanvas.src =
"http://www.graffik.de/wp-content/uploads/forgethers-abgesang-01.png";
jrCanvas.addEventListener("mousemove", function(e){
mouseX = e.clientX;
mouseY = e.clientY;
update();
}, false);
function update() {
ctx.save();
ctx.beginPath();
ctx.arc(mouseX, mouseY, 50, 0, Math.PI * 2, true);
ctx.clip();
ctx.drawImage(bgImageOnCanvas, 0, 0);
ctx.restore();
}

How to add gradient effect in selected image object from HTML canvas using jquery

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>

How can I get coordinate of a image on canvas?

function writeMessage(canvas, message) {
var context = canvas.getContext('2d');
context.clearRect(0, 0, canvas.width, canvas.height);
context.font = '12pt Calibri';
context.fillStyle = 'black';
context.fillText(message, 10, 25);
}
function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect();
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}
function make_base() {
base_image = new Image();
base_image.src = 'https://www.w3schools.com/css/img_fjords.jpg';
base_image.onload = function() {
context.drawImage(base_image, 0, 0);
}
}
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
make_base();
canvas.addEventListener('mousemove', function(evt) {
var mousePos = getMousePos(canvas, evt);
var message = 'Mouse position: ' + mousePos.x + ',' + mousePos.y;
writeMessage(canvas, message);
}, false);
<canvas id="myCanvas" width="500" height="500" style="border:1px solid #000000;">
</canvas>
I can add a image on a canvas and also get coordinates of canvas when mouse hovers on it.
But I when I hover on photo, the image will disappear.
The issue is, you are clearing the entire canvas each time before drawing the text (message), which clears the image as well.
To resolve this, you would need to re-draw the image after clearing the canvas and before drawing the text ...
function writeMessage(canvas, message) {
var context = canvas.getContext('2d');
context.clearRect(0, 0, canvas.width, canvas.height);
context.drawImage(base_image, 0, 0); //<-- draw image
context.font = '12pt Calibri';
context.fillStyle = 'red';
context.fillText(message, 10, 25);
}
function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect();
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}
function make_base() {
base_image = new Image();
base_image.src = 'https://www.w3schools.com/css/img_fjords.jpg';
base_image.onload = function() {
context.drawImage(base_image, 0, 0);
}
}
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
make_base();
canvas.addEventListener('mousemove', function(evt) {
var mousePos = getMousePos(canvas, evt);
var message = 'Mouse position: ' + mousePos.x + ',' + mousePos.y;
writeMessage(canvas, message);
}, false);
<canvas id="myCanvas" width="500" height="500" style="border:1px solid #000000;"></canvas>

How to fade out an item in canvas

I have a full screen canvas in my page. There are also some dive elements over this canvas. there is an circle element in the canvas that moves with the cursor everywhere in the page. However when the cursor arrives to the div element over the canvas, the circle shape stays in the last place it was on the canvas before arriving to the div.
DEMO: JSFIDDLE
Is ther any way that I can fade-out the circle shape when the cursor is over the div element and fade it in when it backs to the canvas?
Also is there any other effect rather than fading out? like making it small and then fade-out...
Here is the bit of code related to the circle:
function writeMessage(canvas, message, x, y) {
var context = canvas.getContext('2d');
context.clearRect(0, 0, canvas.width, canvas.height);
var pattern = context.createPattern(imageResized, 'no-repeat');//Use imageResized, not imageObj.
context.fillStyle = pattern;
context.fill();
context.fillStyle = 'black';
context.beginPath();
context.arc(x, y, 60, 0, 2 * Math.PI);
}
Well, you can always create your own fade function that gets called on mouseout (or mouseleave) event. Here's one I quickly built for you:
function fadeOut(canvas, message, x, y, amount) {
var context = canvas.getContext('2d');
context.clearRect(0, 0, canvas.width, canvas.height);
var pattern = context.createPattern(imageResized, 'no-repeat');
context.fillStyle = pattern;
context.fill();
context.font = '28pt Calibri';
context.fillStyle = 'black';
context.beginPath();
context.arc(x, y, amount, 0, 2 * Math.PI);
if (amount > 0) {
setTimeout(function(){
fadeOut(canvas, message, x, y, --amount);
}, 2);
}
else {
context.clearRect(0, 0, canvas.width, canvas.height);
}
}
See it in action here: http://jsfiddle.net/2p9dn8ed/42/
Or in the snippet:
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var x = 0;
var y = 0;
var width = window.innerWidth;
var height = window.innerHeight;
var imageObj = new Image();
console.log(window.innerWidth + "----" + window.innerHeight);
//Create another canvas to darw a resized image to.
var imageResized = document.createElement('canvas');
imageResized.width = width;
imageResized.height = height;
//Wait for the original image to low to draw the resize.
imageObj.onload = function() {
//Find hoe mauch to scale the image up to cover.
var scaleX = width / imageObj.width;
var scaleY = height / imageObj.height;
var scaleMax = Math.max(scaleX, scaleY);
var ctx = imageResized.getContext('2d');
ctx.scale(scaleMax, scaleMax);
ctx.drawImage(imageObj, 0, 0);
};
imageObj.src = 'http://www.html5canvastutorials.com/demos/assets/darth-vader.jpg';
function writeMessage(canvas, message, x, y) {
var context = canvas.getContext('2d');
context.clearRect(0, 0, canvas.width, canvas.height);
var pattern = context.createPattern(imageResized, 'no-repeat');//Use imageResized, not imageObj.
context.fillStyle = pattern;
context.fill();
context.font = '28pt Calibri';
context.fillStyle = 'black';
//context.fillText(message, x, y);
context.beginPath();
context.arc(x, y, 60, 0, 2 * Math.PI);
//context.stroke();
//
}
function fadeOut(canvas, message, x, y, amount) {
var context = canvas.getContext('2d');
context.clearRect(0, 0, canvas.width, canvas.height);
var pattern = context.createPattern(imageResized, 'no-repeat');//Use imageResized, not imageObj.
context.fillStyle = pattern;
context.fill();
context.font = '28pt Calibri';
context.fillStyle = 'black';
//context.fillText(message, x, y);
context.beginPath();
context.arc(x, y, amount, 0, 2 * Math.PI);
//context.stroke();
//
if (amount > 0) {
setTimeout(function(){
fadeOut(canvas, message, x, y, --amount);
}, 2);
}
else {
context.clearRect(0, 0, canvas.width, canvas.height);
}
}
function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect();
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}
canvas.addEventListener('mousemove', function (evt) {
var mousePos = getMousePos(canvas, evt);
var message = 'Mouse position: ' + mousePos.x + ',' + mousePos.y;
writeMessage(canvas, message, mousePos.x, mousePos.y);
}, false);
canvas.addEventListener('mouseout', function(evt){
var mousePos = getMousePos(canvas, evt);
var message = 'Mouse position: ' + mousePos.x + ',' + mousePos.y;
console.log(1);
fadeOut(canvas, message, mousePos.x, mousePos.y, 60);
});
// Get the canvas element form the page
var canvas = document.getElementById("myCanvas");
/* Rresize the canvas to occupy the full page,
by getting the widow width and height and setting it to canvas*/
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
anvas, img {
display:block;
margin:1em auto;
border:1px solid black;
}
canvas {
background:url('../img/spiral_galaxy-1920x1080.jpg');
background-size: cover;
position: absolute;
left: 0; top: 0;
width: 100%; height: 100%;
z-index:-1;
}
div{
width:200px;
height:200px;
background:rgba(0,0,0,0.5);
position: fixed;
top: 20%;
left: 20%;
}
<canvas id="myCanvas" width="578" height="400"></canvas>
<div><h1>TEXT</h1></div>

Cannot clear the canvas

I am trying to clear the canvas for redrawing, it gets clear and when we try to redraw, the previous thing comes back.
Here is my code:
var drawingApp = (function () {
//declaring Variables
var canvas,
canvasDiv,
context,
canvasWidth = 200,
canvasHeight = 200,
clickX = [],
clickY = [],
clickDrag = [],
paint = false;
//Initalisation Function
function init() {
canvasDiv = document.getElementById('canvasDiv');
canvas = document.createElement('canvas');
canvas.setAttribute('width', canvasWidth);
canvas.setAttribute('height', canvasHeight);
canvas.setAttribute('id', 'canvas');
canvasDiv.appendChild(canvas);
if (typeof G_vmlCanvasManager != 'undefined') {
canvas = G_vmlCanvasManager.initElement(canvas);
}
context = canvas.getContext("2d");
loadEvents(); //Load events
}
function loadEvents() {
//Mouse down Event
$('#canvas').mousedown(function (e) {
var mouseX = e.pageX - this.offsetLeft;
var mouseY = e.pageY - this.offsetTop;
paint = true;
addClick(e.pageX - this.offsetLeft, e.pageY - this.offsetTop);
redraw();
});
//Mouse Move Event
$('#canvas').mousemove(function (e) {
if (paint) {
addClick(e.pageX - this.offsetLeft, e.pageY - this.offsetTop, true);
redraw();
}
});
//Mouse Up Event
$('#canvas').mouseup(function (e) {
paint = false;
});
//Mouse Leave Event
$('#canvas').mouseleave(function (e) {
paint = false;
});
}
//Add Click Function
function addClick(x, y, dragging) {
clickX.push(x);
clickY.push(y);
clickDrag.push(dragging);
}
//Redraw Function
function redraw() {
context.clearRect(0, 0, context.canvas.width, context.canvas.height); // Clears the canvas
context.strokeStyle = "#df4b26";
context.lineJoin = "round";
context.lineWidth = 5;
for (var i = 0; i < clickX.length; i++) {
context.beginPath();
if (clickDrag[i] && i) {
context.moveTo(clickX[i - 1], clickY[i - 1]);
} else {
context.moveTo(clickX[i] - 1, clickY[i]);
}
context.lineTo(clickX[i], clickY[i]);
context.closePath();
context.stroke();
}
}
// Clears the canvas.
function clearCanvas() {
context.clearRect(0, 0, canvas.width, canvas.height);
}
return {
init: init,
erase: clearCanvas
};
})();
$(function () {
drawingApp.init();
});
Here is my fiddle
Please see where m getting wrong
When you clear your canvas using the erase function, you fail to clear the clickX, clickY and clickDrag variables. So the next time it draws it still draws the old data.
Updated JSFiddle - http://jsfiddle.net/P8acZ/6/
The code that changed
function clearCanvas() {
clickDrag = [];
clickX = [];
clickY = [];
context.clearRect(0, 0, canvas.width, canvas.height);
}

Categories