Move a HTML5 Canvas Element - javascript

I'm making a small jigsaw like puzzle in html5. Each jigsaw piece is it's own canvas. I need to move the canvas element using the mouse position. I've managed to get the canvas that is clicked, I just need to move it. I tried manipulating the top and left style attributes but the canvas didn't move. Can this be done or am I trying something impossible.
Thanks!
function MouseDown(can, e)
{
MovingCanvas = can;
clicked = true;
}
function MouseMove(e)
{
if(clicked)
{
var mx = e.clientX;
var my = e.clientY;
MovingCanvas.style.top = my;
MovingCanvas.style.left = mx;
}
}

e.clientX and e.clientY are integers.
Styles expect a string of the form {NUMBER}{UNIT}.
You are missing a unit, therefore it won't work.
MovingCanvas.style.top = my+"px";
MovingCanvas.style.left = mx+"px";

Related

How do get I the clickable point from a html element?

how do I get the x,y coordinates from a HTML element relative to screen?
I'm using x,y from getBoundingClientRect() as below, but as you can see in the blow image, if I use move the cursor to this x,y position, the curson is in the middle between 0 and + buttons not the 5 button, which is the target button.
What am I missing?
JS code:
var e = document.querySelector('input[id=five]');"
var r = e.getBoundingClientRect();
var x = r.x;
var y = r.y;
MoveMouseTo(x,y); // imaginary call, the real cursor move is done by C# but I can share the code, as needed.
Image:
NOTE: if this aditional info may help, it's a C# application with embedded browser.
const getCoords = (e) => {
var x = e.clientX
var y = e.clientY
var xx = e.screenX
var yy = e.screenY
console.log(x, y, "client")
console.log(xx, yy, "screen")
}
You're going to want to assign this function to a onmousemove event to the outermost div containing the UI for your calculator. This should at least show you the difference between a screen X,Y and a client X,Y
https://www.w3schools.com/code/tryit.asp?filename=FVXZOK1SPTR0
You can try to add an event listener on your element and use the event to retrieve the coordinates of the mouse.
const $element = document.querySelector('input[id=five]');
$element.addEventListener('mousemove', handleMouseMove);
function handleMouseMove (event) {
console.log('Offset from the screen coordinates', event.screenX, event.screenY);
// The client refers to the element you are bound to;
console.log('Offset from the client coordinates', event.clientX, event.clientY);
};

Hover on images in a canvas

I am trying to make a simple point and click game with canvas and i'd like to change the cursor to pointer when i hover on a drawn image and change it back to default when i hover off. So i was trying to make an onhover function for each object on my canvas. Is there any easy way to check if i hover over an image ?
My code looks something like this so far :
//heres an object for my canvas
var cupboard = {
x:200,
y:320,
h:300,
w:180,
imgUrl:"data\\cbc.png",
type:2,
status:'c',
onhover: function(e,canvas)
{
if((e.x >= this.x && e.x <= this.x+this.w) &&(e.y >= this.y && e.y <=
this.y+this.h)){
canvas.style.cursor = "pointer";
}
else
{
canvas.style.cursor = "default";
}
}
//i use an array for these objects
room1[cupboard,silverkey];
//heres the event listener
document.getElementById("mainCanvas").addEventListener("mousemove",
function(evt){
var mousepos = getMousePos(document.getElementById("mainCanvas"),evt);
for(i in room1)
{
(function(m){
room1[m].onhover(mousepos,document.getElementById("mainCanvas"));
})(i);
}
});
I had a look online for a solution and cam across this page :
Add onclick and onmouseover to canvas element
markE's answer is very long but could be useful for you, especially the part about '.isPointInside'.
Hope this helps!

How to convert screen coordinates to scene coordinates

I created a a-scene with some objects to drag. The final purpose is exactly what aframe-click-drag-component does. Unfortunately, this component is not compatible with the last version of A-Frame.
I created a custom component.
AFRAME.registerComponent('draggable', {
init: function () {
/* Some code */
}
});
I use the aframe-mouse-cursor-component to be able to get the mouseenter and mouseleave events on the draggable object, and detect when the mouse position allows the user to select the object.
I added an EventListener on document.body to know when the dragging starts:
document.body.addEventListener('mousedown', function (e) {
// start dragging
});
I continuously update a global variable to update the mouse position when a mousemove occurs:
document.addEventListener('DOMContentLoaded', function () {
document.body.addEventListener('mousemove', function (e) {
window.mouseX = e.clientX;
window.mouseY = e.clientY;
});
});
This way, I can easily get the position of the mouse during the dragging. But I do not know how to convert the position of the mouse on the client to a position in the Virtual Reality (restricted to a 2D plan to make it possible).
I solved this issue by using the raycaster coming from the cursor in the middle of the a-camera, but I want to drag the objects with the mouse-cursor, and this component does not have a raycaster.
I also tried to use some maths to convert the mouse coordinates to a coordinates set relative to the camera, without success (essentially because of the screen size which can vary).
What solutions are available? I would like to update the click-drag or the mouse-cursor, but I have no knowledge of THREE.js.
See https://github.com/mayognaise/aframe-mouse-cursor-component or https://github.com/mrdoob/three.js/blob/dev/examples/js/controls/DragControls.js or https://www.npmjs.com/package/aframe-click-drag-component for examples
The main chunk of code is like:
canvas.addEventListener( 'mousemove', function () {
var mouse = new THREE.Vector2();
var rect = canvas.getBoundingClientRect();
mouse.x = ( (event.clientX - rect.left) / rect.width ) * 2 - 1;
mouse.y = - ( (event.clientY - rect.top) / rect.height ) * 2 + 1;
raycaster.setFromCamera( mouse, camera );
}, false);

Trying to drag ship on canvas from left to right in Space Invaders clone

I have a "ship" that I have drawn on my canvas and I want to be able to drag it left and right on the bottom of the canvas when it is clicked. I have done some research but I'm having no luck.
I'm assuming I use onMouseDown to do this so I have this when the page loads...
canGame.onMouseDown = canCanvas.onMouseDown(e);
and here is the code that creates my ship
gShip = spriteNew("MediumSpringGreen", 230, 950, 150, 20);
From there I am not really sure what to do. I have a gameUpdate function which moves the invaders down the screen. A gameInit function that will draw the invaders and ship on the screen. Also I have a gameDraw function which draws everything on the screen. I have a few others which are not really important for my issue.
Here is the jsfiddle with the full source code. For some reason though it will run on my browser when I run the HTM file but not in jsfiddle.
http://jsfiddle.net/f66bk/2/
Like I said in comment, the best way of doing this kind of behaviour is by using the events mouseup, mousedown and mousemove.
I defined a var named isMouseDown to know that the ship is dragged that I set to true on mousedown and false on mouseup:
canGame.onMouseDown = function() { isMouseDown = true }
canGame.onMouseUp = function() { isMouseDown = false }
You will also need the event onmousemove to get your mouse position to redraw your ship properly:
canGame.onMouseUp = function(event) { moveShip(event, this) }
In the function moveShip, you can get your mouse position and set the position of your ship properly:
function moveShip(evt, obj) {
if(!isMouseDown)
return;
var target = evt.target || evt.srcElement,
rect = target.getBoundingClientRect(),
offsetX = evt.clientX - rect.left;
gShip.Rect.X = offsetX - gShip.Rect.Width/2;
}
Here is your jsfiddle :)

How to implement drag and drop for HTML5 Canvas painting application?

Based on Creating an HTML 5 canvas painting application I created a HTML5 canvas painting application. It works fine, but after creating each object I just need to drag the objects.
Working demo
How to implement drag and drop of the figures?
When the user clicks on the canvas, you have to check the coordinates (compare it to the coordinates for the objects), and see if it's on an object. E.g. You can test if a point (e.g. the coordinates for the mousedown even) is within a circle with this method:
function (pt) {
return Math.pow(pt.x - point.x,2) + Math.pow(pt.y - point.y,2) <
Math.pow(radius,2);
};
If the mousedown is on the object, you have to change the objects coordinates according to how the mouse is moved.
Here is an example, where you can drag a circle:
<!DOCTYPE html>
<html>
<head>
<script>
window.onload = function() {
drawCircle(circle);
element = document.getElementById('canvas');
element.addEventListener('mousedown', startDragging, false);
element.addEventListener('mousemove', drag, false);
element.addEventListener('mouseup', stopDragging, false);
element.addEventListener('mouseout', stopDragging, false);
}
function mouseX(e) {
return e.clientX - element.offsetLeft;
}
function mouseY(e) {
return e.clientY - element.offsetTop;
}
var Point = function (x, y) {
this.x = x;
this.y = y;
return this;
}
var Circle = function (point, radius) {
this.point = point;
this.radius = radius;
this.isInside = function (pt) {
return Math.pow(pt.x - point.x, 2) + Math.pow(pt.y - point.y, 2) <
Math.pow(radius, 2);
};
return this;
}
function startDragging(e) {
var p = new Point(e.offsetX, e.offsetY);
if(circle.isInside(p)) {
deltaCenter = new Point(p.x - circle.point.x, p.y - circle.point.y);
}
}
function drag(e) {
if(deltaCenter != null) {
circle.point.x = (mouseX(e) - deltaCenter.x);
circle.point.y = (mouseY(e) - deltaCenter.y);
drawCircle(circle);
}
}
function stopDragging(e) {
deltaCenter = null;
}
function drawCircle(circle) {
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.beginPath();
ctx.arc(circle.point.x, circle.point.y, circle.radius, 0, Math.PI*2, true);
ctx.fill();
}
var circle = new Circle(new Point(30, 40), 25);
var deltaCenter = null;
var element;
</script>
</head>
<body>
<canvas id="canvas" width="400" height="300"></canvas>
</body>
</html>
Try it on jsFiddle
The same effect can be accomplished using Raphael.js (http://raphaeljs.com/) with Joint.jS (http://www.jointjs.com/).
Shapes created with Raphael can be accessed like any DOM element and can be manipulated via attributes. It is an awesome framework.
Joint.js helps in connecting the shapes. They also have a diagramming library and can help create ERD, Statemachine and several common diagrams. The best part is that you can extend their diagram element and create your own custom elements. Its jaw-dropingly cool.
Checkout their demos with source code at http://www.jointjs.com/demos
If you are using the raphael as "raw" lib you must handle the undo/redo by yourself.
The graphiti lib did have Undo/Redo Stack inside and supports the export for SVG, PNG, JSON,...
Additional you have some kind of Viso like connectors and ports.
http://www.draw2d.org/graphiti/jsdoc/#!/example
Greetings
I don't think there's an easy way to do this.
If you're just dealing with lines, my approach would be to keep track of all lines created, with starting coordinates, ending coordinates and some kind of z-index. When the user starts a dragging action (onmousedown), you have to check if the point is near the line, and then update the object and redraw the canvas when the mouse is moved.
How can I tell if a point belongs to a certain line?
This gets a lot more complicated if you're dealing with complex objects though. You'll probably have to find a solution to check if a point is inside a path.
Objects drawn into HTML5 Canvas are turned into pixels and then forgotten. You can't adjust properties on them and have the canvas update to see the effects. You can remember them yourself, but the canvas will still have those pixels set, so you'd have to basically redraw the whole canvas (or at least some of it) when you adjust a property.
You might want to consider SVG for this application instead, SVG elements are remembered in the DOM and when their properties are updated the browser will update the graphic to reflect the changes.
If you must use canvas, then you're going to need to write quite a bit of code to handle mouse-hits, object properties, and repaints.

Categories

Resources