Dragging a circle on a canvas using mousedown - javascript

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>

Related

Using Canvas to draw multiple polygons but can not get color to be different for polygons

I an issue with the implementation of drawing multiple polygons on a canvas.
I draw the two polygons,
when I move the mouse into the 2nd polygon it turns red and so does the first polygon (the first polygon should be blue). When I move the mouse into the 1st polygon it turns red and so does the 2nd polygon (the 2nd polygon should be blue).
I found the issue with research of each canvas call; adding a ctx.beginPath() fixed the issue. See below:
<canvas id="myCanvas" width=600 height=600 ></canvas>
<script>
canvas = document.getElementById('myCanvas');
ctx = canvas.getContext('2d');
myimage = new Image();
myimage.src = 'https://i.postimg.cc/SNjPPZGJ/farms-map.png';
myimage.onload = draw
const rect = canvas.getBoundingClientRect();
const polypoints1 = [{x: 200, y: 29}, {x: 500, y: 19}, {x: 465, y: 146}, {x: 130, y: 150}];
const polypoints2 = [{x: 200, y: 229}, {x: 500, y: 219}, {x: 465, y: 346}, {x: 130, y: 350}];
var polyColor = [];
var dragPoint = null;
draw();
canvas.addEventListener('mousedown', onMouseDown);
canvas.addEventListener('mousemove', function(evt) {
polyColor[0]="blue";
polyColor[1]="blue";
if (inside({x:evt.clientX - rect.left, y:(evt.clientY + window.scrollY) - rect.top}, polypoints1)){
polyColor[0]="red";
polyColor[1]="blue";}
if (inside({x:evt.clientX - rect.left, y:(evt.clientY + window.scrollY) - rect.top}, polypoints2)){
polyColor[0]="blue";
polyColor[1]="red";}
draw()
}, false);
function inside(p, vs) {
var inside = false;
for (var i = 0, j = vs.length - 1; i < vs.length; j = i++) {
var xi = vs[i].x, yi = vs[i].y;
var xj = vs[j].x, yj = vs[j].y;
var intersect = ((yi > p.y) != (yj > p.y)) && (p.x < (xj - xi) * (p.y - yi) / (yj - yi) + xi);
if (intersect) inside = !inside;
}
return inside;
};
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
if (myimage) {
ctx.drawImage(myimage, 1, 1)
}
drawLines();
polypoints1.forEach(p => drawPoint(p));
polypoints2.forEach(p => drawPoint(p));
}
function drawPoint(p) {
ctx.beginPath();
ctx.globalAlpha = 1
ctx.fillStyle = "black";
ctx.lineWidth = 2;
ctx.arc(p.x, p.y, 5, 0, 2 * Math.PI, false);
ctx.stroke();
ctx.fill();
}
function drawLines() {
ctx.beginPath();
ctx.lineWidth = 2;
polypoints1.forEach(p => ctx.lineTo(p.x, p.y));
ctx.lineTo(polypoints1[0].x, polypoints1[0].y);
ctx.stroke();
if (!dragPoint) {
ctx.globalAlpha = 0.2
ctx.fillStyle = polyColor[0];
ctx.fill();
}
ctx.beginPath();
ctx.lineWidth = 2;
polypoints2.forEach(p => ctx.lineTo(p.x, p.y));
ctx.lineTo(polypoints2[0].x, polypoints2[0].y);
ctx.stroke();
if (!dragPoint) {
ctx.globalAlpha = 0.2
ctx.fillStyle = polyColor[1];
ctx.fill();
}
}
function findDragPoint(x, y) {
for (i = 0; i < polypoints1.length; i++) {
if (hitTest(polypoints1[i], x, y)) return polypoints1[i];
if (hitTest(polypoints2[i], x, y)) return polypoints2[i];
};
return null;
}
function onMouseDown(event) {
dragPoint = findDragPoint(event.clientX - canvas.offsetLeft, event.clientY - canvas.offsetTop + window.scrollY);
if (dragPoint) {
dragPoint.x = event.clientX - canvas.offsetLeft;
dragPoint.y = event.clientY - canvas.offsetTop + window.scrollY;
draw();
canvas.addEventListener("mousemove", onMouseMove);
canvas.addEventListener("mouseup", onMouseUp);
}
}
function onMouseMove(event) {
dragPoint.x = event.clientX - canvas.offsetLeft;
dragPoint.y = event.clientY - canvas.offsetTop+ window.scrollY;
draw();
}
function onMouseUp() {
dragPoint = null;
draw();
canvas.removeEventListener("mousemove", onMouseMove);
canvas.removeEventListener("mouseup", onMouseUp);
}
function hitTest(p, x, y) {
var dx = p.x - x, dy = p.y - y;
return Math.sqrt(dx * dx + dy * dy) <= 10;
}
</script>
I found that you have to use ctx.beginPath() before you start to set up the second polygon. This seems to have addressed the issue.

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>

Limit values between two points on an arc?

I'm trying to adapt the code from a previous question on circular dial controls. The concept is pretty similar to this one, except I would like to define a range in which the dial cannot be selected. Consider the volume controls/dials in hardware; they often have these 'dead zones' where they can't be turned:
How can I replicate this in JavaScript? Here's the adapted code so far:
function Dial(size) {
var dial = this;
var canvas = document.querySelector('#c');
var ctx = canvas.getContext("2d");
var pi2 = Math.PI*2;
this.from = 0.75 * Math.PI;
this.to = 0.25 * Math.PI;
this.value = this.from;
var radius = size / 2 - 10;
this.draw = function() {
ctx.save();
ctx.clearRect(0,0,size,size);
ctx.translate(size/2,size/2);
ctx.beginPath();
ctx.strokeStyle = "silver";
ctx.lineWidth = 2;
ctx.arc(0, 0, radius, this.from, this.to);
ctx.stroke();
ctx.beginPath();
ctx.lineWidth = 1;
ctx.fillStyle = "green";
ctx.strokeStyle = "black";
ctx.arc(-radius*Math.sin(this.value),
-radius*Math.cos(this.value),
8, 0, 2*Math.PI);
ctx.fill();
ctx.stroke();
ctx.restore();
};
var getMousePos = function(canvas, evt) {
return {
x: event.pageX - canvas.offsetLeft,
y: event.pageY - canvas.offsetTop
};
};
var inBounds = function(pos) {
return Math.hypot(
size / 2 - radius * Math.sin(dial.value) - pos.x,
size / 2 - radius * Math.cos(dial.value) - pos.y
) <= 8;
};
canvas.addEventListener("mousemove", function(evt) {
var pos = getMousePos(canvas, evt);
if (dial.markerMoving) {
if (pos.x == size/2 && pos.y == size/2)
return;
dial.value = Math.atan2(size/2-pos.x,size/2-pos.y);
}
dial.draw();
}, false);
canvas.addEventListener("mousedown", function(evt) {
var pos = getMousePos(canvas, evt);
dial.markerMoving = inBounds(pos);
}, false);
canvas.addEventListener("mouseup", function(evt) {
dial.markerMoving = false;
}, false);
this.draw();
};
new Dial(150);
<canvas id="c"></canvas>
Bonus points if you can work out how to display a 'range' on the selection - from the starting point on the dial to the selection point.
Turns out it was pretty straightforward, using Math.abs.
function Dial(size) {
var dial = this;
var canvas = document.querySelector('#c');
var ctx = canvas.getContext("2d");
var pi2 = Math.PI*2;
this.from = 0.75 * Math.PI;
this.to = 0.25 * Math.PI;
this.value = this.from;
var radius = size / 2 - 10;
this.draw = function() {
ctx.save();
ctx.clearRect(0,0,size,size);
ctx.translate(size/2,size/2);
ctx.beginPath();
ctx.strokeStyle = "silver";
ctx.lineWidth = 2;
ctx.arc(0, 0, radius, this.from, this.to);
ctx.stroke();
ctx.beginPath();
ctx.lineWidth = 1;
ctx.fillStyle = "green";
ctx.strokeStyle = "black";
ctx.arc(-radius*Math.sin(this.value),
-radius*Math.cos(this.value),
8, 0, 2*Math.PI);
ctx.fill();
ctx.stroke();
ctx.restore();
};
var getMousePos = function(canvas, evt) {
return {
x: event.pageX - canvas.offsetLeft,
y: event.pageY - canvas.offsetTop
};
};
var inBounds = function(pos) {
return Math.hypot(
size / 2 - radius * Math.sin(dial.value) - pos.x,
size / 2 - radius * Math.cos(dial.value) - pos.y
) <= 8;
};
canvas.addEventListener("mousemove", function(evt) {
var pos = getMousePos(canvas, evt);
if (dial.markerMoving) {
if (pos.x == size/2 && pos.y == size/2) {
return;
}
var radians = Math.atan2(size/2-pos.x,size/2-pos.y);
if (Math.abs(radians) < dial.from) {
dial.value = radians;
dial.draw();
}
}
}, false);
canvas.addEventListener("mousedown", function(evt) {
var pos = getMousePos(canvas, evt);
dial.markerMoving = inBounds(pos);
}, false);
canvas.addEventListener("mouseup", function(evt) {
dial.markerMoving = false;
}, false);
this.draw();
};
new Dial(150);
<canvas id="c"></canvas>

HTML5 Canvas Javascript how to make smooth brush

Hello i need make smooth brush likes this:
I try to create it, i make circle and fill it, but result not successful:
Can be seen circles.. this is not smooth like first example
my example code:
function distanceBetween(point1, point2) {
return Math.sqrt(Math.pow(point2.x - point1.x, 2) + Math.pow(point2.y - point1.y, 2));
}
function angleBetween(point1, point2) {
return Math.atan2( point2.x - point1.x, point2.y - point1.y );
}
var el = document.getElementById('c');
var ctx = el.getContext('2d');
//ctx.fillStyle = "rgba('255, 0, 0, 0.1')";
ctx.fillStyle = "red";
ctx.strokeStyle = "red";
ctx.globalAlpha = "0.05";
ctx.lineWidth = 0;
ctx.globalCompositeOperation = "source-over";
var isDrawing, lastPoint;
el.onmousedown = function(e) {
isDrawing = true;
lastPoint = { x: e.clientX, y: e.clientY };
};
el.onmousemove = function(e) {
if (!isDrawing) return;
var currentPoint = { x: e.clientX, y: e.clientY };
var dist = distanceBetween(lastPoint, currentPoint);
var angle = angleBetween(lastPoint, currentPoint);
for (var i = 0; i < dist; i+=5) {
x = lastPoint.x + (Math.sin(angle) * i) - 25;
y = lastPoint.y + (Math.cos(angle) * i) - 25;
ctx.beginPath();
ctx.arc(x+10, y+10, 20, false, Math.PI * 2, false);
ctx.closePath();
ctx.fill();
ctx.stroke();
}
lastPoint = currentPoint;
};
el.onmouseup = function() {
isDrawing = false;
};
function clearit() {
ctx.clearRect(0,0, 1000, 1000);
}
canvas { border: 1px solid #ccc }
<canvas id="c" width="500" height="300"></canvas>
<input type="button" id="clear-btn" value="Clear it" onclick="clearit()">
http://codepen.io/anon/pen/NPjwry
Try with a smaller globalAlpha and decrease the stepping (so you draw more circles)
function distanceBetween(point1, point2) {
return Math.sqrt(Math.pow(point2.x - point1.x, 2) + Math.pow(point2.y - point1.y, 2));
}
function angleBetween(point1, point2) {
return Math.atan2( point2.x - point1.x, point2.y - point1.y );
}
var el = document.getElementById('c');
var ctx = el.getContext('2d');
//ctx.fillStyle = "rgba('255, 0, 0, 0.1')";
ctx.fillStyle = "red";
ctx.strokeStyle = "red";
ctx.globalAlpha = "0.01";
ctx.lineWidth = 0;
ctx.globalCompositeOperation = "source-over";
var isDrawing, lastPoint;
el.onmousedown = function(e) {
isDrawing = true;
lastPoint = { x: e.clientX, y: e.clientY };
};
el.onmousemove = function(e) {
if (!isDrawing) return;
var currentPoint = { x: e.clientX, y: e.clientY };
var dist = distanceBetween(lastPoint, currentPoint);
var angle = angleBetween(lastPoint, currentPoint);
for (var i = 0; i < dist; i+=3) {
x = lastPoint.x + (Math.sin(angle) * i) - 25;
y = lastPoint.y + (Math.cos(angle) * i) - 25;
ctx.beginPath();
ctx.arc(x+10, y+10, 20, false, Math.PI * 2, false);
ctx.closePath();
ctx.fill();
ctx.stroke();
}
lastPoint = currentPoint;
};
el.onmouseup = function() {
isDrawing = false;
};
function clearit() {
ctx.clearRect(0,0, 1000, 1000);
}
canvas { border: 1px solid #ccc }
<canvas id="c" width="500" height="300"></canvas>
<input type="button" id="clear-btn" value="Clear it" onclick="clearit()">
Updated codepen: http://codepen.io/gpetrioli/pen/ramqBz
There is more simple solution: just set width of line to 25px
let ctx = this.d.transparentUpdateImage.getContext('2d');
if (!this.lastPos) {
this.lastPos = {x: x, y: y};
return
}
ctx.beginPath();
ctx.moveTo(this.lastPos.x, this.lastPos.y);
ctx.lineCap = 'round';
ctx.lineJoin = 'round';
ctx.strokeStyle = 'red';
ctx.lineWidth = 25;
ctx.lineTo(x, y);
ctx.stroke();
ctx.closePath();
this.lastPos = {x: x, y: y};

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

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();

Categories

Resources