Drawing multiple polygons in js - javascript

I'm using this code, and it works with charm - It draws a polygon (with canvas) on a given picture, however I'm struggling to modify code, so that it would enable me to draw multiple polygons instead of just one.
I'm a noob to js and haven't found yet anything that might solve it, I'd appreciate any help/hint in some direction.
Code:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="main.css">
<script type="text/javascript" src="https://code.jquery.com/jquery-2.1.4.js"></script>
<script>
//radius of click around the first point to close the draw
var END_CLICK_RADIUS = 15;
//the max number of points of your polygon
var MAX_POINTS = 8;
var mouseX = 0;
var mouseY = 0;
var isStarted = false;
var points = null;
var canvas = null;
window.onload = function() {
background = document.getElementById('justanimage');
//initializing canvas and draw color
canvas = document.getElementById("canvas");
ctx = canvas.getContext("2d");
changeColor("blue");
image = new Image();
image.onload = function() {
ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
};
image.src = 'justanimage.gif';
canvas.addEventListener("click", function(e) {
var x = e.clientX-canvas.offsetLeft;
var y = e.clientY-canvas.offsetTop;
if(isStarted) {
//drawing the next line, and closing the polygon if needed
if(Math.abs(x - points[0].x) < END_CLICK_RADIUS && Math.abs(y - points[0].y) < END_CLICK_RADIUS) {
isStarted = false;
} else {
points[points.length] = new Point(x, y);
if(points.length >= MAX_POINTS) {
isStarted = false;
}
}
} else if(points == null) {
//opening the polygon
points = new Array();
points[0] = new Point(x, y);
isStarted = true;
}
}, false);
//we just save the location of the mouse
canvas.addEventListener("mousemove", function(e) {
mouseX = e.clientX - canvas.offsetLeft;
mouseY = e.clientY - canvas.offsetTop;
}, false);
//refresh time
setInterval("draw();", 5);
}
//object representing a point
function Point(x, y) {
this.x = x;
this.y = y;
}
//resets the application
function reset() {
isStarted = false;
points = null;
document.getElementById("coordinates").innerHTML = " ";
}
//displays coordinates of the the point list
function save() {
if(points == null) {
alert("No picture!");
} else {
var s = "";
for(var a in points) {
//inversing y axis by (canvas.height - points[a].y)
s += "(" + points[a].x + "," + (canvas.height - points[a].y) + ")\n";
}
document.getElementById("coordinates").innerHTML = s + '\n';
}
}
//draws the current shape
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.beginPath();
if(points != null && points.length > 0) {
ctx.moveTo(points[0].x, points[0].y);
for(i = 1 ; i < points.length ; i++) {
ctx.lineTo(points[i].x, points[i].y);
}
if(isStarted) {
ctx.lineTo(mouseX, mouseY);
} else {
ctx.lineTo(points[0].x, points[0].y);
}
}
ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
ctx.stroke();
}
</script>
</head>
<body>
<div id="outer">
<canvas id="canvas" width=300 height=300; ></canvas>
</div>
<p id="coordinates"> </p>
<input type="button" value="Save" onclick="save();" />
<input type="button" value="Reset" onclick="reset();" />
</body>
</html>

Basically this solution adds a new array polygons, which keeps all polygons. The points array is now included in the polygons.
var polygons = [];
window.onload = function () {
// ...
canvas.addEventListener("click", function (e) {
// ...
if (isStarted) {
//drawing the next line, and closing the polygon if needed
if (Math.abs(x - polygons[polygons.length - 1][0].x) < END_CLICK_RADIUS && Math.abs(y - polygons[polygons.length - 1][0].y) < END_CLICK_RADIUS) {
isStarted = false;
} else {
polygons[polygons.length - 1].push(new Point(x, y));
if (polygons[polygons.length - 1].length >= MAX_POINTS) {
isStarted = false;
}
}
} else {
//opening the polygon
polygons.push([new Point(x, y)]);
isStarted = true;
}
}, false);
// ...
}
function draw() {
ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
polygons.forEach(function (points, i) {
ctx.beginPath();
points.forEach(function (p, j) {
if (j) {
ctx.lineTo(p.x, p.y);
} else {
ctx.moveTo(p.x, p.y);
}
});
if (i + 1 === polygons.length && isStarted) { // just the last one
ctx.lineTo(mouseX, mouseY);
} else {
ctx.lineTo(points[0].x, points[0].y);
}
ctx.stroke();
});
}
(Another solution might be to save the image with the last polygon and use it again for the new polygon.)
Working example:
//radius of click around the first point to close the draw
var END_CLICK_RADIUS = 15;
//the max number of points of your polygon
var MAX_POINTS = 8;
var mouseX = 0;
var mouseY = 0;
var isStarted = false;
var polygons = [];
var canvas = null;
var ctx;
var image;
window.onload = function () {
var background = document.getElementById('justanimage');
//initializing canvas and draw color
canvas = document.getElementById("canvas");
ctx = canvas.getContext("2d");
//changeColor("blue"); // <-- is missing!
image = new Image();
image.onload = function () {
ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
};
image.src = 'http://lorempixel.com/10/10/';
canvas.addEventListener("click", function (e) {
var x = e.clientX - canvas.offsetLeft;
var y = e.clientY - canvas.offsetTop;
if (isStarted) {
//drawing the next line, and closing the polygon if needed
if (Math.abs(x - polygons[polygons.length - 1][0].x) < END_CLICK_RADIUS && Math.abs(y - polygons[polygons.length - 1][0].y) < END_CLICK_RADIUS) {
isStarted = false;
} else {
polygons[polygons.length - 1].push(new Point(x, y));
if (polygons[polygons.length - 1].length >= MAX_POINTS) {
isStarted = false;
}
}
} else {
//opening the polygon
polygons.push([new Point(x, y)]);
isStarted = true;
}
}, false);
//we just save the location of the mouse
canvas.addEventListener("mousemove", function (e) {
mouseX = e.clientX - canvas.offsetLeft;
mouseY = e.clientY - canvas.offsetTop;
}, false);
//refresh time
setInterval("draw();", 5);
}
//object representing a point
function Point(x, y) {
this.x = x;
this.y = y;
}
//resets the application
function reset() {
isStarted = false;
points = null;
document.getElementById("coordinates").innerHTML = " ";
}
//draws the current shape
function draw() {
ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
polygons.forEach(function (points, i) {
ctx.beginPath();
points.forEach(function (p, j) {
if (j) {
ctx.lineTo(p.x, p.y);
} else {
ctx.moveTo(p.x, p.y);
}
});
if (i + 1 === polygons.length && isStarted) { // just the last one
ctx.lineTo(mouseX, mouseY);
} else {
ctx.lineTo(points[0].x, points[0].y);
}
ctx.stroke();
});
}
<canvas id="canvas" width="500" height="500"></canvas>
<img id="justanimage" />

Related

How to draw parallelogram with draggable points

I have been studying JS for a few days, but I need to draw a parallelogram and allow user to change its angles by dragging one of its points. I took a code from a related question, and tried to change it (I know, it's a nightmare). But the 4th point doesn't work properly. I get this:
https://i.stack.imgur.com/PAjE6.png
How can I make the 4th point create a parallelogram?
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
var cw = canvas.width;
var ch = canvas.height;
var mouse = {};
var draggable = false;
context.lineWidth = 2;
context.strokeStyle = "blue";
var coordinates = [];
var isDone = false;
var clicks = 0;
canvas.addEventListener("mousedown", function(e) {
handleMouseDown(e);
});
function GetMassCenterAndFourthPoint(knownpoints) {
let point4X = knownpoints[2].x - knownpoints[1].x + knownpoints[0].x;
let point4Y = knownpoints[2].y - knownpoints[1].y + knownpoints[0].y;
coordinates.push({
x: point4X,
y: point4Y
});
}
function handleMouseDown(e) {
mouse = oMousePos(canvas, e);
//if isDone you can drag
if (isDone) {
for (index = 0; index < coordinates.length; index++) {
// you draw a small circle no stroke, no fill
context.beginPath();
context.arc(
coordinates[index].x,
coordinates[index].y,
5,
0,
2 * Math.PI
);
// if the mouse is inside the circle
if (context.isPointInPath(mouse.x, mouse.y)) {
// you can drag this point
// I'm using index + 1 because index == 0 is false
draggable = index + 1;
// if I have a point a can break the loop
break;
}
}
} else {
coordinates.push({
x: mouse.x,
y: mouse.y
});
drawPolygon();
clicks++;
if (clicks === 3) {
isDone = true;
}
}
}
function drawPolygon() {
context.clearRect(0, 0, cw, ch);
if (isDone) {
GetMassCenterAndFourthPoint(coordinates);
}
context.beginPath();
context.moveTo(coordinates[0].x, coordinates[0].y);
for (index = 1; index < coordinates.length; index++) {
context.lineTo(coordinates[index].x, coordinates[index].y);
}
context.closePath();
context.stroke();
// Additionaly I'm drawing a small circle around every point
// you can delete this.
for (index = 0; index < coordinates.length; index++) {
context.beginPath();
context.arc(coordinates[index].x, coordinates[index].y, 5, 0, 2 * Math.PI);
context.stroke();
}
}
canvas.addEventListener("mousemove", function(e) {
if (isDone) {
if (draggable) {
mouse = oMousePos(canvas, e);
// draggable - 1 is the index of the point in the coordinates array
coordinates[draggable - 1].x = mouse.x;
coordinates[draggable - 1].y = mouse.y;
drawPolygon();
}
}
});
canvas.addEventListener("mouseup", function(e) {
if (draggable) {
draggable = false;
}
});
// a function to detect the mouse position
function oMousePos(canvas, evt) {
var ClientRect = canvas.getBoundingClientRect();
return {
//objeto
x: Math.round(evt.clientX - ClientRect.left),
y: Math.round(evt.clientY - ClientRect.top)
};
}
canvas {
border: 1px solid black;
}
<canvas id="canvas" width="600" height="600"></canvas>
I also tried to draw my own parallelogram, but can't do it draggable
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
startX;
startY;
}
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
var cw = canvas.width;
var ch = canvas.height;
var mouse = {};
var draggable = false;
var points = [];
let isDone = false;
var clicks =0;
let click = false;
canvas.addEventListener("click", function(e) {
console.log(clicks);
clicks++;
if(!isDone){
const point = new Point(e.offsetX, e.offsetY);
points.push(point);
context.beginPath();
context.arc(point.x, point.y, 5, 0, 2 * Math.PI);
context.fillStyle = "red";
context.fill();
if(clicks===3){
isDone=true;
}
}
if(isDone){
GetMassCenterAndFourthPoint(points);
drawParallelogramAndCircle();
}
});
function GetMassCenterAndFourthPoint(knownpoints){
const point4X = knownpoints[2].x-knownpoints[1].x+knownpoints[0].x;
const point4Y = knownpoints[2].y-knownpoints[1].y+knownpoints[0].y;
context.beginPath();
context.arc(point4X, point4Y, 5, 0, 2 * Math.PI);
context.fillStyle = "red";
context.fill();
points.push(new Point(point4X, point4Y));
const massCenterX = (knownpoints[1].x+knownpoints[3].x)/2;
const massCenterY = (knownpoints[1].y+knownpoints[3].y)/2;
points.push(new Point(massCenterX, massCenterY));
}
function drawParallelogramAndCircle(){
context.beginPath();
context.moveTo(points[0].x, points[0].y);
for(let i=1;i<points.length-1;i++){
context.lineTo(points[i].x, points[i].y);
if(i===3){
context.lineTo(points[0].x, points[0].y);
}
}
context.strokeStyle = "blue";
context.closePath();
context.stroke();
// find square. Here will be the logic to calculate square
let square = 250;
context.beginPath();
context.arc(points[4].x, points[4].y, 30, 0, 2 * Math.PI);
context.strokeStyle = "yellow";
context.closePath();
context.stroke();
}
canvas {
border: 1px solid black;
}
<canvas id="canvas" width="600" height="600"></canvas>

How to draw a smooth continuous line with mouse using html canvas and javascript

I'm attempting to create a simple draw/paint programme using html5 canvas and plain javascript. I've got it working ok, but when drawing and moving the mouse too fast the line disconnects and I just end up with a line of dots - how can I make this a smooth continuous line?
Advice would be much appreciated! I'm quite new to JS so code examples would be really useful, thanks in advance.
Current JS is:
var canvas, ctx
var mouseX, mouseY, mouseDown = 0
function draw(ctx,x,y,size) {
ctx.fillStyle = "#000000"
ctx.beginPath()
ctx.arc(x, y, size, 0, Math.PI*2, true)
ctx.closePath()
ctx.fill()
}
function clearCanvas(canvas,ctx) {
ctx.clearRect(0, 0, canvas.width, canvas.height)
}
function onMouseDown() {
mouseDown = 1
draw(ctx, mouseX, mouseY, 2)
}
function onMouseUp() {
mouseDown = 0
}
function onMouseMove(e) {
getMousePos(e)
if (mouseDown == 1) {
draw(ctx, mouseX, mouseY, 2)
}
}
function getMousePos(e) {
if (!e)
var e = event
if (e.offsetX) {
mouseX = e.offsetX
mouseY = e.offsetY
}
else if (e.layerX) {
mouseX = e.layerX
mouseY = e.layerY
}
}
function init() {
canvas = document.getElementById('sketchpad')
ctx = canvas.getContext('2d')
canvas.addEventListener('mousedown', onMouseDown, false)
canvas.addEventListener('mousemove', onMouseMove, false)
window.addEventListener('mouseup', onMouseUp, false)
}
init();
<canvas id="sketchpad" width="500" height="500"></canvas>
Drawing a smooth curve with the mouse.
Sadly it is not that easy if you wish to stay true to the artists intended line.
It involves recording the whole mouse stroke. When the stroke is complete, reduce the number of points to the detail limit (set by artist) then apply a bezier smoothing function on the remaining points.
It can be done as the stroke is drawn but for some devices this can become too much if the line becomes very long. As the line detail reduction looks at all points when showing the smoothed line live some people dont like the way it slightly changes as the line gets longer.
Demo
The code below demonstrates a solution I have found useful.
Use the left button to draw with smoothing done one button release.
Use the right button to draw with live smoothing (blue line).
Middle mouse button click to clear.
Use the two sliders at the top to set the amount of smoothing, and the amount of detail. Left click to drag out a stroke, the raw line is shown. When the mouse is released the line is then simplified, smoothed, and added to the background image.
var canvas = document.getElementById("canV");
var ctx = canvas.getContext("2d");
// mouse stuff
var mouse = {
x:0,
y:0,
buttonLastRaw:0, // user modified value
buttonRaw:0,
buttons:[1,2,4,6,5,3], // masks for setting and clearing button raw bits;
};
function mouseMove(event){
mouse.x = event.offsetX; mouse.y = event.offsetY;
if(mouse.x === undefined){ mouse.x = event.clientX; mouse.y = event.clientY;}
if(event.type === "mousedown"){ mouse.buttonRaw |= mouse.buttons[event.which-1];
}else if(event.type === "mouseup"){mouse.buttonRaw &= mouse.buttons[event.which+2];
}else if(event.type === "mouseout"){ mouse.buttonRaw = 0; mouse.over = false;
}else if(event.type === "mouseover"){ mouse.over = true; }
event.preventDefault();
}
canvas.addEventListener('mousemove',mouseMove);
canvas.addEventListener('mousedown',mouseMove);
canvas.addEventListener('mouseup' ,mouseMove);
canvas.addEventListener('mouseout' ,mouseMove);
canvas.addEventListener('mouseover' ,mouseMove);
canvas.addEventListener("contextmenu", function(e){ e.preventDefault();}, false);
// Line simplification based on
// the Ramer–Douglas–Peucker algorithm
// referance https://en.wikipedia.org/wiki/Ramer%E2%80%93Douglas%E2%80%93Peucker_algorithm
// points are and array of arrays consisting of [[x,y],[x,y],...,[x,y]]
// length is in pixels and is the square of the actual distance.
// returns array of points of the same form as the input argument points.
var simplifyLineRDP = function(points, length) {
var simplify = function(start, end) { // recursize simplifies points from start to end
var maxDist, index, i, xx , yy, dx, dy, ddx, ddy, p1, p2, p, t, dist, dist1;
p1 = points[start];
p2 = points[end];
xx = p1[0];
yy = p1[1];
ddx = p2[0] - xx;
ddy = p2[1] - yy;
dist1 = (ddx * ddx + ddy * ddy);
maxDist = length;
for (var i = start + 1; i < end; i++) {
p = points[i];
if (ddx !== 0 || ddy !== 0) {
t = ((p[0] - xx) * ddx + (p[1] - yy) * ddy) / dist1;
if (t > 1) {
dx = p[0] - p2[0];
dy = p[1] - p2[1];
} else
if (t > 0) {
dx = p[0] - (xx + ddx * t);
dy = p[1] - (yy + ddy * t);
} else {
dx = p[0] - xx;
dy = p[1] - yy;
}
}else{
dx = p[0] - xx;
dy = p[1] - yy;
}
dist = dx * dx + dy * dy
if (dist > maxDist) {
index = i;
maxDist = dist;
}
}
if (maxDist > length) { // continue simplification while maxDist > length
if (index - start > 1){
simplify(start, index);
}
newLine.push(points[index]);
if (end - index > 1){
simplify(index, end);
}
}
}
var end = points.length - 1;
var newLine = [points[0]];
simplify(0, end);
newLine.push(points[end]);
return newLine;
}
// This is my own smoothing method
// It creates a set of bezier control points either 2nd order or third order
// bezier curves.
// points: list of points
// cornerThres: when to smooth corners and represents the angle between to lines.
// When the angle is smaller than the cornerThres then smooth.
// match: if true then the control points will be balanced.
// Function will make a copy of the points
var smoothLine = function(points,cornerThres,match){ // adds bezier control points at points if lines have angle less than thres
var p1, p2, p3, dist1, dist2, x, y, endP, len, angle, i, newPoints, aLen, closed, bal, cont1, nx1, nx2, ny1, ny2, np;
function dot(x, y, xx, yy) { // get do product
// dist1,dist2,nx1,nx2,ny1,ny2 are the length and normals and used outside function
// normalise both vectors
dist1 = Math.sqrt(x * x + y * y); // get length
if (dist1 > 0) { // normalise
nx1 = x / dist1 ;
ny1 = y / dist1 ;
}else {
nx1 = 1; // need to have something so this will do as good as anything
ny1 = 0;
}
dist2 = Math.sqrt(xx * xx + yy * yy);
if (dist2 > 0) {
nx2 = xx / dist2;
ny2 = yy / dist2;
}else {
nx2 = 1;
ny2 = 0;
}
return Math.acos(nx1 * nx2 + ny1 * ny2 ); // dot product
}
newPoints = []; // array for new points
aLen = points.length;
if(aLen <= 2){ // nothing to if line too short
for(i = 0; i < aLen; i ++){ // ensure that the points are copied
newPoints.push([points[i][0],points[i][1]]);
}
return newPoints;
}
p1 = points[0];
endP =points[aLen-1];
i = 0; // start from second poitn if line not closed
closed = false;
len = Math.hypot(p1[0]- endP[0], p1[1]-endP[1]);
if(len < Math.SQRT2){ // end points are the same. Join them in coordinate space
endP = p1;
i = 0; // start from first point if line closed
p1 = points[aLen-2];
closed = true;
}
newPoints.push([points[i][0],points[i][1]])
for(; i < aLen-1; i++){
p2 = points[i];
p3 = points[i + 1];
angle = Math.abs(dot(p2[0] - p1[0], p2[1] - p1[1], p3[0] - p2[0], p3[1] - p2[1]));
if(dist1 !== 0){ // dist1 and dist2 come from dot function
if( angle < cornerThres*3.14){ // bend it if angle between lines is small
if(match){
dist1 = Math.min(dist1,dist2);
dist2 = dist1;
}
// use the two normalized vectors along the lines to create the tangent vector
x = (nx1 + nx2) / 2;
y = (ny1 + ny2) / 2;
len = Math.sqrt(x * x + y * y); // normalise the tangent
if(len === 0){
newPoints.push([p2[0],p2[1]]);
}else{
x /= len;
y /= len;
if(newPoints.length > 0){
var np = newPoints[newPoints.length-1];
np.push(p2[0]-x*dist1*0.25);
np.push(p2[1]-y*dist1*0.25);
}
newPoints.push([ // create the new point with the new bezier control points.
p2[0],
p2[1],
p2[0]+x*dist2*0.25,
p2[1]+y*dist2*0.25
]);
}
}else{
newPoints.push([p2[0],p2[1]]);
}
}
p1 = p2;
}
if(closed){ // if closed then copy first point to last.
p1 = [];
for(i = 0; i < newPoints[0].length; i++){
p1.push(newPoints[0][i]);
}
newPoints.push(p1);
}else{
newPoints.push([points[points.length-1][0],points[points.length-1][1]]);
}
return newPoints;
}
// creates a drawable image
var createImage = function(w,h){
var image = document.createElement("canvas");
image.width = w;
image.height =h;
image.ctx = image.getContext("2d");
return image;
}
// draws the smoothed line with bezier control points.
var drawSmoothedLine = function(line){
var i,p;
ctx.beginPath()
ctx.moveTo(line[0][0],line[0][1])
for(i = 0; i < line.length-1; i++){
p = line[i];
p1 = line[i+1]
if(p.length === 2){ // linear
ctx.lineTo(p[0],p[1])
}else
if(p.length === 4){ // bezier 2nd order
ctx.quadraticCurveTo(p[2],p[3],p1[0],p1[1]);
}else{ // bezier 3rd order
ctx.bezierCurveTo(p[2],p[3],p[4],p[5],p1[0],p1[1]);
}
}
if(p.length === 2){
ctx.lineTo(p1[0],p1[1])
}
ctx.stroke();
}
// smoothing settings
var liveSmooth;
var lineSmooth = {};
lineSmooth.lengthMin = 8; // square of the pixel length
lineSmooth.angle = 0.8; // angle threshold
lineSmooth.match = false; // not working.
// back buffer to save the canvas allowing the new line to be erased
var backBuffer = createImage(canvas.width,canvas.height);
var currentLine = [];
mouse.lastButtonRaw = 0; // add mouse last incase not there
ctx.lineWidth = 3;
ctx.lineJoin = "round";
ctx.lineCap = "round";
ctx.strokeStyle = "black";
ctx.clearRect(0,0,canvas.width,canvas.height);
var drawing = false; // if drawing
var input = false; // if menu input
var smoothIt = false; // flag to allow feedback that smoothing is happening as it takes some time.
function draw(){
// if not drawing test for menu interaction and draw the menus
if(!drawing){
if(mouse.x < 203 && mouse.y < 24){
if(mouse.y < 13){
if(mouse.buttonRaw === 1){
ctx.clearRect(3,3,200,10);
lineSmooth.angle = (mouse.x-3)/200;
input = true;
}
}else
if(mouse.buttonRaw === 1){
ctx.clearRect(3,14,200,10);
lineSmooth.lengthMin = (mouse.x-3)/10;
input = true;
}
canvas.style.cursor = "pointer";
}else{
canvas.style.cursor = "crosshair";
}
if(mouse.buttonRaw === 0 && input){
input = false;
mouse.lastButtonRaw = 0;
}
ctx.lineWidth = 0.5;
ctx.fillStyle = "red";
ctx.clearRect(3,3,200,10);
ctx.clearRect(3,14,200,10);
ctx.fillRect(3,3,lineSmooth.angle*200,10);
ctx.fillRect(3,14,lineSmooth.lengthMin*10,10);
ctx.textAlign = "left";
ctx.textBaseline = "top";
ctx.fillStyle = "#000"
ctx.strokeRect(3,3,200,10);
ctx.fillText("Smooth "+(lineSmooth.angle * (180 / Math.PI)).toFixed(0)+"deg",5,2)
ctx.strokeRect(3,14,200,10);
ctx.fillText("Detail "+lineSmooth.lengthMin.toFixed(0) + "pixels",5,13);
}else{
canvas.style.cursor = "crosshair";
}
if(!input){
ctx.lineWidth = 3;
if(mouse.buttonRaw === 4 && mouse.lastButtonRaw === 0){
currentLine = [];
drawing = true;
backBuffer.ctx.clearRect(0,0,canvas.width,canvas.height);
backBuffer.ctx.drawImage(canvas,0,0);
currentLine.push([mouse.x,mouse.y])
}else
if(mouse.buttonRaw === 4){
var lp = currentLine[currentLine.length-1]; // get last point
// dont record point if no movement
if(mouse.x !== lp[0] || mouse.y !== lp[1] ){
currentLine.push([mouse.x,mouse.y]);
ctx.beginPath();
ctx.moveTo(lp[0],lp[1])
ctx.lineTo(mouse.x,mouse.y);
ctx.stroke();
liveSmooth = smoothLine(
simplifyLineRDP(
currentLine,
lineSmooth.lengthMin
),
lineSmooth.angle,
lineSmooth.match
);
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.drawImage(backBuffer,0,0);
ctx.strokeStyle = "Blue";
drawSmoothedLine(liveSmooth );
ctx.strokeStyle = "black";
}
}else
if(mouse.buttonRaw === 0 && mouse.lastButtonRaw === 4){
ctx.textAlign = "center"
ctx.fillStyle = "red"
ctx.fillText("Smoothing...",canvas.width/2,canvas.height/5);
smoothIt = true;
}else
if(smoothIt){
smoothIt = false;
var newLine = smoothLine(
simplifyLineRDP(
currentLine,
lineSmooth.lengthMin
),
lineSmooth.angle,
lineSmooth.match
);
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.drawImage(backBuffer,0,0);
drawSmoothedLine(newLine);
drawing = false;
}
if(mouse.buttonRaw === 1 && mouse.lastButtonRaw === 0){
currentLine = [];
drawing = true;
backBuffer.ctx.clearRect(0,0,canvas.width,canvas.height);
backBuffer.ctx.drawImage(canvas,0,0);
currentLine.push([mouse.x,mouse.y])
}else
if(mouse.buttonRaw === 1){
var lp = currentLine[currentLine.length-1]; // get last point
// dont record point if no movement
if(mouse.x !== lp[0] || mouse.y !== lp[1] ){
currentLine.push([mouse.x,mouse.y]);
ctx.beginPath();
ctx.moveTo(lp[0],lp[1])
ctx.lineTo(mouse.x,mouse.y);
ctx.stroke();
}
}else
if(mouse.buttonRaw === 0 && mouse.lastButtonRaw === 1){
ctx.textAlign = "center"
ctx.fillStyle = "red"
ctx.fillText("Smoothing...",canvas.width/2,canvas.height/5);
smoothIt = true;
}else
if(smoothIt){
smoothIt = false;
var newLine = smoothLine(
simplifyLineRDP(
currentLine,
lineSmooth.lengthMin
),
lineSmooth.angle,
lineSmooth.match
);
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.drawImage(backBuffer,0,0);
drawSmoothedLine(newLine);
drawing = false;
}
}
// middle button clear
if(mouse.buttonRaw === 2){
ctx.clearRect(0,0,canvas.width,canvas.height);
}
mouse.lastButtonRaw = mouse.buttonRaw;
requestAnimationFrame(draw);
}
draw();
.canC { width:1000px; height:500px; border:1px black solid;}
<canvas class="canC" id="canV" width=1000 height=500></canvas>
You could save the last position and draw a line between the last point and the actual point.
if (lastX && lastY && (x !== lastX || y !== lastY)) {
ctx.fillStyle = "#000000";
ctx.lineWidth = 2 * size;
ctx.beginPath();
ctx.moveTo(lastX, lastY);
ctx.lineTo(x, y);
ctx.stroke();
// ...
lastX = x;
lastY = y;
}
On mouseup event set the two variables to zero.
var canvas, ctx
var mouseX, mouseY, mouseDown = 0,
lastX, lastY;
function draw(ctx,x,y,size) {
if (lastX && lastY && (x !== lastX || y !== lastY)) {
ctx.fillStyle = "#000000";
ctx.lineWidth = 2 * size;
ctx.beginPath();
ctx.moveTo(lastX, lastY);
ctx.lineTo(x, y);
ctx.stroke();
}
ctx.fillStyle = "#000000";
ctx.beginPath();
ctx.arc(x, y, size, 0, Math.PI*2, true);
ctx.closePath();
ctx.fill();
lastX = x;
lastY = y;
}
function clearCanvas(canvas,ctx) {
ctx.clearRect(0, 0, canvas.width, canvas.height)
}
function onMouseDown() {
mouseDown = 1
draw(ctx, mouseX, mouseY, 2)
}
function onMouseUp() {
mouseDown = 0;
lastX = 0;
lastY = 0;
}
function onMouseMove(e) {
getMousePos(e)
if (mouseDown == 1) {
draw(ctx, mouseX, mouseY, 2)
}
}
function getMousePos(e) {
if (!e)
var e = event
if (e.offsetX) {
mouseX = e.offsetX
mouseY = e.offsetY
}
else if (e.layerX) {
mouseX = e.layerX
mouseY = e.layerY
}
}
function init() {
canvas = document.getElementById('sketchpad')
ctx = canvas.getContext('2d')
canvas.addEventListener('mousedown', onMouseDown, false)
canvas.addEventListener('mousemove', onMouseMove, false)
window.addEventListener('mouseup', onMouseUp, false)
}
init();
<canvas id="sketchpad" width="600" height="300"></canvas>
Good question! And I recommend you a site https://developer.mozilla.org/zh-CN/docs/Web/API/Canvas_API to learn more canvas API.
I think using lineTo is better than arc.So I hope this code will help you.
var canvas, ctx;
var mouseDown = 0, lastX, lastY;
function draw(ctx,x,y) {
ctx.beginPath();
ctx.moveTo(lastX,lastY);
ctx.lineTo(x,y);
ctx.closePath();
ctx.stroke();
}
function clearCanvas(canvas,ctx) {
ctx.clearRect(0, 0, canvas.width, canvas.height)
}
function onMouseDown(e) {
var xy = getMousePos(e);
lastX = xy.mouseX;
lastY = xy.mouseY;
mouseDown = 1;
}
function onMouseUp() {
mouseDown = 0
}
function onMouseMove(e) {
if (mouseDown == 1) {
var xy = getMousePos(e);
draw(ctx, xy.mouseX, xy.mouseY);
lastX = xy.mouseX, lastY = xy.mouseY;
}
}
function getMousePos(e) {
var o = {};
if (!e)
var e = event
if (e.offsetX) {
o.mouseX = e.offsetX
o.mouseY = e.offsetY
}
else if (e.layerX) {
o.mouseX = e.layerX
o.mouseY = e.layerY
}
return o;
}
function init() {
canvas = document.getElementById('sketchpad')
ctx = canvas.getContext('2d')
canvas.addEventListener('mousedown', onMouseDown, false)
canvas.addEventListener('mousemove', onMouseMove, false)
canvas.addEventListener('mouseup', onMouseUp, false)
}
init();

Draw polygons of fixed sides with mouse on canvas

I am trying to draw polygons(lets say 4 sided) on a canvas using mouse click and move events.
Click on canvas the moveTo(this point).
Now move the cursor a lineTo(the current point) but not intermediate point. Line should keep moving with mousemove and should be draw to the canvas only once clicked.
After fourth click(or any x) the polygon should closepath();
var pressed = false;
function myfunc1(e){
context.beginPath();
context.arc(e.clientX, e.clientY, radius, 0, Math.PI*2);
context.fill();
context.beginPath();
context.moveTo(e.clientX,e.clientY);
pressed = true;
}
function myfunc2(e){
if(pressed ===true){
context.lineTo(e.clientX,e.clientY);
context.stroke();
}
}
canvas.addEventListener('click',myfunc1);
canvas.addEventListener('mousemove',myfunc2);
I wrote this, but i don't want the intermediate lines
What you need is a stack. Don't think of drawing lines. Think of storing all your points of click in an array. And when you have clicked 4 times, draw the polygon (assuming that is what you want). Something like this:
var stack = [];
myfunc1(e){
stack.push(e.clientX, e.clientY);
if(stack.length == 4)
actuallyDraw();
}
var actuallyDraw(){
//take the 4 points in stack and draw the polygon
//clearing the stack for the next polygon
stack.length = 0;
}
canvas.addEventListener('click', myfunc1);
Use below code it will help you to solve your problem.
Click to assign polygon vertices point
<button id=done>Click when done assigning points</button>
<canvas id="canvas" width=450 height=450></canvas>
var canvas=document.getElementById("canvas");
var context=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(); }
context.lineWidth=2;
context.strokeStyle='blue';
var coordinates = [];
var isDone=false;
$('#done').click(function(){
isDone=true;
});
$("#canvas").mousedown(function(e){handleMouseDown(e);});
function handleMouseDown(e){
if(isDone || coordinates.length>10){return;}
// tell the browser we're handling this event
e.preventDefault();
e.stopPropagation();
mouseX=parseInt(e.clientX-offsetX);
mouseY=parseInt(e.clientY-offsetY);
coordinates.push({x:mouseX,y:mouseY});
drawPolygon();
}
function drawPolygon(){
context.clearRect(0,0,cw,ch);
context.beginPath();
context.moveTo(coordinates[0].x, coordinates[0].y);
for(index=1; index<coordinates.length;index++) {
context.lineTo(coordinates[index].x, coordinates[index].y);
}
context.closePath();
context.stroke();
}
I created an array(cords[]) which holds the coordinates of the polygon i am drawing and push them to another array (polygons[]) if the current polygon is completed. Then i can clear the canvas when required and redraw the polygons from polygon[]
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var img = document.getElementById("myimg");
ctx.drawImage(img, 0, 0);
var canvasOffset = $("#canvas").offset();
var offsetX = canvasOffset.left;
var offsetY = canvasOffset.top;
var polygons = [];
var cords = [];
var start = false;
var control = false;
var clicks = 0;
ctx.strokeStyle = "orange";
ctx.lineWidth = 1;
$("#canvas").mousedown(function(e) {
handleMouseDown(e);
});
$("#canvas").mousemove(function(e) {
handleMouseMove(e);
});
function handleMouseDown(e) {
start = false;
clicks = clicks + 1;
var mouseX = parseInt(e.clientX - offsetX);
var mouseY = parseInt(e.clientY - offsetY);
cords.push([mouseX, mouseY]);
console.log(cords);
clearanddraw();
if (clicks % 4 === 0) {
return;
}
start = true;
}
function handleMouseMove(e) {
if (!start) {
return;
}
canvasclear();
var mouseX = parseInt(e.clientX - offsetX);
var mouseY = parseInt(e.clientY - offsetY);
ctx.beginPath();
ctx.moveTo(cords[clicks - 1][0], cords[clicks - 1][1]);
ctx.lineTo(mouseX, mouseY);
ctx.stroke();
}
function canvasclear() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(myimg, 0, 0);
drawOtherPol();
ctx.beginPath();
ctx.moveTo(cords[0][0], cords[0][1]);
for (var i = 0; i < clicks - 1; i++) {
ctx.lineTo(cords[i + 1][0], cords[i + 1][1]);
//alert("redrwan");
}
ctx.stroke();
return;
}
function clearanddraw() {
if (clicks > 1) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(myimg, 0, 0);
drawOtherPol();
ctx.beginPath();
ctx.moveTo(cords[0][0], cords[0][1]);
for (var i = 0; i < clicks - 1; i++) {
ctx.lineTo(cords[i + 1][0], cords[i + 1][1]);
}
if (clicks < 4) {
ctx.stroke();
}
if (clicks === 4) {
ctx.closePath();
ctx.stroke();
savepolygon();
cords = [];
clicks = 0;
return;
}
}
start = true;
}
function savepolygon() {
polygons.push(cords);
console.log(polygons);
return
}
function drawOtherPol() {
if (polygons.length === 0) {
return;
} else {
for (var i = 0; i < polygons.length; i++) {
ctx.beginPath();
ctx.moveTo(polygons[i][0][0], polygons[i][0][1]);
ctx.lineTo(polygons[i][1][0], polygons[i][1][1]);
ctx.lineTo(polygons[i][2][0], polygons[i][2][1]);
ctx.lineTo(polygons[i][3][0], polygons[i][3][1]);
ctx.closePath();
ctx.stroke();
}
return;
}
}

HTML5 canvas and php on Chrome not working

I would love to create a fiddle for this to show but i'm using php and it won't let me use php in those so i'm hoping someone will still know whats going on!
I have a javascript that works completely fine on it's own. It is a HTML click and drag canvas. The click and drag is constrained to a circle and draws the image to the canvas when you click a button that is next to the canvas. This button calls a method that draws the image onto the canvas and makes it click and draggable. I have tested this by itself and it works beautifully. When I add a simple line of php code my click and drag canvas quits moving the image. When you click the button to draw the image on, that works, but then you can't move the image.
I am beyond confused because the php that i am using has nothing to do with what is going on in the canvas. Here is the code:
it's also important to point out that this code works fine in safari but doesn't work at all in chrome so i know it has something to do with chrome i just don't understand what the problem is.
My question is mainly, is there a way that safari loads versus chrome that would affect running javascript and php on the same page since it works fine in one browser and not the other. I just added the code so people would know what I am referring to.
Here is the PHP
<dl class="header">
<?php
$name = $_GET['id'];
if ($name=="bracelet") {
echo "<li>Design x!</li>";
}
elseif ($name=="purse") {
echo "<li>Design y!</li>";
}
elseif ($name=="ring") {
echo "<li>Design z!</li>";
}
?>
</dl>
Here is the full code
<HTML>
<HEAD>
<style>
#canvas {
border:1px solid red;
}
</style>
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="styles.css">
</HEAD>
<BODY>
<dl class="header">
<?php
$name = $_GET['id'];
if ($name=="bracelet") {
echo "<li>Design x!</li>";
}
elseif ($name=="purse") {
echo "<li>Design y!</li>";
}
elseif ($name=="ring") {
echo "<li>Design z!</li>";
}
?>
</dl>
<h5>Add Images and Canvases with the buttons<br>
Click to select which image to move.<br>
Then move the mouse to desired drop location<br>
and click again to drop the image there.</h5>
<canvas id="canvas" width=300 height=300></canvas>
<input type="image" src="http://s25.postimg.org/tovdg674b/crystal_003.png" id="button1" width="35" height="20"></input>
<input type="image" src="http://s25.postimg.org/ph0l7f5or/crystal_004.png" id="button2" width="35" height="20"></input>
<input type="image" src="http://s25.postimg.org/60fvkwakr/crystal_005.png" id="button3" width="35" height="20"></input>
<input type="image" src="http://s25.postimg.org/fz5fl49e3/crystal_006.png" id="button4" width="35" height="20"></input>
<button id="save">save</button>
<br>
<script>
// canvas stuff
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var centerX = canvas.width / 2;
var centerY = canvas.height / 2;
var radius = 50;
var contexts = [];
var points = [];
// image stuff
var states = [];
var img = new Image();
img.onload = function () {}
img.src = "http://s25.postimg.org/5qs46n4az/crystal_009.png";
setUpCanvas();
setUpPoints();
function setUpCanvas() {
contexts.push(canvas.getContext("2d"));
// link the new canvas to its context in the contexts[] array
canvas.contextIndex = contexts.length;
// wire up the click handler
canvas.onclick = function (e) {
handleClick(e, this.contextIndex);
};
// wire up the mousemove handler
canvas.onmousemove = function (e) {
handleMousemove(e, this.contextIndex);
};
canvas.addEventListener('dblclick', function() {
removeState(this.contextIndex);
});
}
function setUpPoints() {
//points that make up a circle circumference to an array
points = [];
for (var degree=0; degree<360; degree++) {
var radians = degree * Math.PI/180;
var TO_RADIANS = Math.PI/180;
var xpoint = centerX + radius * Math.cos(radians);
var ypoint = centerY + radius * Math.sin(radians);
points.push({
x: xpoint,
y: ypoint
});
}
ctx.beginPath();
ctx.moveTo(points[0].x + 4, points[0].y + 4)
//draws the thin line on the canvas
for (var i = 1; i < points.length; i++) {
var pt = points[i];
ctx.lineTo(pt.x + 4, pt.y + 4);
}
ctx.stroke(); //end of drawing the thin line
}
function addCircle() {
ctx.beginPath();
ctx.moveTo(points[0].x + 4, points[0].y + 4)
//draws the thin line on the canvas
for (var i = 1; i < points.length; i++) {
var pt = points[i];
ctx.lineTo(pt.x + 4, pt.y + 4);
}
ctx.stroke(); //end of drawing the thin line
}
function clearAll() {
//Clear all canvases
for (var i = 0; i < contexts.length; i++) {
var context = contexts[i];
context.clearRect(0, 0, canvas.width, canvas.height);
}
}
function handleClick(e, contextIndex) {
e.stopPropagation();
var mouseX = parseInt(e.clientX - e.target.offsetLeft);
var mouseY = parseInt(e.clientY - e.target.offsetTop);
for (var i = 0; i < states.length; i++) {
var state = states[i];
console.log(state);
if (state.dragging) {
state.dragging = false;
state.draw();
continue;
}
if (state.contextIndex == contextIndex && mouseX > state.x && mouseX < state.x + state.width && mouseY > state.y && mouseY < state.y + state.height) {
state.dragging = true;
state.offsetX = mouseX - state.x;
state.offsetY = mouseY - state.y;
state.contextIndex = contextIndex;
}
state.draw();
}
}
function handleMousemove(e, contextIndex) {
e.stopPropagation();
var mouseX = parseInt(e.clientX - e.target.offsetLeft);
var mouseY = parseInt(e.clientY - e.target.offsetTop);
clearAll();
addCircle();
var minDistance = 1000;
var minPoint = -1;
for (var i = 0; i < states.length; i++) {
var state = states[i];
if (state.dragging) {
for (var i = 0; i < points.length; i++) {
var pt = points[i];
var dx = mouseX - pt.x;
var dy = mouseY - pt.y;
if ((dx > 0 && dx>120)) {
state.x = mouseX - state.offsetX;
state.y = mouseY - state.offsetY;
state.contextIndex = contextIndex;
} else if ((dx < 0 && dx < -120)) {
state.x = mouseX - state.offsetX;
state.y = mouseY - state.offsetY;
state.contextIndex = contextIndex;
}
else {
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < minDistance) {
minDistance = distance;
//points in relation to the constrained line (where it will be drawn to)
//reset state.x and state.y to closest point on the line
state.x = pt.x - img.width / 2;
state.y = pt.y - img.height / 2;
state.contextIndex = contextIndex;
}
}
}
}
state.draw();
}
}
function removeState(contextIndex) {
for (var i = 0; i < states.length; i++) {
var state = states[i];
state.remove();
}
}
function addState(image) {
var ptxy = points[1];
state = {}
state.dragging = false;
state.contextIndex = 1;
state.image = image;
state.x = ptxy.x - image.width / 2;
state.y = ptxy.y - image.height / 2;
state.width = image.width;
state.height = image.height;
state.offsetX = 0;
state.offsetY = 0;
state.draw = function () {
var context = contexts[this.contextIndex - 1];
if (this.dragging) {
context.strokeStyle = 'black';
context.strokeRect(this.x, this.y, this.width + 2, this.height + 2)
}
context.drawImage(this.image, this.x, this.y);
}
state.draw();
return (state);
}
function save() {
// var data = ctx.getImageData(0, 0, canvas.width, canvas.height);
}
$("#button1").click(function () {
states.push(addState(img));
});
$("#button2").click(function () {
states.push(addState(img));
});
$("#button3").click(function () {
states.push(addState(img));
});
$("#button4").click(function () {
states.push(addState(img));
});
$("#save").click(function () {
save();
});
</script>
</BODY>
</HTML>
Anyone curious and wanting to know the answer of how i solved this here you go. I am new to HTML5 canvas and how it works. After a lot of trial and error I found out that the canvas offset was wrong once the canvas changed from the top of the screen to somewhere else. It was as simple as that....

how to remove a unconnected points when i mouseout from canvas

i need to remove unconnected points when i mouseout from canvas. I just draw lines when mousemove using moveTo and LineTo. when mouseout from canvas have to omit the unconnected points.
Here is code for jquery:
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/jquery.js"></script>
<script type="text/javascript">
$(function() {
var canvas = $('#canvas');
var context = canvas.get(0).getContext("2d");
var clicked = false;
var b=0;
var storedLines = [];
var storedLine = {};
var mouse = {
x: -1,
y: -1
}
var parentOffset = $('#canvas').offset();
canvas.click(function(e) {
if (b==1)
{
$(this).unbind(e);
}
else
{
clicked = true;
mouse.x = e.pageX - parentOffset.left;
mouse.y = e.pageY - parentOffset.top;
context.moveTo(mouse.x, mouse.y);
if (clicked) {
storedLines.push({
startX: storedLine.startX,
startY: storedLine.startY,
endX: mouse.x,
endY: mouse.y
});
}
storedLine.startX = mouse.x;
storedLine.startY = mouse.y;
$(this).mousemove(function(k) {
context.clearRect(0, 0, 960, 500);
context.beginPath();
context.strokeStyle = "blue";
for (var i = 0; i < storedLines.length; i++) {
var v = storedLines[i];
context.moveTo(v.startX, v.startY);
context.lineTo(v.endX, v.endY);
context.stroke();
}
context.moveTo(mouse.x, mouse.y);
context.lineTo(k.pageX - parentOffset.left, k.pageY - parentOffset.top);
context.stroke();
context.closePath();
});
}
});
$('#canvas').mouseout(function(e){
$(this).unbind("mousemove");
b=1;
});
});
HTML code:
<html>
<body>
<canvas id="canvas" width=600 height=600 ></canvas>
</body>
</html>
First thing to do is to clarify the code : Have one part that deals only with the mouse, and another part that deals only with the lines.
This way you will have a much better view on what will happen on each event.
I started a bit to clarify the code, you should even make a class handling lines (which will be very useful if you handle several of them).
jsbin is here : http://jsbin.com/eseTODo/2/edit?js,output
var canvas = $('#canvas');
var context = canvas.get(0).getContext("2d");
// -----------------------------------------
// Mouse
var clicked = false;
var onCanvas = false;
var mouse = {
x: -1,
y: -1
}
var parentOffset = $('#canvas').offset();
canvas.mousedown(function (e) {
clicked = true;
if (!onCanvas) return;
mouse.x = e.pageX - parentOffset.left;
mouse.y = e.pageY - parentOffset.top;
addPoint(mouse.x, mouse.y);
clearScreen();
drawLines();
});
canvas.mouseup(function (e) {
clicked = false;
if (!onCanvas) return;
});
canvas.mousemove(function (e) {
if (!onCanvas) return;
clearScreen();
drawLines();
drawPendingLine(e.pageX - parentOffset.left,
e.pageY - parentOffset.top);
});
canvas.mouseout(function (e) {
onCanvas = false;
clearScreen();
drawLines();
clearLines();
});
canvas.mouseenter(function (e) {
onCanvas = true;
});
// -----------------------------------------
// Lines
var storedLines = [];
var storedLine = {};
var startedALine = false;
function clearLines() {
storedLines.length = 0;
startedALine = false;
}
function addPoint(x, y) {
if (startedALine) {
storedLines.push({
startX: storedLine.startX,
startY: storedLine.startY,
endX: x,
endY: y
});
}
startedALine = true;
storedLine.startX = x;
storedLine.startY = y
}
function drawLines() {
context.strokeStyle = "blue";
if (!startedALine) return;
if (!storedLines.length) return;
for (var i = 0; i < storedLines.length; i++) {
var v = storedLines[i];
context.beginPath();
context.moveTo(v.startX, v.startY);
context.lineTo(v.endX, v.endY);
context.stroke();
context.closePath();
}
context.stroke();
}
function drawPendingLine(lastX, lastY) {
if (!startedALine) return;
context.beginPath();
context.strokeStyle = "green";
context.moveTo(storedLine.startX, storedLine.startY);
context.lineTo(lastX, lastY);
context.stroke();
context.closePath();
}
function clearScreen() {
context.clearRect(0, 0, 600, 600);
}
Can't you set a flag like
var hasLeftCanvas = false;
and set it to true when you leave the canvas?
canvas.onmouseleave = function() {
hasLeftCanvas = true;
}
and then, in your script:
$(this).mousemove(function(k) {
if(!hasLeftCanvas) {
context.clearRect(0, 0, 960, 500);
context.beginPath();
context.strokeStyle = "blue";
for (var i = 0; i < storedLines.length; i++) {
var v = storedLines[i];
context.moveTo(v.startX, v.startY);
context.lineTo(v.endX, v.endY);
context.stroke();
}
context.moveTo(mouse.x, mouse.y);
context.lineTo(k.pageX - parentOffset.left, k.pageY - parentOffset.top);
context.stroke();
context.closePath();
}
});
remember to set it back to false when the cursor re enters the canvas

Categories