zoom jpeg image on canvas with mousewheel event in javascript - javascript

I have written simple code in java script which adds JPEG image on canvas & add line on that image with simple mousedown & mouseup event. Now i wanted to add zoom-in & zoom-out effect on that image.can anybody help me out?
my js file looks as below.
var canvas;
var context;
var width;
var height;
var finalPos = {x: 0, y: 0};
var startPos = {x: 0, y: 0};
function main() {
canvas = document.getElementById('imageCanvas');
context = canvas.getContext('2d');
loadImage();
width = canvas.width;
height = canvas.height;
var canvasOffset = $('#imageCanvas').offset();
function line(cnvs) {
cnvs.beginPath();
cnvs.moveTo(startPos.x, startPos.y);
cnvs.lineTo(finalPos.x, finalPos.y);
cnvs.stroke();
}
$('#imageCanvas').mousedown(function (e) {
context.strokeStyle = 'blue';
context.lineWidth = 5;
context.lineCap = 'round';
context.beginPath();
startPos = {x: e.pageX - canvasOffset.left, y: e.pageY - canvasOffset.top};
});
$('#imageCanvas').mouseup(function (e) {
// Replace with var that is second canvas
finalPos = {x: e.pageX - canvasOffset.left, y: e.pageY - canvasOffset.top};
line(context);
});
}
;
function loadImage() {
system_image = new Image();
system_image.src = 'img/Google_OH_406TwentySecondStreet.jpg';
system_image.onload = function () {
context.drawImage(system_image, 0, 0, width, height);
};
}

You can use scale function on mousewheel
context.scale(scaleValue, scaleValue);
You must do that before drawimage on context.
I have created the example here: [link]: http://jsfiddle.net/itsjawad/5wohz3r1/

Related

JavaScript Canvas touch future with multiple eventListeners

I need to add a touch feature to the canvas app that I'm working on (multiple users white board), and I already read about the event listeners and the event.preventDefault(), but I can't understand how can I use two event listeners with 'DOMContentLoaded' and 'touchmove'. At this point I don't know if using multiple event listeners is the solution I need.
This is the code I'm using:
document.addEventListener("DOMContentLoaded", function() {
var mouse = {
click: false,
move: false,
pos: {x:0, y:0},
pos_prev: false
};
var canvas = document.getElementById('drawing');
var context = canvas.getContext('2d');
var width = 1280;
var height = 960;
var socket = io.connect();
var lineWidth = 1;
var shadowBlur = 1;
var shadowColor = "black";
var strokeStyle = "black";
canvas.width = width;
canvas.height = height;
canvas.onmousedown = function(e){ mouse.click = true; };
canvas.onmouseup = function(e){ mouse.click = false; };
canvas.onmousemove = function(e) {
mouse.pos.x = e.clientX / width;
mouse.pos.y = e.clientY / height;
mouse.move = true;
};
socket.on('draw_line', function (data) {
var line = data.line;
context.beginPath();
context.lineWidth = lineWidth;
context.shadowBlur = shadowBlur;
context.strokeStyle = strokeStyle;
context.lineJoin="round";
context.lineCap = "round";
context.moveTo(line[0].x * width, line[0].y * height);
context.lineTo(line[1].x * width, line[1].y * height);
context.stroke();
});
function mainLoop() {
if (mouse.click && mouse.move && mouse.pos_prev) {
socket.emit('draw_line', { line: [ mouse.pos, mouse.pos_prev ] });
mouse.move = false;
}
mouse.pos_prev = {x: mouse.pos.x, y: mouse.pos.y};
setTimeout(mainLoop, 50);
}
mainLoop();
});
I would really appreciate any help.
Thanks.
Are you encountering some sort of bug? Right now it appears that your code operates by listening for the mouse being clicked and the mouse being moved. If the mouse is pressed down, the mouse is being moved and the loop has run at least once (mouse.click && mouse.move && mouse.pos_prev) then it draws a line on the canvas element.

How can I stop HTML5 Canvas Ghosting?

I made a small program that:
changes the mouse cursor inside the canvas to a black square
gives the black square a nice trail that fades away over time (the point of the program)
Here's the code:
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
canvas.style.cursor = 'none'; // remove regular cursor inside canvas
function getMousePos(canvas, e) {
var rect = canvas.getBoundingClientRect();
return {
x: e.clientX - rect.left,
y: e.clientY - rect.top
};
}
function fadeCanvas() {
ctx.save();
ctx.globalAlpha = 0.1; // the opacity (i.e. fade) being applied to the canvas on each function re-run
ctx.fillStyle = "#FFF";
ctx.fillRect(0, 0, canvas.width, canvas.height); // area being faded (whole canvas)
ctx.restore();
requestAnimationFrame(fadeCanvas); // animate at 60 fps
}
fadeCanvas();
function draw(e) {
var pos = getMousePos(canvas, e);
ctx.fillStyle = "black";
ctx.fillRect(pos.x, pos.y, 8, 8); // the new cursor
}
addEventListener('mousemove', draw, false);
Here's a live example: https://jsfiddle.net/L6j71crw/2/
Problem
However the trail does not fade away completely, and leaves a ghosting trail.
Q: How can I remove the ghosting trail?
I have tried using clearRect() in different ways, but it just clears the entire animation leaving nothing to display. At best it just removes the trail and only fades the square cursor alone, but it still doesn't make the cursor completely transparent when the fading process is completed. I have tried finding posts about it, but I found nothing that gave a definitive answer and—most importantly—no posts with a working example.
Any ideas?
Try having a list of positions, this won't leave a ghost trail!
my code:
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var Positions = [];
var maxlength = 20;
canvas.style.cursor = 'none'; // remove regular cursor inside canvas
var V2 = function(x, y){this.x = x; this.y = y;};
function getMousePos(canvas, e) {
// ctx.clearRect(0, 0, canvas.width, canvas.height);
var rect = canvas.getBoundingClientRect();
return {
x: e.clientX - rect.left,
y: e.clientY - rect.top
};
}
function fadeCanvas() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
for(var e = 0; e != Positions.length; e++)
{
ctx.fillStyle = ctx.fillStyle = "rgba(0, 0, 0, " + 1 / e + ")";
ctx.fillRect(Positions[e].x, Positions[e].y, 8, 8);
}
if(Positions.length > 1)
Positions.pop()
//ctx.save();
//ctx.globalAlpha = 0.5; // the opacity (i.e. fade) being applied to the canvas on each function re-run
//ctx.fillStyle = "#fff";
//ctx.fillRect(0, 0, canvas.width, canvas.height); // area being faded (whole canvas)
//ctx.restore();
requestAnimationFrame(fadeCanvas); // animate at 60 fps
}
fadeCanvas();
function draw(e) {
var pos = getMousePos(canvas, e);
Positions.unshift(new V2(pos.x, pos.y));
if(Positions.length > maxlength)
Positions.pop()
//ctx.fillStyle = "black";
//ctx.fillRect(pos.x, pos.y, 8, 8); // the new cursor
}
addEventListener('mousemove', draw, false);
JSFiddle: https://jsfiddle.net/L6j71crw/9/
Edit: made the cursor constant.

Chroma keying with javascript & jQuery

Okay, we need your help! We (with our informatics class) are building a digital scratchmap! Like this:
(source: megagadgets.nl)
With your mouse you should be able to scratch out the places you've been to. Now we're stuck. We have a canvas and we draw the image of a world map. Then when the user clicks and drags a stroke gets add on top of the world map.
Now we want to convert the (green drawn) strokes to transparency so we can reveal the image behind it. (Just like scratching out the places you've been to and revealing the map behind it (in colour)).
This is our html:
<body>
<h1>Scratchmap</h1>
<hr>
<canvas id="ball" width="600px" height ="600px">
</canvas>
<canvas id="ball2" width="600px" height ="600px">
</canvas>
</body>
And this is our javascript:
// Set variables
var a_canvas = document.getElementById("ball");
var context = a_canvas.getContext("2d");
var a_canvas2 = document.getElementById("ball2");
var context2 = a_canvas2.getContext("2d");
var img = new Image();
img.onload = function () {
context.drawImage(img, img_x, img_y);
}
img.src = "worldmap.png"
var mouse_pos_x = [];
var mouse_pos_y = [];
var thickness = 0;
var arraycount = 0;
var mouse_down = false;
var mouse_skip = [];
function update() {}
document.body.onmousedown = function () {
mouse_down = true;
var mouseX, mouseY;
if (event.offsetX) {
mouseX = event.offsetX;
mouseY = event.offsetY;
} else if (event.layerX) {
mouseX = event.layerX;
mouseY = event.layerY;
}
mouse_pos_x.push(mouseX);
mouse_pos_y.push(mouseY);
arraycount += 1;
}
document.body.onmouseup = function () {
if (mouse_down) {
mouse_down = false;
mouse_skip.push(arraycount);
}
}
document.body.onmousemove = function () {
if (mouse_down) {
var mouseX, mouseY;
if (event.offsetX) {
mouseX = event.offsetX;
mouseY = event.offsetY;
} else if (event.layerX) {
mouseX = event.layerX;
mouseY = event.layerY;
}
context.drawImage(img, 0, 0);
mouse_pos_x.push(mouseX);
mouse_pos_y.push(mouseY);
context.lineWidth = 2.5;
context.strokeStyle = "#00FF00";
context.moveTo(mouse_pos_x[arraycount - 1], mouse_pos_y[arraycount - 1]);
context.lineTo(mouse_pos_x[arraycount], mouse_pos_y[arraycount]);
context.stroke();
arraycount += 1;
var imgdata = context.getImageData(0, 0, a_canvas.width, a_canvas.height);
var l = imgdata.data.length / 4;
for (var i = 0; i < l; i++) {
var r = imgdata.data[i * 4 + 0];
var g = imgdata.data[i * 4 + 1];
var b = imgdata.data[i * 4 + 2];
if (g < 255) {
imgdata.data[i * 4 + 3] = 0;
}
}
context2.putImageData(imgdata, 0, 0);
}
}
setInterval(update, 10);
Now when we remove the draw_image() the green color becomes yellow on the other canvas. But with the draw_image() nothing gets drawn on the second canvas.
What's going wrong? Or do you have a way to do this with other Javascript or not in javascript at all?
Any help would be appreciated!
Luud Janssen & Friends
You can do this with a slightly different approach:
Set the hidden image as CSS background
Draw the cover image on top using context
Change composite mode to destination-out
Anything now drawn will erase instead of draw revealing the (CSS set) image behind
Live demo
The key code (see demo linked above for details):
function start() {
/// draw top image - background image is already set with CSS
ctx.drawImage(this, 0, 0, canvas.width, canvas.height);
/// KEY: this will earse where next drawing is drawn
ctx.globalCompositeOperation = 'destination-out';
canvas.onmousedown = handleMouseDown;
canvas.onmousemove = handleMouseMove;
window.onmouseup = handleMouseUp;
}
Then it's just a matter of tracking the mouse position and draw any shape to erase that area, for example a circle:
function erase(x, y) {
ctx.beginPath();
ctx.arc(x, y, radius, 0, pi2);
ctx.fill();
}
Random images for illustrative purposes

draw on image using canvas

I have a picture which which is loaded like this:
<img src="map/racetrack.jpg" id="map">
And here is my drawing function:
this.drawRoute = function(){
var pos = [];
var canvas = $('<canvas/>')[0];
var img = $('#map')[0];
var ctx = canvas.getContext("2d");
canvas.width = img.width;
canvas.height = img.height;
$(window).on('mousedown', function(e){
pos.push({
x: e.clientX,
y: e.clientY
});
});
if (positions.length > 1) {
ctx.beginPath();
ctx.moveTo(pos[0].x, pos[0].y);
for (var i = 1; i < pos.length; i++) {
ctx.lineTo(pos[i].x, pos[i].y);
}
ctx.stroke();
}
}
But nothing is drawn on the picture. I can't see where the mistake is. I know usually I'm supposed to use <canvas> element, but I only need this particular part done in canvas, nothing else.
Here's the fiddle
Well a few things first you have no canvas element. Secondly I didnt see where you were calling the draw portion.
Live Demo
What I ended up doing was adding a canvas element, hiding the image, and then every time you draw it draws the image to the canvas, and then draws the points over it. This should hopefully be enough to get you started.
var pos = [];
var canvas = $('#canvas')[0];
var img = $('#map')[0];
var ctx = canvas.getContext("2d");
canvas.width = img.width;
canvas.height = img.height;
function render() {
ctx.drawImage(img, 0, 0);
if (pos.length > 1) {
ctx.beginPath();
ctx.moveTo(pos[0].x, pos[0].y);
for (var i = 1; i < pos.length; i++) {
ctx.lineTo(pos[i].x, pos[i].y);
}
ctx.stroke();
}
}
$(window).on('mousedown', function (e) {
pos.push({
x: e.clientX,
y: e.clientY
});
render();
});
render();

Drawing a filled circle in a canvas on mouseclick

I want to draw a filled (or not filled) circle in a canvas on mouseclick, but I can't get my code to work properly, I've tried pretty much everything!
This is my HTML:
<div id="images"></div>
<canvas style="margin:0;padding:0;position:relative;left:50px;top:50px;" id="imgCanvas" width="250" height="250" onclick="draw(e)"></canvas>
and my current script:
var canvas = document.getElementById("imgCanvas");
var context = canvas.getContext("2d");
function createImageOnCanvas(imageId) {
canvas.style.display = "block";
document.getElementById("images").style.overflowY = "hidden";
var img = new Image(300, 300);
img.src = document.getElementById(imageId).src;
context.drawImage(img, (0), (0)); //onload....
}
function draw(e) {
var pos = getMousePos(canvas, e);
posx = pos.x;
posy = pos.y;
context.fillStyle = "#000000";
context.arc(posx, posy, 50, 0, 2 * Math.PI);
}
function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect();
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}
The code works just fine if and only if I remove the "use strict";, but in this assignment I have to make a code that works even with it, which is my problem.
Here is the jsFiddle
Solved it myself.
function draw(e) {
var canvas = document.getElementById("imgCanvas");
var context = canvas.getContext("2d");
var rect = canvas.getBoundingClientRect();
var posx = e.clientX - rect.left;
var posy = e.clientY - rect.top;
context.fillStyle = "#000000";
context.beginPath();
context.arc(posx, posy, 50, 0, 2 * Math.PI);
context.fill();
}
This script works fine for me.

Categories

Resources