How can I move an obj inside a canvas using touch event? - javascript

Hello everybody I've just trying to understands how this does it work
I have a basic canvas base just in javascript and I would like to move it using touch event
I'm not sure about this but Can I use the drag event ?
Do I need to use a loop function ?
How can I trigger that blue cube ?
I know there are lot of javascript engine in fact i'm using phaser but I would like to undertand this
Thank you
var canvas, cx, width, height;
var cube = {
x: 80,
y: 100,
update: function () {
},
draw: function (ctx) {
ctx.save();
ctx.fillStyle = "blue";
ctx.fillRect(100, 410, 50, 50);
ctx.restore();
}
};
function onpress(e) {
e.preventDefault();
var whichArt = e.target;
var touch = e.touches[0];
var moveOffsetX = whichArt.offsetLeft - touch.pageX;
var moveOffsetY = whichArt.offsetTop - touch.pageY;
whichArt.addEventListener('touchmove', function () {
var positionX = touch.pageX + moveOffsetX;
var positionY = touch.pageY + moveOffsetY;
cube.x = positionX;
cube.y = positionY;
console.log(cube.x);
}, false);
}
function main() {
canvas = document.createElement("canvas");
width = window.innerWidth;
height = window.innerHeight;
if (width >= 500) {
width = 320;
height = 480;
canvas.style.border = "1px solid #000";
}
document.addEventListener("touchstart", onpress);
canvas.width = width;
canvas.height = height;
ctx = canvas.getContext("2d");
document.body.appendChild(canvas);
run();
}
function run() {
var loop = function () {
update();
render();
window.requestAnimationFrame(loop, canvas);
}
window.requestAnimationFrame(loop, canvas);
}
function update() {
}
function render() {
cube.draw(ctx);
}
main();
http://jsfiddle.net/marcogomesr/sxbo3r83/

The canvas is only a passive drawing surface : You have to handle the drag by yourself.
Below a short example :
draggables object have to implement isPointInside, and to be added to the list of draggables object.
I used a dragData object that stores the list of draggables object, the currently dragged object, maybe you'll want to store the start/current point of the drag, and handle a drag-offset so the user holds the object right on the point where he/she started dragging.
http://jsfiddle.net/3ksvn4y0/3/
var canvas, cx, width, height;
var canvasRect;
var cube1, cube2;
var dragData = {
draggables: [],
start: { x: 0, y: 0
},
current: { x: 0, y: 0
},
target: null
};
function Cube(x,y,w,h, color) {
this.x=x; this.y=y; this.w=w; this.h = h;
this.color = color;
}
Cube.prototype = {
update: function () {
},
draw: function (ctx) {
ctx.fillStyle = this.color;
ctx.fillRect(this.x, this.y, this.w, this.h);
},
isPointInside: function (x, y) {
return (x >= this.x) && (x < this.x + this.w) && (y > this.y) && (y < this.y + this.h);
}
};
var pointerCoords = {
x: 0,
y: 0,
update: function (e) {
var coords = e.touches ? e.touches[0] : e;
this.x = coords.pageX - canvasRect.left;
this.y = coords.pageY - canvasRect.top;
}
};
function onStart(e) {
e.preventDefault();
pointerCoords.update(e);
// look if we start the touch within a draggable object
var target = null;
for (var i = 0; i < dragData.draggables.length; i++) {
var draggable = dragData.draggables[i];
if (draggable.isPointInside(pointerCoords.x, pointerCoords.y)) {
target = draggable;
break;
}
}
dragData.target = target;
}
function onMove(e) {
pointerCoords.update(e);
var target = dragData.target;
if (!target) return;
target.x = pointerCoords.x;
target.y = pointerCoords.y;
}
function onStop(e) {
pointerCoords.update(e);
e.preventDefault();
if (!dragData.target) return;
onMove(e);
dragData.target = null;
}
function main() {
canvas = document.createElement("canvas");
width = window.innerWidth;
height = window.innerHeight;
if (width >= 500) {
width = 320;
height = 480;
canvas.style.border = "1px solid #000";
}
canvas.width = width;
canvas.height = height;
ctx = canvas.getContext("2d");
document.body.appendChild(canvas);
canvasRect = canvas.getBoundingClientRect();
canvas.addEventListener("touchstart", onStart);
canvas.addEventListener('touchmove', onMove);
canvas.addEventListener("touchstop", onStop);
canvas.addEventListener("mousedown", onStart);
canvas.addEventListener('mousemove', onMove);
canvas.addEventListener("mouseup", onStop);
cube1 = new Cube(100, 80, 30, 30, 'blue');
cube2 = new Cube(150, 160, 20, 20, 'red');
dragData.draggables.push(cube1, cube2);
run();
}
function run() {
var loop = function () {
requestAnimationFrame(loop);
update();
render();
}
loop();
}
function update() {
}
function render() {
ctx.clearRect(0, 0, width, height);
cube1.draw(ctx);
cube2.draw(ctx);
}
main();

Related

Draw rectangle in canvas with loaded pdf file using pdf.js

I am trying to draw rectangle over a pdf file. When I draw rectangle in pdf, rectangle not draw properly.
I want to draw only one rectangle at a time, when I draw new rectangle the old rectangle should be remove, but it is not happening.
Here is my code:
Rendering code of pdf (Rendering is working properly)
function pdfFile (file) {
pdfjsLib.workerSrc = 'pdf.worker.js';
pdfjsLib.getDocument(file).promise.then(function(pdfDoc) {
pdf = pdfDoc;
document.getElementById('page_count').textContent = pdfDoc.numPages;
showButtonGroup(pdf);
renderPage(pageNum);
});
}
function renderPage(num) {
pageRendering = true;
pdf.getPage(num).then(function(page) {
var viewport = page.getViewport({scale: scale});
canvas.height = viewport.height;
canvas.width = viewport.width;
var renderContext = {
canvasContext: ctx,
viewport: viewport
};
var renderTask = page.render(renderContext);
renderTask.promise.then(function() {
pageRendering = false;
if (pageNumPending !== null) {
renderPage(pageNumPending);
pageNumPending = null;
}
});
});
document.getElementById('page_num').textContent = num;
}
Mouse move function not working properly
function mouseMove(e) {
if (drag) {
ctx.putImageData(pdfPages[pageNum], 0, 0);
ctx.clearRect(rect.startX, rect.startY, rect.w, rect.h);
rect.w = ((e.pageX - x) - this.offsetLeft) - rect.startX;
rect.h = ((e.pageY - y) - this.offsetTop) - rect.startY;
ctx.strokeStyle = color;
ctx.strokeRect(rect.startX, rect.startY, rect.w, rect.h);
Object.assign(data, {
x: rect.startX,
y: rect.startY,
w: rect.w,
h: rect.h
})
console.log(data);
}
}
Note
When I enable clearRect and putImageData function then rectangle draw properly but canvas pdf shows empty. Here is the attached image
When only enabled clearRect function then showing multiple rectangle in pdf. Here is the attached image
Please check the below, need to clear the existing rectangle before creating new
function renderPage(num) {
pageRendering = true;
pdf.getPage(num).then(function (page) {
var viewport = page.getViewport({ scale: scale });
canvas.height = viewport.height;
canvas.width = viewport.width;
var renderContext = {
canvasContext: ctx,
viewport: viewport
};
var renderTask = page.render(renderContext);
renderTask.promise.then(function () {
pageRendering = false;
//You need to clear the existing rectangle
pdfPages[num] = ctx.getImageData(0, 0, canvas.width, canvas.height);
//Now you can draw new rectangle
drawRectangle(10, 10, 100, 50);
if (pageNumPending !== null) {
renderPage(pageNumPending);
pageNumPending = null;
}
});
});
function drawRectangle(x, y, w, h) {
ctx.strokeStyle = color;
ctx.strokeRect(x, y, w, h);
}
The other way to do selectable rectangles on canvas in react using pdf.js is by keeping original canvas saved using toDataURL() and then after clearRect use canvas.draw() to draw your canvas with the base64 image saved earlier.
import React, { useEffect, useState, useRef, useCallback } from "react";
import pdfjsWorker from "pdfjs-dist/build/pdf.worker.entry";
import * as pdfjsLib from "pdfjs-dist/build/pdf";
export default function CustomPdfReader({ url }) {
pdfjsLib.GlobalWorkerOptions.workerSrc = pdfjsWorker;
const canvasRef = useRef();
const [pdfRef, setPdfRef] = useState("");
const currentPage = 1;
const zoomScale = 1;
const rotateAngle = 0;
var pdf_image = "";
const renderPage = useCallback(
(pageNum, pdf = pdfRef) => {
pdf &&
pdf.getPage(pageNum).then(function (page) {
const viewport = page.getViewport({ scale: zoomScale, rotation: rotateAngle });
const canvas = canvasRef.current;
canvas.height = viewport?.height;
canvas.width = viewport?.width;
const renderContext = {
canvasContext: canvas?.getContext("2d"),
viewport: viewport,
textContent: pdfRef,
};
page.render(renderContext);
});
},
[pdfRef, url]
);
useEffect(() => {
if (url.slice(-4).toLowerCase() === ".pdf") {
renderPage(currentPage, pdfRef);
} else {
setPdfRef("");
}
}, [pdfRef, renderPage, url]);
useEffect(() => {
const loadingTask = pdfjsLib.getDocument(url);
loadingTask.promise.then(
(loadedPdf) => {
setPdfRef(loadedPdf);
},
function (reason) {
console.error(reason);
}
);
}, [url]);
var cursorInCanvas = false;
var canvasOfDoc = canvasRef?.current;
var ctx;
var startX;
var startY;
var offsetX;
var offsetY;
const saveInitialCanvas = () => {
if (canvasOfDoc?.getContext) {
var canvasPic = new Image();
canvasPic.src = canvasOfDoc.toDataURL();
pdf_image = canvasPic;
}
};
useEffect(() => {
if (canvasOfDoc) {
ctx = canvasOfDoc.getContext("2d");
var canvasOffset = canvasOfDoc.getBoundingClientRect();
offsetX = canvasOffset.left;
offsetY = canvasOffset.top;
}
}, [canvasOfDoc, pdfRef, renderPage, url]);
function handleMouseIn(e) {
if (typeof pdf_image == "string") {
saveInitialCanvas();
}
e.preventDefault();
e.stopPropagation();
startX = ((e.offsetX * canvasOfDoc.width) / canvasOfDoc.clientWidth) | 0;
startY = ((e.offsetY * canvasOfDoc.width) / canvasOfDoc.clientWidth) | 0;
cursorInCanvas = true;
}
function handleMouseOut(e) {
e.preventDefault();
e.stopPropagation();
cursorInCanvas = false;
}
function handleMouseMove(e) {
e.preventDefault();
e.stopPropagation();
if (!cursorInCanvas) {
return;
}
let mouseX = ((e.offsetX * canvasOfDoc.width) / canvasOfDoc.clientWidth) | 0;
let mouseY = ((e.offsetY * canvasOfDoc.width) / canvasOfDoc.clientWidth) | 0;
var width = mouseX - startX;
var height = mouseY - startY;
if (ctx) {
ctx?.clearRect(0, 0, canvasOfDoc.width, canvasOfDoc.height);
ctx?.drawImage(pdf_image, 0, 0);
ctx.beginPath();
ctx.rect(startX, startY, width, height);
ctx.strokeStyle = "#1B9AFF";
ctx.lineWidth = 1;
ctx.stroke();
}
}
canvasOfDoc?.addEventListener("mousedown", function (e) {
handleMouseIn(e);
});
canvasOfDoc?.addEventListener("mousemove", function (e) {
handleMouseMove(e);
});
canvasOfDoc?.addEventListener("mouseup", function (e) {
handleMouseOut(e);
});
canvasOfDoc?.addEventListener("mouseout", function (e) {
handleMouseOut(e);
});
return (
<>
<canvas id="pdf-doc" ref={canvasRef} />
</>
);
}

Drawing multiple boxes on canvas

Before I edited my code to create the boxes as objects and push them into an array, I could draw multiple boxes on the canvas and all of them would show up at once (until I cleared the canvas). However, now only one box shows up on the canvas at once, and when I draw another box, the previous box would be removed (although they would still be created as an object and pushed into the array). How do I edit my code so that I can draw multiple boxes onto the canvas and have them all show up together, until I clear the canvas?
Code:
const annotation = {
xcoordi: 0,
ycoordi: 0,
width: 0,
height: 0,
printCoordinates: function () {
console.log(`X: ${this.xcoordi}px, Y: ${this.ycoordi}px, Width: ${this.width}px, Height: ${this.height}px`);
}
};
//the array of all rectangles
let boundingBoxes = [];
// the actual rectangle, the one that is being drawn
let o={};
// a variable to store the mouse position
let m = {},
// a variable to store the point where you begin to draw the rectangle
start = {};
// a boolean
let isDrawing = false;
function handleMouseDown(e) {
start = oMousePos(canvas2, e);
isDrawing = true;
//console.log(start.x, start.y);
canvas2.style.cursor = "crosshair";
}
function handleMouseMove(e) {
if(isDrawing){
m = oMousePos(canvas2, e);
draw();
}
}
function handleMouseUp(e) {
canvas2.style.cursor = "default";
isDrawing = false;
const box = Object.create(annotation);
box.xcoordi = o.x;
box.ycoordi = o.y;
box.width = o.w;
box.height = o.h;
boundingBoxes.push(box);
draw();
box.printCoordinates();
console.log(boundingBoxes)
}
function draw() {
o.x = start.x; // start position of x
o.y = start.y; // start position of y
o.w = m.x - start.x; // width
o.h = m.y - start.y; // height
clearcanvas();
// draw all the rectangles saved in the rectsRy
boundingBoxes.map(r => {drawRect(r)})
// draw the actual rectangle
drawRect(o);
}
canvas2.addEventListener("mousedown", handleMouseDown);
canvas2.addEventListener("mousemove", handleMouseMove);
canvas2.addEventListener("mouseup", handleMouseUp);
function savecanvas(){
context2.clearRect(0, 0, canvas2.width, canvas2.height);
var savedBoxes = boundingBoxes.slice(0);
console.log(savedBoxes); // ok
}
function resetcanvas(){
context2.clearRect(0, 0, canvas2.width, canvas2.height);
boundingBoxes.length = 0;
console.log(boundingBoxes); // ok
}
function drawRect(o){
context2.strokeStyle = "limegreen";
context2.lineWidth = 2;
context2.beginPath(o);
context2.rect(o.x,o.y,o.w,o.h);
context2.stroke();
}
// Function to detect the mouse position
function oMousePos(canvas2, evt) {
let ClientRect = canvas2.getBoundingClientRect();
return {
x: Math.round(evt.clientX - ClientRect.left),
y: Math.round(evt.clientY - ClientRect.top)
}
}
Any help is really appreciated, thank you!
You have 2 errors:
in your code you are using a clearcanvas(); function which is not defined. I've replaced it with context2.clearRect(0, 0, canvas2.width, canvas2.height);
and this is more important: the object you save has these properties: xcoordi, ycoordi, width, height, BUT in drawRect(o) you are using x, y, w, h to draw the rect, but x, y, w, h are undefined, and thus no rect is drawn.
Please check my code:
const canvas2 = document.getElementById("canvas");
const context2 = canvas.getContext("2d");
const annotation = {
x: 0,
y: 0,
w: 0,
h: 0,
printCoordinates: function () {
console.log(`X: ${this.x}px, Y: ${this.y}px, Width: ${this.w}px, Height: ${this.h}px`);
}
};
//the array of all rectangles
let boundingBoxes = [];
// the actual rectangle, the one that is being drawn
let o={};
// a variable to store the mouse position
let m = {},
// a variable to store the point where you begin to draw the rectangle
start = {};
// a boolean
let isDrawing = false;
function handleMouseDown(e) {
start = oMousePos(canvas2, e);
isDrawing = true;
//console.log(start.x, start.y);
canvas2.style.cursor = "crosshair";
}
function handleMouseMove(e) {
if(isDrawing){
m = oMousePos(canvas2, e);
draw();
}
}
function handleMouseUp(e) {
canvas2.style.cursor = "default";
isDrawing = false;
const box = Object.create(annotation);
box.x = o.x;
box.y = o.y;
box.w = o.w;
box.h = o.h;
boundingBoxes.push(box);
draw();
box.printCoordinates();
console.log(boundingBoxes)
}
function draw() {
o.x = start.x; // start position of x
o.y = start.y; // start position of y
o.w = m.x - start.x; // width
o.h = m.y - start.y; // height
//clearcanvas();
context2.clearRect(0, 0, canvas2.width, canvas2.height);//////***********
// draw all the rectangles saved in the rectsRy
boundingBoxes.map(r => {drawRect(r)})
// draw the actual rectangle
drawRect(o);
}
canvas2.addEventListener("mousedown", handleMouseDown);
canvas2.addEventListener("mousemove", handleMouseMove);
canvas2.addEventListener("mouseup", handleMouseUp);
function savecanvas(){
context2.clearRect(0, 0, canvas2.width, canvas2.height);
var savedBoxes = boundingBoxes.slice(0);
console.log(savedBoxes); // ok
}
function resetcanvas(){
context2.clearRect(0, 0, canvas2.width, canvas2.height);
boundingBoxes.length = 0;
console.log(boundingBoxes); // ok
}
function drawRect(o){
context2.strokeStyle = "limegreen";
context2.lineWidth = 2;
context2.beginPath(o);
context2.rect(o.x,o.y,o.w,o.h);
context2.stroke();
}
// Function to detect the mouse position
function oMousePos(canvas2, evt) {
let ClientRect = canvas2.getBoundingClientRect();
return {
x: Math.round(evt.clientX - ClientRect.left),
y: Math.round(evt.clientY - ClientRect.top)
}
}
canvas{border:1px solid;}
<canvas id="canvas"></canvas>
void function() {
"use strict";
// Variables
var canvasWidth = 180;
var canvasHeight = 160;
var canvas = null;
var ctx = null;
var rectangles = [];
var isDrawing = false;
var mouseStartX = 0.0;
var mouseStartY = 0.0;
var mouseEndX = 0.0;
var mouseEndY = 0.0;
// Functions
// Constructor function (called with 'new')
function Rectangle(x,y,width,height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
function draw() {
ctx.fillStyle = "black";
ctx.fillRect(0,0,canvasWidth,canvasHeight);
ctx.strokeStyle = "limegreen";
ctx.lineWidth = 2;
ctx.beginPath();
for (var i = 0; i < rectangles.length; ++i) {
var rectangle = rectangles[i];
ctx.rect(
rectangle.x,
rectangle.y,
rectangle.width,
rectangle.height
);
}
ctx.stroke();
}
function getMousePosition(e) {
if (canvas && e) {
var bounds = canvas.getBoundingClientRect();
return [
e.clientX - bounds.left,
e.clientY - bounds.top
];
} else {
return [
0.0,
0.0
];
}
}
// Event Handlers
window.onmousedown = function(e) {
if (!isDrawing) {
isDrawing = true;
// Destructuring Assignment
[mouseStartX,mouseStartY] = getMousePosition(e);
canvas.style.cursor = "crosshair";
}
}
window.onmouseup = function(e) {
if (isDrawing) {
isDrawing = false;
// Destructuring Assignment
[mouseEndX,mouseEndY] = getMousePosition(e);
rectangles.push(
new Rectangle(
mouseStartX,
mouseStartY,
mouseEndX - mouseStartX,
mouseEndY - mouseStartY
)
);
draw();
canvas.style.cursor = "default";
}
}
window.onmousemove = function(e) {
if (isDrawing) {
// Destructuring Assignment
[mouseEndX,mouseEndY] = getMousePosition(e);
draw();
ctx.strokeStyle = "darkred";
ctx.lineWidth = 2;
ctx.beginPath();
ctx.rect(
mouseStartX,
mouseStartY,
mouseEndX - mouseStartX,
mouseEndY - mouseStartY
);
ctx.stroke();
}
}
// Runs when the page loads
window.onload = function() {
canvas = document.getElementById("canvas");
canvas.width = canvasWidth;
canvas.height = canvasHeight;
ctx = canvas.getContext("2d");
draw();
}
}();
canvas {
display: block;
margin: auto;
border: solid 2px black;
border-radius: 10px;
}
<!doctype html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<canvas id="canvas"></canvas>
</body>
</html>

How to draw rectangle in canvas which is already in pdf.js

am using pdf.js here am rendering my pdf in canvas,
My code is:
<div id="viewerContainer" tabindex="0">
<div id="viewer" class="pdfViewer"></div>
</div>
The above canvas is generating through viewer.js
Now I am trying to draw rectangle on my pdf, but its not showing my rectangle,
My script is in below:
<script type="text/javascript">
var canvas, context, startX, endX, startY, endY;
var mouseIsDown = 0;
function init() {
canvas = document.getElementById("page1");
context = canvas.getContext("2d");
canvas.addEventListener("mousedown", mouseDown, false);
canvas.addEventListener("mousemove", mouseXY, false);
canvas.addEventListener("mouseup", mouseUp, false);
}
function mouseUp() {
if (mouseIsDown !== 0) {
mouseIsDown = 0;
drawSquare(); //update on mouse-up
}
}
function mouseDown() {
mouseIsDown = 1;
startX = endX = event.clientX - canvas.offsetLeft; //remember to subtract
startY = endY = event.clientY - canvas.offsetTop; //canvas offset
drawSquare(); //update
}
function mouseXY(eve) {
if (mouseIsDown !== 0) {
if (!eve) {
var eve = event;
}
endX = event.pageX - canvas.offsetLeft;
endY = event.pageY - canvas.offsetTop;
drawSquare();
}
}
function drawSquare() {
// creating a square
var width = Math.abs(startX - endX);
var height = Math.abs(startY - endY);
context.clearRect(0, 0, context.width, context.height);
//or use fillRect if you use a bg color
context.beginPath();
context.rect(startX, startY, width, height);
context.fillStyle = "yellow";
context.fill();
context.lineWidth = 7;
context.strokeStyle = 'black';
context.stroke();
}
</script>
viwer.js code:
var canvasWrapper = document.createElement('div');
canvasWrapper.style.width = div.style.width;
canvasWrapper.style.height = div.style.height;
canvasWrapper.classList.add('canvasWrapper');
if (this.annotationLayer && this.annotationLayer.div) {
div.insertBefore(canvasWrapper, this.annotationLayer.div);
} else {
div.appendChild(canvasWrapper);
}
var textLayer = null;
if (this.textLayerFactory) {
var textLayerDiv = document.createElement('div');
textLayerDiv.className = 'textLayer';
textLayerDiv.style.width = canvasWrapper.style.width;
textLayerDiv.style.height = canvasWrapper.style.height;
if (this.annotationLayer && this.annotationLayer.div) {
div.insertBefore(textLayerDiv, this.annotationLayer.div);
} else {
div.appendChild(textLayerDiv);
}
textLayer = this.textLayerFactory.createTextLayerBuilder(textLayerDiv, this.id - 1, this.viewport, this.enhanceTextSelection);
}
var viewport = this.viewport;
var canvas = document.createElement('canvas');
canvas.id = this.renderingId;
canvas.setAttribute('hidden', 'hidden');
var isCanvasHidden = true;
var showCanvas = function showCanvas() {
if (isCanvasHidden) {
canvas.removeAttribute('hidden');
isCanvasHidden = false;
}
};
canvasWrapper.appendChild(canvas);
Is there any mistake in my code? I have searched many source but I could not able to find the correct one. Kindly help me in this issue.

Dragging a circle on a canvas using mousedown

Right now, I have 2 circles and a line in between. I want to be able to drag one of the circles with the line still attached and it will stay connected to the circle as I move it.
The node1 and node2 are the circle dimensions. The line/muscle is connected to node1 and node2's x and y position.
function draw() {
//draw in the container
c.fillStyle = "#000000";
c.fillRect(container.y, container.x, container.width, container.height);
//draw first node
c.arc(node1.x, node1.y, node1.r, 0, 2*Math.PI);
c.fillStyle = node1.color;
c.fill();
//draw second node
c.arc(node2.x, node2.y, node2.r, 0, 2*Math.PI);
c.strokeStyle = node2.color;
c.fillStyle = node2.color;
c.fill();
//draw muscle
c.beginPath();
c.moveTo(muscle.node1x, muscle.node1y);
c.lineTo(muscle.node2x, muscle.node2y);
c.strokeStyle = muscle.color;
c.lineWidth = muscle.width;
c.stroke();
}
How the project looks so far
The following code is based on your draw function and implements the drag function.
function draw(container, c, node1, node2, muscle) {
//draw in the container
c.fillStyle = "#000000";
c.fillRect(container.y, container.x, container.width, container.height);
//draw first node
c.arc(node1.x, node1.y, node1.r, 0, 2 * Math.PI);
c.fillStyle = node1.color;
c.closePath();
c.fill();
//draw second node
c.arc(node2.x, node2.y, node2.r, 0, 2 * Math.PI);
c.strokeStyle = node2.color;
c.fillStyle = node2.color;
c.closePath();
c.fill();
//draw muscle
c.beginPath();
c.moveTo(muscle.node1x, muscle.node1y);
c.lineTo(muscle.node2x, muscle.node2y);
c.strokeStyle = muscle.color;
c.lineWidth = muscle.width;
c.closePath();
c.stroke();
}
function Node(x, y, r, color) {
this.x = x;
this.y = y;
this.r = r || 20;
this.color = color || "#ff0";
}
function Muscle(node1, node2, width, color) {
this.node1 = node1;
this.node2 = node2;
this.width = width || 5;
this.color = color || "#f00";
Object.defineProperties(this, {
node1x: {
"get": () => this.node1.x,
"set": x => { this.node1.x = x }
},
node1y: {
"get": () => this.node1.y,
"set": y => { this.node1.y = y }
},
node2x: {
"get": () => this.node2.x,
"set": x => { this.node2.x = x }
},
node2y: {
"get": () => this.node2.y,
"set": y => { this.node2.y = y }
}
})
}
function handleMouseDrag(canvas, nodes) {
var isDrag = false;
var offset = { x: 0, y: 0, x0: 0, y0: 0 };
var dragNode = undefined;
canvas.addEventListener("mousedown", function (e) {
var x = e.offsetX, y = e.offsetY;
for (var i in nodes) {
if (Math.pow(x - nodes[i].x, 2) + Math.pow(y - nodes[i].y, 2) < Math.pow(nodes[i].r, 2)) {
isDrag = true;
dragNode = nodes[i];
offset = { x: dragNode.x, y: dragNode.y, x0: x, y0: y };
return;
}
}
});
canvas.addEventListener("mousemove", function (e) {
if (isDrag) {
dragNode.x = e.offsetX - offset.x0 + offset.x;
dragNode.y = e.offsetY - offset.y0 + offset.y;
}
});
canvas.addEventListener("mouseup", function (e) {
isDrag = false;
});
canvas.addEventListener("mouseleave", function (e) {
isDrag = false;
});
}
function main() {
var node1 = new Node(40, 40);
var node2 = new Node(120, 120);
var muscle = new Muscle(node1, node2);
var canvas = document.getElementById("canvas");
var container = { x: 0, y: 0, get width() { return canvas.width }, get height() { return canvas.height } }
var ctx = canvas.getContext("2d");
handleMouseDrag(canvas, [node1, node2]);
function updateFrame() {
ctx.save();
draw(container, ctx, node1, node2, muscle);
ctx.restore();
requestAnimationFrame(updateFrame)
};
updateFrame();
}
main();
<canvas width="400" height="400" id="canvas"></canvas>

Touch move event not correct

I'm busy creating a small real time drawing app and got stuck trying to create a touchscreen system. It's partially working but when I touch and move the line connects to the last line.
Here's my code:
document.addEventListener("DOMContentLoaded", function() {
var mouse = {
click: false,
move: false,
pos: {x:0, y:0},
pos_prev: false,
colour: "blue"
};
var canvas = document.getElementById('drawing');
var ctx = canvas.getContext('2d');
var width = window.innerWidth;
var height = window.innerHeight;
var socket = io.connect();
canvas.width = width;
canvas.height = height;
/* window.onresize= function(){
var width = window.innerWidth;
var height = window.innerHeight;
console.log(height);
canvas.style.width = width;
canvas.style.height = height;
}; */
canvas.onmousedown = function(e){ mouse.click = true; };
canvas.onmouseup = function(e){ mouse.click = false; };
canvas.ontouchstart = function(e){ mouse.click = true; };
canvas.ontouchend = function(e){ mouse.click = false; };
canvas.onmousemove = function(e) {
mouse.pos.x = e.clientX / width;
mouse.pos.y = e.clientY / height;
mouse.pos.w = document.getElementById("rag").value;
mouse.move = true;
};
canvas.ontouchmove = function(e) {
var touch = e.touches[0];
var x = touch.pageX - canvas.offsetLeft;
var y = touch.pageY - canvas.offsetTop;
mouse.pos.x = x / width;
mouse.pos.y = y / height;
console.log(mouse.pos.x);
mouse.pos.w = document.getElementById("rag").value;
mouse.move = true;
};
socket.on('draw_line', function (data) {
var line = data.line;
ctx.strokeStyle = line[2];
ctx.lineWidth = line[0].w;
ctx.beginPath();
ctx.moveTo(line[0].x * width, line[0].y * height);
ctx.lineTo(line[1].x * width, line[1].y * height);
ctx.stroke();
});
socket.on('clear', function () {
ctx.clearRect(0,0,width,height);
});
function mainLoop() {
if (mouse.click && mouse.move && mouse.pos_prev) {
mouse.colour = document.getElementById("col").value;
socket.emit('draw_line', { line: [ mouse.pos, mouse.pos_prev, mouse.colour]});
mouse.move = false;
}
mouse.pos_prev = {x: mouse.pos.x, y: mouse.pos.y};
setTimeout(mainLoop, 20);
}
mainLoop();
});
A life example can be found here:
http://80.61.54.121:88/
Does anyone know how to fix the lines connecting with eacother? Thanks in advance.

Categories

Resources