var canvas = document.getElementById('mainCanvas');
var ctx = canvas.getContext('2d');
var status = document.getElementById('status');
var click = document.getElementById('click');
var hover = document.getElementById('hover');
canvas.style.backgroundColor = 'red';
var mouseX;
var mouseY;
var item1 = new item('item1', ctx);
item1.drawItem(50, 50);
var item2 = new item('item2', ctx);
item2.drawItem(150, 200);
var item3 = new item('item3', ctx);
item3.drawItem(200, 250);
var items = [item1, item2, item3];
canvas.addEventListener('mousemove', mouseMoveHandler, false);
canvas.addEventListener('click', mouseClickHandler, false);
function mouseMoveHandler(event) {
mouseX = event.clientX - canvas.getBoundingClientRect().left;
mouseY = event.clientY - canvas.getBoundingClientRect().top;
for (var i = 0; i < items.length; i++) {
if (mouseX > items[i].x & mouseY > items[i].y &
mouseX < items[i].x + items[i].width & mouseY < items[i].y + items[i].height) {
hover.innerHTML = items[i].name;
} else {
hover.innerHTML = 'No';
}
}
}
function mouseClickHandler(event) {
click.innerHTML = mouseX + ' | ' + mouseY;
}
function item(name, ctx) {
this.x = undefined;
this.y = undefined;
this.width = 50;
this.height = 50;
this.name = name;
this.drawItem = function(x, y) {
ctx.fillRect(this.x = x, this.y = y, this.width, this.height);
}
}
<div class='canvas'>
<canvas id='mainCanvas' width='500' height='300'></canvas>
</div>
<p id='click'>0 | 0</p>
<p id='hover'>No</p>
What I'm trying to accomplish:
When the mouse hovers each square (or item) in the canvas, I want the name of the square (assigned as the first parameter when creating each item) to display as the hover element.
What I'm getting:
It somewhat works, but only with the last square. Whenever I hover over any other square that isn't the last one, the 'hover' element does not display the name of the square the mouse is over. I even created and added a new item to the 'items' array and it worked with the new one, but not with the others.
Your problem is that the for loop keeps running after you find a hit. Lets say you mouse item2. Your code will work and display 'item2'. Then the loop goes to the next step and checks if you hover over item3. You don't, so the code displays 'no'.
The solution is to stop the loop once you have a hit
if (mouseX > items[i].x &
mouseY > items[i].y &
mouseX < items[i].x + items[i].width &
mouseY < items[i].y + items[i].height
) {
hover.innerHTML = items[i].name;
break;
} else {
hover.innerHTML = 'No';
}
Related
I need help with a pretty difficult problem. I am currently making a game with React and Redux. In this game I use a canvas to create a map data from my redux store. Currently the map is just a matrix of black and white squares. Let's say that I wanted to change the color of a square when you click on it, but also maintain the ability to drag the element. The problem is that it is difficult to pinpoint exactly where the mouse is clicking given that the element can be dragged anywhere on the page. As far as I can tell, none of the mouseclick event object properties seem to be able to tell me. I thought offsetX and offsetY would tell me, but they don't seem to stay the same when the canvas object moves for some reason.
I am using React and Redux for this project, and the CanvasMap element is wrapped in a Draggable from this library: https://www.npmjs.com/package/react-draggable#draggablecore
import React from 'react'
import { connect } from 'react-redux'
import './CanvasMap.css'
class CanvasMap extends React.Component{
componentDidMount() {
const map = this.props.map //Data representing the map
const canvas = this.refs.canvas
const context = canvas.getContext('2d')
//Building the map on the canvas
for(let i = 0; i < map.length; i++){
for(let j = 0; j < map[i].length; j++){
const x=i*100
const y=j*100
const isBlackSquare= map[i][j] === 'black' ? true : false
if(isBlackSquare) context.fillRect(x, y, 100, 100)
else context.strokeRect(x, y, 100, 100)
}
}
function handleClick(e){
//None of the event properties seem to stay the same when the canvas is moved
console.log(e)
}
canvas.addEventListener('click', handleClick)
}
render(){
return (
<div className='Map'>
<canvas ref='canvas' width={8000} height={8000} />
</div>
)
}
}
function mapStateToProps(state){
return {
map: [...state.map]
}
}
const connectedComponent = connect(mapStateToProps)(CanvasMap)
export { connectedComponent as CanvasMap }
In most cases when you click on an HTML element you can use the rectangleBounding Box and get coordinators from that like
domRect = element.getBoundingClientRect();
in a canvas click position it is a little more difficult
Here is a script I did a while ago to draw while dragging the mouse the on the canvas .Maybe you can apply this method
<html>
<head>
<style>
* { margin:0; padding:0; } /* to remove the top and left whitespace */
html, body { width:100%; height:100%; } /* just to be sure these are full screen*/
canvas { display:block; } /* To remove the scrollbars */
</style>
</head>
<body>
<canvas id="canvas" ></canvas>
<script>
////////////////////////////////////////
(function() {
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var elemLeft = canvas.offsetLeft;
var elemTop = canvas.offsetTop;
var BB=canvas.getBoundingClientRect();
var offsetX=BB.left;
var offsetY=BB.top;
// resize the canvas to fill browser window dynamically
window.addEventListener('resize', resizeCanvas, false);
function resizeCanvas() {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
/**
* Your drawings need to be inside this function otherwise they will be reset when
* you resize the browser window and the canvas goes will be cleared.
*/
drawStuff();
}
resizeCanvas();
function drawStuff() {
// do your drawing stuff here
var img = new Image();
img.src = 'images/3PkBe.gif';
img.onload = function()
{
//var canvas = document.getElementById('canvas');
// create pattern
var ptrn = ctx.createPattern(img, 'repeat'); // Create a pattern with this image, and set it to "repeat".
ctx.fillStyle = ptrn;
ctx.fillRect(0, 0, canvas.width, canvas.height); // context.fillRect(x, y, width, height);
ctx.shadowBlur=20;
//ctx.shadowColor="black";
//ctx.fillStyle="green";
//ctx.fillRect(20,160,100,80);
ctx.strokeStyle = "lightgray";
//var canvasOffset = canvas.offset();
//var offsetX = canvasOffset.left;
//var offsetY = canvasOffset.top;
var mouseIsDown = false;
var lastX = 0;
var lastY = 0;
var elements = [];
makeShip( 30 , 30,120, 120, '#119' , "romea");
makeShip( 30, 160,120, 120, '#393', "fomar");
makeShip( 30, 290,120, 120, '#955', "ojab");
makeShip( 30, 420,120, 120, '#6ff', "eliot");
// Add event listener for `click` events.
canvas.addEventListener('click', function(event) {
var x = event.pageX - elemLeft,
y = event.pageY - elemTop;
console.info(x, y);
elements.forEach(function(element) {
if (y > element.y && y < element.y + element.height && x > element.x && x < element.x + element.width) {
console.log(element.name);
}
});
}, false);
canvas.addEventListener('mousedown', function(event) {
var x = event.pageX - elemLeft,
y = event.pageY - elemTop;
console.info(x, y);
elements.forEach(function(element) {
if (y > element.y && y < element.y + element.height && x > element.x && x < element.x + element.width) {
console.info(element.name);
handleMouseDown(element);
}
});
}, false);
canvas.addEventListener('mousemove', function(event) {
var x = event.pageX - elemLeft,
y = event.pageY - elemTop;
console.info(x, y);
elements.forEach(function(element) {
if (y > element.y && y < element.y + element.height && x > element.x && x < element.x + element.width) {
console.info(element.name);
handleMouseMove(element,x,y);
}
});
}, false);
canvas.addEventListener('mouseup', function(event) {
var x = event.pageX - elemLeft,
y = event.pageY - elemTop;
//console.info(x, y);
elements.forEach(function(element) {
//if (y > element.y && y < element.y + element.height && x > element.x && x < element.x + element.width) {
console.info(element.name + "mouse up evenr=========");
handleMouseUp(element);
//}
});
}, false);
function makeShip(x, y, width, height, colour,ShipName) {
var ship = {
name: ShipName,
colour: colour,
width: width,
height: height,
x: x,
y: y
}
elements.push(ship);
return (ship);
}
function drawShip(ship) {
//ctx.fillStyle = ship.colour;
//ctx.fillRect(ship.x, ship.y, ship.width, ship.height);
//ctx.fillRect(element.x, element.y, element.width, element.height);
}
function drawAllShips() {
// ctx.clearRect(0, 0, canvas.width, canvas.height);
for (var i = 0; i < elements.length; i++) {
var ship = elements[i]
//drawShip(ship);
ctx.fillStyle = ship.colour;
ctx.fillRect(ship.x , ship.y, ship.width, ship.height);
// ctx.fillStyle = ship.fill;
// ctx.fill();
// ctx.stroke();
}
}
// Add element.
//elements.push({
//colour: '#05EFFF',
//width: 150,
//height: 100,
//x: 20,
//y: 15
//});
// Render elements.
// elements.forEach(function(element) {
// ctx.fillStyle = element.colour;
// ctx.fillRect(element.x, element.y, element.width, element.height);
// });
drawAllShips();
function handleMouseDown(e) {
mouseX = e.x ;
mouseY = e.y ;
//mouseX = parseInt(e.x - offsetX);
//mouseY = parseInt(e.y - offsetY);
console.log("===========Problem "+mouseX);
// mousedown stuff here
lastX = mouseX;
lastY = mouseY;
mouseIsDown = true;
//alert("mouse Handle");
}
function handleMouseUp(e) {
//mouseX = parseInt(e.clientX - offsetX);
//mouseY = parseInt(e.clientY - offsetY);
ctx.onmousemove = null;
// mouseup stuff here
mouseIsDown = false;
return
}
function handleMouseMove(e,x,y) {
if (mouseIsDown) {
//console.log(' no fuck');
mouseX = e.x ;
mouseY = e.y ;
console.log(e.name+"is truing to drag");
// mousemove stuff here
//for (var i = 0; i < elements.length; i++) {
//if (ctx.isPointInPath(mouseX, mouseY)) {
//console.log('============== no fuck');
var ship =e;// elements[i];
ship.x = x-15;//(mouseX - lastX);
ship.y = y-20;//(mouseY -lastY);
// ship.right = ship.x + ship.width;
// ship.bottom = ship.y + ship.height;
//drawShip(ship);
//}
//}
lastX = mouseX;
lastY = mouseY;
drawAllShips();
}
}
<!-- ctx.mousedown(function (e) { -->
<!-- handleMouseDown(e); -->
<!-- }); -->
<!-- ctx.mousemove(function (e) { -->
<!-- handleMouseMove(e); -->
<!-- }); -->
<!-- ctx.mouseup(function (e) { -->
<!-- handleMouseUp(e); -->
<!-- }); -->
}
}
})();
</script>
</body>
</html>
SOLVED IT!
I got lost in the slew of data around elements and click events, I was trying to figure out the right combination of pageX, clientX, offsetLeft, screenX, etc. However, the final solution is incredibly simple once you know exactly what to do. Here it is:
function handleClick(e){
const rect = e.target.getBoundingClientRect()
const x = e.pageX - rect.left
const y = e.pageY - rect.top
}
This should get you the exact x and y coordinate of your mouse in relation to the element, no matter where you drag and reposition the element.
(english is not my native language, hope you cope on this)
I'm having trouble why is my text can't be dragged when I add another canvas on it.
Basically, what I wanted to happen is I can drag my text and draw, and when I click the button "DRAW" i will start to draw.
Here's my code :
// FUNCTION FOR DRAWING !!!
$(function() {
$.each(['#f00', '#ff0', '#0f0'], function() {
$('#colors_demo').append("<a href='#colors_sketch' data-color='" + this + "' style='width: 30px;height: 30px;display:inline-block; background: " + this + ";'></a> ");
});
$('#colors_sketch').sketch();
$('#colors_sketch').sketch({defaultColor: "#ff0"});
});
//FUNCTION FOR DISPLAY TEXT!!!
function cakeDedicationFree() {
if (document.getElementById('design3').checked) {
var canvas2 = document.getElementById("colors_sketch");
context = canvas2.getContext("2d");
var $canvas2 = $("#colors_sketch");
var canvasOffset = $canvas2.offset();
var offsetX = canvasOffset.left;
var offsetY = canvasOffset.top;
var scrollX = $canvas2.scrollLeft();
var scrollY = $canvas2.scrollTop();
var startX;
var startY;
var texts = []; // an array to hold text objects
var selectedText = -1;// this var will hold the index of the hit-selected text
function draw()
{ // clear the canvas & redraw all texts
context.clearRect(0, 0, canvas2.width, canvas2.height);
for (var i = 0; i < texts.length; i++)
{
var text = texts[i];
context.fillText(text.text, text.x, text.y);
}
}
function textHittest(x, y, textIndex) { // test if x,y is inside the bounding box of texts[textIndex]
var text = texts[textIndex];
return (x >= text.x && x <= text.x + text.width && y >= text.y - text.height && y <= text.y);
}
function handleMouseDown(d) {
d.preventDefault();
startX = parseInt(d.clientX - offsetX);
startY = parseInt(d.clientY - offsetY);
for (var i = 0; i < texts.length; i++) {
if (textHittest(startX, startY, i)) {
selectedText = i; } }
}
function handleMouseUp(d) { // done dragging
d.preventDefault();
selectedText = -1; }
function handleMouseOut(d) { // also done dragging
d.preventDefault();
selectedText = -1; }
function handleMouseMove(d) {
if (selectedText < 0) { return; }
d.preventDefault();
mouseX = parseInt(d.clientX - offsetX);
mouseY = parseInt(d.clientY - offsetY);
var dx = mouseX - startX;
var dy = mouseY - startY;
startX = mouseX;
startY = mouseY;
var text = texts[selectedText];
text.x += dx;
text.y += dy;
draw(); }
$("#colors_sketch").mousedown(function (d) { handleMouseDown(d); }); // listen for mouse events
$("#colors_sketch").mousemove(function (d) { handleMouseMove(d); });
$("#colors_sketch").mouseup(function (d) { handleMouseUp(d); });
$("#colors_sketch").mouseout(function (d) { handleMouseOut(d); });
$("#text_dedi").click(function () {
var y = texts.length * 20 + 20;
var text = { text: $("#dedi_text").val(),
x: 20,
y: y
};
context.font = "30px Roboto";
text.width = context.measureText(text.text).width;
text.height = 16;
text.color = "#fff";
texts.push(text); // put this new text in the texts array
draw(); // redraw everything
});
document.getElementById('clear').addEventListener('click', function() {
context.clearRect(0, 0, canvas2.width, canvas2.height);
texts = []; },
false);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://intridea.github.io/sketch.js/lib/sketch.js"></script>
<!-- DRAWING PART -->
<div id="colors_demo" class="tools">
</div>
<div class="tools">
Marker
Eraser
</div>
<!-- DISPLAY TEXT PART -->
<br> <input type="radio" id="design3" name="design_3" onchange="cakeDedicationFree()" />
Text
<input type="text" size="15" id="dedi_text" name="dedicationT" placeholder="Text">
<button id="text_dedi"> Post </button> <input type="button" value="Clear" id="clear" size="23" >
<canvas id="colors_sketch" width="800" height="300"></canvas>
AS you can see, there's a big bug happening ..
worst part in my system it really doesn't show up.
Hope someone can help me.. Thank you in advance!!!
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....
I want to add 4 text boxes which will give me the coordinates of a rectangle and if I manually edit the coordinates it should change /alter the rectangle as well.
Please tell me how to proceed with this solution.
In my example if you click ROI it will draw a rectangle I want the upper and lower X and Y coordinates of the same.
the working fiddle is http://jsfiddle.net/qf6Ub/2/
// references to canvas and context
var oImageBuffer = document.createElement('img');
var oCanvas = document.getElementById("SetupImageCanvas");
var o2DContext = oCanvas.getContext("2d");
// set default context states
o2DContext.lineWidth = 1;
o2DContext.translate(0.50, 0.50); // anti-aliasing trick for sharper lines
// vars to save user drawings
var layers = [];
var currentColor = "black";
// vars for dragging
var bDragging = false;
var startX, startY;
// vars for user-selected status
var $roiCheckbox = document.getElementById("btnROI");
var $layersCheckbox = document.getElementById("btnLAYER");
var $patches = document.getElementById('txtPatchCount');
var $mouse = document.getElementById("MouseCoords");
var roiIsChecked = false;
var layersIsChecked = false;
var patchCount = 0;
// listen for mouse events
oCanvas.addEventListener('mousedown', MouseDownEvent, false);
oCanvas.addEventListener('mouseup', MouseUpEvent, false);
oCanvas.addEventListener('mousemove', MouseMoveEvent, false);
oCanvas.addEventListener('mouseout', MouseOutEvent, false);
$("#txtPatchCount").keyup(function () {
getStatus();
// clear the canvas
o2DContext.clearRect(0, 0, oCanvas.width, oCanvas.height);
// redraw all previously saved line-pairs and roi
for (var i = 0; i < layers.length; i++) {
var layer = layers[i];
if (layer.patchCount > 0) {
layer.patchCount = patchCount;
}
draw(layer);
}
});
// mouse event handlers
function MouseDownEvent(e) {
e.preventDefault();
startX = e.clientX - this.offsetLeft;
startY = e.clientY - this.offsetTop;
currentColor = randomColor();
getStatus();
bDragging = true;
}
function MouseUpEvent(e) {
if (!bDragging) {
return;
}
e.preventDefault();
bDragging = false;
mouseX = e.clientX - this.offsetLeft;
mouseY = e.clientY - this.offsetTop;
layers.push({
x1: startX,
y1: startY,
x2: mouseX,
y2: mouseY,
color: currentColor,
drawLayer: layersIsChecked,
patchCount: patchCount,
});
}
function MouseOutEvent(e) {
MouseUpEvent(e);
}
function MouseMoveEvent(e) {
if (!bDragging) {
return;
}
var mouseX = e.clientX - this.offsetLeft;
var mouseY = e.clientY - this.offsetTop;
// clear the canvas
o2DContext.clearRect(0, 0, oCanvas.width, oCanvas.height);
// redraw all previously saved line-pairs and roi
for (var i = 0; i < layers.length; i++) {
draw(layers[i]);
}
// create a temporary layer+roi object
var tempLayer = {
x1: startX,
y1: startY,
x2: mouseX,
y2: mouseY,
color: currentColor,
drawLayer: layersIsChecked,
patchCount: patchCount,
};
// draw the temporary layer+roi object
draw(tempLayer);
// Display the current mouse coordinates.
$mouse.innerHTML = "(" + mouseX + "," + mouseY + ")" + patchCount;
}
function draw(layer) {
if (layer.drawLayer) {
// set context state
o2DContext.lineWidth = 0.50;
o2DContext.strokeStyle = layer.color;
// draw parallel lines
hline(layer.y1);
hline(layer.y2);
}
if (layer.patchCount > 0) {
// set context state
o2DContext.lineWidth = 1.5;
o2DContext.strokeStyle = '#0F0';
// draw regions
o2DContext.strokeRect(layer.x1, layer.y1, (layer.x2 - layer.x1), (layer.y2 - layer.y1));
var w = layer.x2 - layer.x1;
o2DContext.beginPath();
for (var i = 1; i < layer.patchCount; i++) {
var x = layer.x1 + i * w / layer.patchCount;
o2DContext.moveTo(x, layer.y1);
o2DContext.lineTo(x, layer.y2);
}
o2DContext.stroke();
}
}
function getStatus() {
roiIsChecked = $roiCheckbox.checked;
layersIsChecked = $layersCheckbox.checked;
patchCount = $patches.value;
if (!roiIsChecked || !patchCount) {
patchCount = 0;
}
}
function randomColor() {
return ('#' + Math.floor(Math.random() * 16777215).toString(16));
}
function hline(y) {
o2DContext.beginPath();
o2DContext.moveTo(0, y);
o2DContext.lineTo(oCanvas.width, y);
o2DContext.stroke();
}
document.getElementById("MouseCoords").innerHTML = "(" + x + "," + y + "); "
+"("+ oPixel.x + "," + oPixel.y + "); "
+"("+ oCanvasRect.left + "," + oCanvasRect.top + ")";
}
Ok, I went back to the drawing board and came up with this FIDDLE.
It provides the dimensions of the div and its location from the top and left of the container.
You can calculate the exact coordinates from those numbers.
JS
var divwidth = $('.coord').width();
var divheight = $('.coord').height();
var pos = $('.coord').offset();
$('#divdimensions').html(divwidth + ',' + divheight);
$('#divposition').html( pos.left + ',' + pos.top );
I want to keydown trigger the movement of a block and then with another keydown, add another moving block. And if I keydown again, then another moving block appears. As it is now, the keydown stops the movement of the first block. I would like to have all the blocks moving simultaneously. Here's the code. It's also available on jsfiddle http://jsfiddle.net/7eUEE/
Thank you!
var canvas = document.getElementById("canvas");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
var ctx = canvas.getContext("2d");
var w = canvas.width;
var h = canvas.height;
window.addEventListener("keydown", addnew, true);
window.addEventListener("keydown", move, true);
var list = [];
var id = 0;
var color = 'blue';
var x = 0;
var y = 0;
window.onkeydown = function(s){
s.preventDefault();
if(!s){
s = window.event;
}
var keycode;
if(s.which){
keycode = s.which;
}else{
keycode = s.keyCode;
}
}
function box(id, color, x ,y){
box.id = id;
box.color = color;
box.x = x;
box.y = y;
}
function addnew(e){
e.preventDefault();
if(!e){
e = window.event;
}
//space
if(e.keyCode == 32){
list[id] = new box(id, color, x, y);
id++;
y = y + 100;
box.y = y;
box.color = 'red';
console.log(box.y);
}
}
list[0] = box(id, color, x ,y);
function move(e){
e.preventDefault();
if(!e){
e = window.event;
}
//right
if(e.keyCode == 39){
list[id];
setInterval(loopdraw);
}
}
var loopdraw = function draw(){
box.x = box.x + 1;
console.log(box.x);
ctx.beginPath();
ctx.fillStyle = box.color;
ctx.fillRect(box.x, box.y, 50, 50);
ctx.closePath();
}
Your Box objects don't behave like objects, because you use them in 3 ways:
class: list[id] = new box(id, color, x, y);
function: list[0] = box(id, color, x ,y);
object: box.y = y;, box.color = 'red'; etc
The list part is right: keep a collection of (moving) boxes. The loop part isn't, because you don't use the list. You only 'loop' 1 box.
I've updated the fiddle: http://jsfiddle.net/rudiedirkx/7eUEE/1/ and I've renamed the box class to Box, because there might be Box objects named box.
The important parts:
// Create initial box
list[id++] = new Box(id, color, x ,y);
// Create more boxes
list[id++] = new Box(id, 'red', x, y);
// Loop through existing boxes animation
function loopdraw() {
list.forEach(function(box) {
// Draw