I'm making a game (called Flow in android and app store) but i have a problem in Js that if i draw a line through cells then I end the function and call 'mousedown' again the lines will connect.
I feel pretty stupid. Can you help me why do they connect even tho I use context.beginPath().Here's the jsfiddle too.
https://jsfiddle.net/vj7f3qb0/
function inGame(map,usedColor) {
let x = 0;
y = 0;
canvas = document.querySelector('canvas')
const position = canvas.getBoundingClientRect();
canvas.addEventListener('mousedown', e => {
x = e.clientX - position.left;
y = e.clientY - position.top;
let b = parseInt(Math.round(x) / 50)
let a = parseInt(Math.round(y) / 50)
if(map[a][b] != 0) {
isValidClick = true
isDrawing = true
// drawLine(map,b,a,c,usedColor)
drawLine(map,a,b,canvas,usedColor)
}
})
}
function drawLine(map,a,b,canvas,usedColor) {
let savedMap = map;
let c = canvas.getContext('2d');
// console.log(c)
const position = canvas.getBoundingClientRect();
canvas.addEventListener("mousemove", e => {
let y = parseInt(Math.round(e.clientX - position.left) / 50)
let x = parseInt(Math.round(e.clientY - position.top) / 50)
if(x != a || y != b){
if(isDrawing) {
c.beginPath()
c.moveTo((b*50)+25,(a*50)+25);
c.lineTo((y*50)+25,(x*50)+25);
c.lineWidth = 5;
c.strokeStyle = "black"
c.stroke()
console.log("x,y")
console.log(x,y)
a = x
b = y
}}
// console.log(x,y)
// console.log(a,b)
canvas.addEventListener("mouseup", e => {
if(isDrawing) {
isDrawing = false;
}
})
})
}
Related
I am creating a canvas with multiple image which have zoom and pan action in Svelte application. And now want to draw line on it after disable zoom and pan. Zoom and pan working well but I cannot draw line on the canvas after zoom and pan disabled as expected. Unable to draw line on cursor point or correcting-coordinates. It's drawing far from cursor and moving the line too far on mouse move.
I am giving full code here so that any one can run it in Svelte application to see it
I tried so many ways but can't solve it.
<script>
import { onMount } from "svelte";
import { f7ready } from "framework7-svelte";
let canvasWidth = 500;
let canvasHeight = 500;
let ctx;
let canvas;
let isDrawing = false;
let start;
var scaleFactor = 1.1;
var factor = 1.1;
let canDragAndZoom = true;
let t, l;
$: ctx;
$: canvas;
$: isDrawing;
$: start;
$: t;
$: l;
$: scaleFactor;
$: factor;
$: canDragAndZoom;
let lastX = canvasWidth;
let lastY = canvasHeight;
$: lastX;
$: lastY;
onMount(() => {
f7ready(async () => {
canvas = document.getElementById("myCanvas");
canvas.width = canvasWidth;
canvas.height = canvasHeight;
var gkhead1 = new Image();
var gkhead2 = new Image();
var gkhead3 = new Image();
var gkhead4 = new Image();
var gkhead5 = new Image();
gkhead1.src =
"http://localhost/asset_ims/assets/uploads/files/canvasImg1.jpeg";
gkhead2.src =
"http://localhost/asset_ims/assets/uploads/files/canvasImg2.jpeg";
gkhead3.src =
"http://localhost/asset_ims/assets/uploads/files/canvasImg3.jpeg";
gkhead4.src =
"http://localhost/asset_ims/assets/uploads/files/canvasImg4.jpeg";
gkhead5.src =
"http://localhost/asset_ims/assets/uploads/files/canvasImg5.jpeg";
ctx = canvas.getContext("2d");
ctx.lineWidth = 1;
trackTransforms(ctx);
function redraw() {
// Clear the entire canvas
var p1 = ctx.transformedPoint(0, 0);
var p2 = ctx.transformedPoint(canvas.width, canvas.height);
ctx.clearRect(p1.x, p1.y, p2.x - p1.x, p2.y - p1.y);
ctx.save();
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.restore();
ctx.drawImage(gkhead1, 50, 150, 100, 129);
ctx.drawImage(gkhead2, 135, 150, 100, 194);
ctx.drawImage(gkhead3, 240, 150, 100, 141);
ctx.drawImage(gkhead4, 345, 150, 100, 125);
ctx.drawImage(gkhead5, 50, 300, 100, 75);
}
redraw();
var dragStart, dragged;
canvas.addEventListener(
"mousedown",
function (evt) {
document.body.style.mozUserSelect =
document.body.style.WebkitUserSelect =
document.body.style.userSelect =
document.body.style.msUserSelect =
"auto";
// drag code
lastX = evt.offsetX || evt.pageX - canvas.offsetLeft;
lastY = evt.offsetY || evt.pageY - canvas.offsetTop;
dragStart = ctx.transformedPoint(lastX, lastY);
// drag code
dragged = false;
},
false
);
canvas.addEventListener(
"mousemove",
function (evt) {
lastX = evt.offsetX || evt.pageX - canvas.offsetLeft;
lastY = evt.offsetY || evt.pageY - canvas.offsetTop;
dragged = true;
dragStart = canDragAndZoom ? dragStart : null;
if (dragStart) {
var pt = ctx.transformedPoint(lastX, lastY);
ctx.translate(pt.x - dragStart.x, pt.y - dragStart.y);
redraw();
}
},
false
);
canvas.addEventListener(
"mouseup",
function (evt) {
dragStart = null;
if (!dragged) zoom(evt.shiftKey ? -1 : 1);
},
false
);
// var scaleFactor = 1.1;
var zoom = function (clicks) {
if (!canDragAndZoom) {
return false;
}
var pt = ctx.transformedPoint(lastX, lastY);
ctx.translate(pt.x, pt.y);
factor = Math.pow(scaleFactor, clicks);
ctx.scale(factor, factor);
ctx.translate(-pt.x, -pt.y);
redraw();
};
var handleScroll = function (evt) {
var delta = evt.wheelDelta
? evt.wheelDelta / 40
: evt.detail
? -evt.detail
: 0;
if (delta) zoom(delta);
return evt.preventDefault() && false;
};
canvas.addEventListener("DOMMouseScroll", handleScroll, false);
canvas.addEventListener("mousewheel", handleScroll, false);
// };
});
});
$: if (ctx) {
ctx.strokeStyle = "red";
}
const handleStart = ({ offsetX: x, offsetY: y }) => {
isDrawing = true;
start = { x, y };
};
const handleEnd = () => {
isDrawing = false;
};
const dragEnable = () => {
canDragAndZoom = canDragAndZoom ? false : true;
};
const handleMove = (event) => {
if (!isDrawing) return;
let canvas = document.getElementById("myCanvas");
let context = canvas.getContext("2d");
let rect = canvas.getBoundingClientRect();
let currentX = event.clientX - rect.left;
let currentY = event.clientY - rect.top;
const { x, y } = start;
context.beginPath();
context.moveTo(x, y);
context.lineTo(currentX, currentY);
context.stroke();
start = { x: currentX, y: currentY };
};
function trackTransforms(ctx) {
var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
var xform = svg.createSVGMatrix();
ctx.getTransform = function () {
return xform;
};
var savedTransforms = [];
var save = ctx.save;
ctx.save = function () {
savedTransforms.push(xform.translate(0, 0));
return save.call(ctx);
};
var restore = ctx.restore;
ctx.restore = function () {
xform = savedTransforms.pop();
return restore.call(ctx);
};
var scale = ctx.scale;
ctx.scale = function (sx, sy) {
xform = xform.scaleNonUniform(sx, sy);
return scale.call(ctx, sx, sy);
};
var rotate = ctx.rotate;
ctx.rotate = function (radians) {
xform = xform.rotate((radians * 180) / Math.PI);
return rotate.call(ctx, radians);
};
var translate = ctx.translate;
ctx.translate = function (dx, dy) {
xform = xform.translate(dx, dy);
return translate.call(ctx, dx, dy);
};
var transform = ctx.transform;
ctx.transform = function (a, b, c, d, e, f) {
var m2 = svg.createSVGMatrix();
m2.a = a;
m2.b = b;
m2.c = c;
m2.d = d;
m2.e = e;
m2.f = f;
xform = xform.multiply(m2);
return transform.call(ctx, a, b, c, d, e, f);
};
var setTransform = ctx.setTransform;
ctx.setTransform = function (a, b, c, d, e, f) {
xform.a = a;
xform.b = b;
xform.c = c;
xform.d = d;
xform.e = e;
xform.f = f;
return setTransform.call(ctx, a, b, c, d, e, f);
};
var pt = svg.createSVGPoint();
ctx.transformedPoint = function (x, y) {
pt.x = x;
pt.y = y;
return pt.matrixTransform(xform.inverse());
};
}
</script>
<canvas
id="myCanvas"
bind:this={canvas}
on:mousedown={handleStart}
on:mouseup={handleEnd}
on:mouseleave={handleEnd}
on:mousemove={handleMove}
/>
<a href="#" on:click={dragEnable}>
<i class="f7-icons presc_icon">pencil_outline</i>
</a>
After so many try and lots of effort i was able to solve the issue and now it is working as expected .
just had to add some line in handleMove function .
I am posting the solution as answer here so that any one next time can learn it and use the whole code with answer .
const handleMove = (event) => {
if (!isDrawing) return;
let currentX = event.offsetX;
let currentY = event.offsetY;
const { x, y } = start;
let startx = ctx.transformedPoint(x, y);
let endy = ctx.transformedPoint(currentX, currentY);
ctx.beginPath();
ctx.moveTo(startx.x, startx.y);
ctx.lineTo(endy.x, endy.y);
ctx.stroke();
start = { x: currentX, y: currentY };
};
I'm currently doing a project regarding p5.js and I need to do the following:
Input: given image and rectangle;
Algorithm: move the image inside the rectangle. By saying moving, I mean when the mouse is clicked, move the whole image to match the size of the rectangle by showing only portion of the image (size of the rectangle).
Output: dragging image inside the rectangle.
Update: When I import an image with React input form, it does not change the current image in P5 even I call the p5.redraw() function.
My current code is moving the image, but I need an image to be inside the rectangle and show only part of the image that is this size of the rectangle. The code is written in React:
const [selectedFile, setSelectedFile] = useState();
let backgroundImage;
let dragging = false; // Is the object being dragged?
let rollover = false; // Is the mouse over the ellipse?
let x, y, w, h; // Location and size
let offsetX, offsetY; // Mouseclick offset
const setup = (p5, parentRef) => {
p5.createCanvas(1000, 500).parent(parentRef);
// Starting location
x = 350;
y = 50;
const url =
"https://upload.wikimedia.org/wikipedia/commons/thumb/b/b6/Image_created_with_a_mobile_phone.png/640px-Image_created_with_a_mobile_phone.png";
backgroundImage = p5.loadImage(url);
// Dimensions
w = 700;
h = 700;
};
const draw = (p5) => {
p5.background(233);
if (
p5.mouseX > x &&
p5.mouseX < x + w &&
p5.mouseY > y &&
p5.mouseY < y + h
) {
rollover = true;
} else {
rollover = false;
}
// Adjust location if being dragged
if (dragging) {
x = p5.mouseX + offsetX;
y = p5.mouseY + offsetY;
}
if (selectedFile != null) {
const url = URL.createObjectURL(selectedFile);
backgroundImage = p5.loadImage(url);
// p5.image(backgroundImage, x, y, w, h);
// p5.redraw();
// backgroundImage = p5.loadImage(url, () => {
// p5.image(backgroundImage, x, y, w, h);
// p5.redraw();
// });
} else {
}
p5.image(backgroundImage, x, y);
drawMaskOverlay(p5);
};
const drawMaskOverlay = (p5) => {
p5.fill(255);
p5.noStroke();
p5.beginShape();
// CW
p5.vertex(0, 0);
p5.vertex(p5.width, 0);
p5.vertex(p5.width, p5.height);
p5.vertex(0, p5.height);
// cutout contour CCW
p5.beginContour();
p5.vertex(400, 100);
p5.vertex(400, 400);
p5.vertex(600, 400);
p5.vertex(600, 100);
p5.endContour();
p5.endShape();
};
const mousePressed = (p5) => {
if (
p5.mouseX > x &&
p5.mouseX < x + w &&
p5.mouseY > y &&
p5.mouseY < y + h
) {
dragging = true;
offsetX = x - p5.mouseX;
offsetY = y - p5.mouseY;
}
};
const mouseReleased = (p5) => {
// Quit dragging
dragging = false;
};
to display it, I use the following code:
return (
<div className="App">
<div>
<h1>Select an image</h1>
<input
type="file"
name="file"
id="file"
// onChange={(e) => setSelectedFile(e.target.files[0])}
onChange={(e) => setSelectedFile(e.target.files[0])}
/>
<Sketch
// preload={preload}
setup={setup}
draw={draw}
mouseReleased={mouseReleased}
mousePressed={mousePressed}
/>
</div>
</div>
);
I use react-p5 library.
You can see and test the code in StackBlitz.
One quick workaround is to simply overlay a cutout shape using beginContour() / endContour(), thus only showing a portion of the image:
let backgroundImage;
let dragging = false;
let rollover = false;
let x, y, w, h; // Location and size
let offsetX, offsetY;
preload = () => {
const url = "https://upload.wikimedia.org/wikipedia/commons/thumb/b/b6/Image_created_with_a_mobile_phone.png/640px-Image_created_with_a_mobile_phone.png";
backgroundImage = loadImage(url);
};
setup = () => {
createCanvas(1000, 500);
// Starting location
x = 100;
y = 100;
// Dimensions
w = 300;
h = 400;
}
draw = () => {
background(233);
if (
mouseX > x &&
mouseX < x + w &&
mouseY > y &&
mouseY < y + h
) {
rollover = true;
} else {
rollover = false;
}
if (dragging) {
x = mouseX + offsetX;
y = mouseY + offsetY;
}
image(backgroundImage, x, y, w, h);
// noFill();
// stroke(0);
// rect(100, 100, 200, 300);
drawMaskOverlay();
};
function drawMaskOverlay(){
fill(0);
noStroke();
beginShape();
// CW
vertex(0, 0);
vertex(width, 0);
vertex(width, height);
vertex(0, height);
// cutout contour CCW
beginContour();
vertex(100, 100);
vertex(100, 400);
vertex(300, 400);
vertex(300, 100);
endContour();
endShape();
}
mousePressed = () => {
if (
mouseX > x &&
mouseX < x + w &&
mouseY > y &&
mouseY < y + h
) {
dragging = true;
offsetX = x - mouseX;
offsetY = y - mouseY;
}
};
mouseReleased = () => {
dragging = false;
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.2/p5.min.js"></script>
If the project is a school project it's unclear whether the above will pass if it doesn't cover the materials taught. If it's a personal project, the above should be a simple enough workaround.
Other alternatives ways of showing parts of the image could be:
working with p5.Image which has a mask() method (potentially in conjuction with p5.Graphics which would make it easy draw into and covert to a p5.Image via get())
with with p5.Image and instead of masking, clearing a blank (buffer) image and only copying a portion of backgroundImage (depending on it's dragged location) via copy() which would make it appear like backgroundImage is masked.
Update based on your file select comment here's a tweaked version of the above snippet:
let backgroundImage;
let dragging = false;
let rollover = false;
let x, y, w, h; // Location and size
let offsetX, offsetY;
preload = () => {
const url = "https://upload.wikimedia.org/wikipedia/commons/thumb/b/b6/Image_created_with_a_mobile_phone.png/640px-Image_created_with_a_mobile_phone.png";
backgroundImage = loadImage(url);
};
setup = () => {
createCanvas(1000, 500);
// Starting location
x = 100;
y = 100;
// Dimensions
w = 300;
h = 400;
createFileInput(handleFile);
}
handleFile = (file) => {
if (file.type === 'image') {
backgroundImage = createImg(file.data, '');
backgroundImage.hide();
} else {
backgroundImage = null;
}
}
draw = () => {
background(233);
if (
mouseX > x &&
mouseX < x + w &&
mouseY > y &&
mouseY < y + h
) {
rollover = true;
} else {
rollover = false;
}
if (dragging) {
x = mouseX + offsetX;
y = mouseY + offsetY;
}
// only render the image if it exists
if(backgroundImage)
image(backgroundImage, x, y, w, h);
// noFill();
// stroke(0);
// rect(100, 100, 200, 300);
drawMaskOverlay();
};
function drawMaskOverlay(){
fill(0);
noStroke();
beginShape();
// CW
vertex(0, 0);
vertex(width, 0);
vertex(width, height);
vertex(0, height);
// cutout contour CCW
beginContour();
vertex(100, 100);
vertex(100, 400);
vertex(300, 400);
vertex(300, 100);
endContour();
endShape();
}
mousePressed = () => {
if (
mouseX > x &&
mouseX < x + w &&
mouseY > y &&
mouseY < y + h
) {
dragging = true;
offsetX = x - mouseX;
offsetY = y - mouseY;
}
};
mouseReleased = () => {
dragging = false;
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.2/p5.min.js"></script>
Here is the link to the codepen: https://codepen.io/Jsbbvk/pen/RwGBwOO
const edgePadding = 80;
const panSpeed = 5;
const expandCanvasEdge = (x, y) => {
let pan = {
x: 0,
y: 0,
};
const width = canvas.getWidth(),
height = canvas.getHeight();
if (x <= edgePadding) {
//left
const speedRatio = 1 - Math.max(0, x) / edgePadding;
pan.x = panSpeed * speedRatio;
} else if (x >= width - edgePadding) {
//right
const speedRatio =
1 - (width - Math.min(width, x)) / edgePadding;
pan.x = -panSpeed * speedRatio;
}
if (y <= edgePadding) {
//top
const speedRatio = 1 - Math.max(0, y) / edgePadding;
pan.y = panSpeed * speedRatio;
} else if (y >= height - edgePadding) {
//bottom
const speedRatio =
1 - (height - Math.min(height, y)) / edgePadding;
pan.y = -panSpeed * speedRatio;
}
if (pan.x || pan.y) {
canvas.relativePan(new fabric.Point(pan.x, pan.y));
}
}
canvas.on('mouse:move', function(opt) {
if (this.isMouseDown && this.isDrawingMode) {
let {x, y} = canvas.getPointer(opt.e, true);
expandCanvasEdge(x, y);
}
if (!this.isDrawingMode && this.isDragging) {
//panning
var e = opt.e;
var vpt = this.viewportTransform;
vpt[4] += e.clientX - this.lastPosX;
vpt[5] += e.clientY - this.lastPosY;
this.requestRenderAll();
this.lastPosX = e.clientX;
this.lastPosY = e.clientY;
}
});
In the demo, when you draw close to the edge of the canvas, the canvas should pan to allow more drawing space.
However, while the panning is happening, the drawing (path) is static on the canvas; it doesn't stretch as the canvas pans.
Is there a way to fix this issue?
I did some deep research for you and found a few examples.
You can overcome this situation by using the relativePan function.
One of the examples I have found:
function startPan(event) {
if (event.button != 2) {
return;
}
var x0 = event.screenX,
y0 = event.screenY;
function continuePan(event) {
var x = event.screenX,
y = event.screenY;
fc.relativePan({ x: x - x0, y: y - y0 });
x0 = x;
y0 = y;
}
function stopPan(event) {
$(window).off('mousemove', continuePan);
$(window).off('mouseup', stopPan);
};
$(window).mousemove(continuePan);
$(window).mouseup(stopPan);
$(window).contextmenu(cancelMenu);
};
function cancelMenu() {
$(window).off('contextmenu', cancelMenu);
return false;
}
$(canvasWrapper).mousedown(startPan);
You can determine a roadmap by examining the resources and demos here.
JSFiddle demo https://jsfiddle.net/tornado1979/up48rxLs/
I have a array of abstract shapes coordinates. I want to split that shape into a number of squares and get their coordinates like shown in the image shown below:
For that i have tried is:
Find the extreme left and top coordinates and further with the loop find the relative position of the square coordinates. But this includes the square on outer side of it.
My Code:
var intersections = [];
var y = -9999;
var x = -9999;
var ym = 9999;
var xm = 9999;
var boundry = [];
//loop to find the extreme cordinates
for(var k=0; k <points.length; k++){
var pt = [];
pt.push(points[k].x);
pt.push(points[k].y);
boundry.push(pt);
if(points[k].x > x){
x = points[k].x;
}
if(points[k].y > y){
y = points[k].y;
}
if(points[k].x < xm){
xm = points[k].x;
}
if(points[k].y < ym){
ym = points[k].y;
}
}
for(var o = ym; o < y; o = o + split_diff){
console.log('o',o);
for(var i = xm; i < x; i = i + split_diff){
//divided points!
var isInside = checkIn(o,x);
if(isInside){
intersections.push(o,x);
}
}
}
What i want
Is there any other way to achieve same without getting the outer squares. like any external library or so. Thank you for the help in advance.
function split_polygon(points){
// above code here
}
//array of all the intersection cordinates
To cope with all kinds of polygons (even non-convex), you could scan across a horizontal line where that line crosses the polygon and so determine which are the line segment(s) of that line that are interior to the polygon.
Once you have that it is rather easy to pick the points on those line segments.
Repeat for several horizontal lines (at the required vertical distance).
Here is a snippet that allows you to click on a canvas to define a polygon. To create the final closing edge of the polygon, click the button. At that time the algorithm to create that dot-grid will also kick in.
function intersectionY(edge, y) {
const [[x1, y1], [x2, y2]] = edge;
const dir = Math.sign(y2 - y1);
if (dir && (y1 - y)*(y2 - y) <= 0) return { x: x1 + (y-y1)/(y2-y1) * (x2-x1), dir };
}
function tilePolygon(points, tileSize){
const minY = Math.min(...points.map(p => p[1]));
const maxY = Math.max(...points.map(p => p[1]));
const minX = Math.min(...points.map(p => p[0]));
const gridPoints = [];
for (let y = minY; y <= maxY; y += tileSize) {
// Collect x-coordinates where polygon crosses this horizontal line (y)
const cuts = [];
let prev = null;
for (let i = 0; i < points.length; i++) {
const cut = intersectionY([points[i], points[(i+1)%points.length]], y);
if (!cut) continue;
if (!prev || prev.dir !== cut.dir) cuts.push(cut);
prev = cut;
}
if (prev && prev.dir === cuts[0].dir) cuts.pop();
// Now go through those cuts from left to right toggling whether we are in/out the polygon
let dirSum = 0;
let startX = null;
for (let cut of cuts.sort((a, b) => a.x - b.x)) {
dirSum += cut.dir;
if (dirSum % 2) { // Entering polygon
if (startX === null) startX = cut.x;
} else if (startX !== null) { // Exiting polygon
// Genereate grid points on this horizontal line segement
for (let x = minX + Math.ceil((startX - minX) / tileSize)*tileSize; x <= cut.x; x += tileSize) {
gridPoints.push([x, y]);
}
startX = null;
}
}
}
return gridPoints;
}
function controller() { // I/O for this interactive snippet
const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d");
const points = [];
function drawLines(points, close, color = "black") {
ctx.beginPath();
ctx.moveTo(...points[0]);
for (let point of points) ctx.lineTo(...point);
if (close) ctx.closePath();
ctx.strokeStyle = color;
ctx.stroke();
}
function drawPoint(x, y, color = "black") {
ctx.fillStyle = color;
ctx.fillRect(x, y, 1, 1);
}
document.querySelector("#polclose").addEventListener("click", function () {
const gridPoints = tilePolygon(points, 10);
// Output:
drawLines(points, true);
gridPoints.forEach(p => drawPoint(...p, "red"));
});
canvas.addEventListener("click", function(e) {
const x = e.clientX - this.offsetLeft;
const y = e.clientY - this.offsetTop;
points.push([x, y]);
drawLines(points, false);
});
canvas.addEventListener("mousemove", function(e) {
const x = e.clientX - this.offsetLeft;
const y = e.clientY - this.offsetTop;
document.querySelector("#output").textContent = x + ", " + y;
});
}
controller();
canvas { border: 1px solid }
Click at different coordinates to create a polygon:<br>
<canvas></canvas><br><button id="polclose">Complete Polygon</button>
<div id="output"></div>
Is there a way to keep count of the number of shapes drawn on a canvas
I'm using a brush of sorts to draw a string of circles on a canvas and would like to find a way to count how many are present
var mainCanvas = document.getElementById('draw1');
mainContext = mainCanvas.getContext('2d');
var CircleBrush = {
iPrevX: 0,
iPrevY: 0,
// initialization function
init: function () {
mainContext.globalCompositeOperation = 'source-over';
mainContext.lineWidth = 1;
mainContext.strokeStyle = '#4679BD';
mainContext.lineWidth = 1;
mainContext.lineJoin = 'round';
},
startCurve: function (x, y) {
this.iPrevX = x;
this.iPrevY = y;
mainContext.fillStyle = '#4679BD';
},
draw: function (x, y) {
var iXAbs = Math.abs(x - this.iPrevX);
var iYAbs = Math.abs(y - this.iPrevY);
var rad = 6;
if (iXAbs > 10 || iYAbs > 10) {
mainContext.beginPath();
mainContext.arc(this.iPrevX, this.iPrevY, rad, Math.PI * 2, false);
mainContext.fill();
mainContext.stroke();
this.iPrevX = x;
this.iPrevY = y;
}
}
};
var circleCounter = [0];
mainContext.font = '21pt Arial';
mainContext.fillStyle = '#262732';
mainContext.textBaseline = 'top';
mainContext.fillText(circleCounter, 20, 20);
CircleBrush.init();
$('#draw1').mousedown(function (e) { // mouse down handler
cMoeDo = true;
var canvasOffset = $('#draw1').offset();
var canvasX = Math.floor(e.pageX - canvasOffset.left);
var canvasY = Math.floor(e.pageY - canvasOffset.top);
CircleBrush.startCurve(canvasX, canvasY);
circleCounter ++1;
});
$('#draw1').mouseup(function (e) { // mouse up handler
cMoeDo = false;
});
$('#draw1').mousemove(function (e) { // mouse move handler
if (cMoeDo) {
var canvasOffset = $('#draw1').offset();
var canvasX = Math.floor(e.pageX - canvasOffset.left);
var canvasY = Math.floor(e.pageY - canvasOffset.top);
CircleBrush.draw(canvasX, canvasY);
circleCounter ++1;
}
})
Demo fiddle http://jsfiddle.net/A2vyY/
Thanks in advance
You need to clear the space for the counter and redraw the count. In order to do so I put the counter and text drawing in the draw function like so
draw: function (x, y) {
var iXAbs = Math.abs(x - this.iPrevX);
var iYAbs = Math.abs(y - this.iPrevY);
var rad = 6;
if (iXAbs > 10 || iYAbs > 10) {
mainContext.beginPath();
mainContext.arc(this.iPrevX, this.iPrevY, rad, Math.PI*2, false);
mainContext.fill();
mainContext.stroke();
this.iPrevX = x;
this.iPrevY = y;
circleCounter ++;
mainContext.clearRect(0,0,50,25);
mainContext.fillText(circleCounter, 5, 5);
}
}
Updated jsFiddle (I moved the counter some so that there is more room for the dots)
You can put the counter in a separate div and just update the text
<div id="content">
<div id="counter">0</div>
<canvas id="draw1" height="500" width="500"></canvas>
</div>
Return true when a circle is drawn, false if not
draw: function (x, y) {
/* ... */
if (iXAbs > 10 || iYAbs > 10) {
/* ... */
return true;
}
return false;
}
increment and show as necessary
if (CircleBrush.draw(canvasX, canvasY)) {
++circleCounter;
$('#counter').text(circleCounter);
}
See modified JSFiddle