Drawing a straight line using mouse events inside a div using JavaScript - javascript

This code is work proper in canvas but I want to do this inside a div tag not in canvas.
var canvasWidth = 180;
var canvasHeight = 160;
var canvas = null;
var bounds = null;
var ctx = null;
var hasLoaded = false;
var startX = 0;
var startY = 0;
var mouseX = 0;
var mouseY = 0;
var isDrawing = false;
var existingLines = [];
function draw() {
ctx.fillStyle = "#333333";
ctx.fillRect(0, 0, canvasWidth, canvasHeight);
ctx.strokeStyle = "black";
ctx.lineWidth = 2;
ctx.beginPath();
for (var i = 0; i < existingLines.length; ++i) {
var line = existingLines[i];
ctx.moveTo(line.startX, line.startY);
ctx.lineTo(line.endX, line.endY);
}
ctx.stroke();
if (isDrawing) {
ctx.strokeStyle = "darkred";
ctx.lineWidth = 3;
ctx.beginPath();
ctx.moveTo(startX, startY);
ctx.lineTo(mouseX, mouseY);
ctx.stroke();
}
}
function onmousedown(e) {
if (hasLoaded && e.button === 0) {
if (!isDrawing) {
startX = e.clientX - bounds.left;
startY = e.clientY - bounds.top;
isDrawing = true;
}
draw();
}
}
function onmouseup(e) {
if (hasLoaded && e.button === 0) {
if (isDrawing) {
existingLines.push({
startX: startX,
startY: startY,
endX: mouseX,
endY: mouseY
});
isDrawing = false;
}
draw();
}
}
function onmousemove(e) {
if (hasLoaded) {
mouseX = e.clientX - bounds.left;
mouseY = e.clientY - bounds.top;
if (isDrawing) {
draw();
}
}
}
window.onload = function() {
canvas = document.getElementById("canvas");
canvas.width = canvasWidth;
canvas.height = canvasHeight;
canvas.onmousedown = onmousedown;
canvas.onmouseup = onmouseup;
canvas.onmousemove = onmousemove;
bounds = canvas.getBoundingClientRect();
ctx = canvas.getContext("2d");
hasLoaded = true;
draw();
}
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<style>
body {
background-color: black;
}
canvas {
position: absolute;
margin: auto;
left: 0;
right: 0;
border: solid 1px white;
border-radius: 10px;
}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<div id="drawBoard">
<!--I want to draw here-->
</div>
</body>
</html>
Above code is fine , But i want to draw line inside a div(direct on document page) not in canvas. I don't have any idea to do this. please help me to do this or refer me some article on this.
I dont have idea even how can i start. Please refer me some related answer.

First of all, let me apologyze for my enlgish, i'll try my best to explain!
You may be interested on using "SVG" lines for this purpose https://developer.mozilla.org/en-US/docs/Web/SVG/Element/svg since you can draw lines easly.
To acomplish this, you will need and SVG container, here you can find some information about how it works -> https://www.w3schools.com/html/html5_svg.asp
Once you have the container, you need to create and move lines inside using javascript, to do so, you need the following code:
//To create 1
document.createElementNS('http://www.w3.org/2000/svg','line');
//To select 1
document.querySelector('#nameOfTheLine')
//To change its position
line.setAttribute('x1',x1);
line.setAttribute('y1',y1);
line.setAttribute('x2',x2);
line.setAttribute('y2',y2);
//To change its stroke so you can see it:
line.setAttribute("stroke", "color")
i'll give you this example that i made, its not the best but i hope you will find it usefull!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
#canvas{
border: 1px solid #000;
}
</style>
</head>
<body>
<div id="border">
<svg id="canvas" width="500" height="400">
</svg>
</div>
<script>
/*Store the "svg" item in a variable */
const canvas = document.querySelector('#canvas');
//Class to store the position
class Vector2D{
constructor(x,y){
this.x = x;
this.y = y;
}
}
//Variables that will store the initial and final position of the line before its drawn.
let initialPosOfLine;
let finalPosOfLine;
//Variable to store the stage of the canvsa, if the user its drawing or not.
let drawingOverCanvas = false;
//Variable to store the current index of the line
let lineIndex = 0;
// Code that will be executed once the user click with the mouse in the svg.
canvas.addEventListener('mousedown', event => {
//If we are drawing, do nothing.
if(drawingOverCanvas) return;
/*Calculate position relative to div -- Done by https://stackoverflow.com/questions/3234256/find-mouse-position-relative-to-element */
var rect = canvas.getBoundingClientRect();
var x = event.clientX - rect.left; //x position within the element.
var y = event.clientY - rect.top; //y position within the element.
//Change the variable drawingOverCanvas to true since now we are drawing
drawingOverCanvas = true;
//Store the mouse position over the div as the initialPos;
initialPosOfLine = new Vector2D(x , y);
//draw a line at the starting point;
drawToPos(initialPosOfLine, initialPosOfLine, 'line'+lineIndex , false);
});
// Code that will be executed once the user click with the mouse in the svg.
canvas.addEventListener('mouseup', event => {
//If we are not drawing, do nothing.
if(!drawingOverCanvas) return;
//Set the varible to "false" as we are not drawing now.
drawingOverCanvas = false;
/*Calculate position relative to div -- Done by https://stackoverflow.com/questions/3234256/find-mouse-position-relative-to-element */
var rect = canvas.getBoundingClientRect();
var x = event.clientX - rect.left; //x position within the element.
var y = event.clientY - rect.top; //y position within the element.
//Store the final position as a vector.
finalPosOfLine = new Vector2D(x, y);
//Set the line to its correct position
drawToPos(initialPosOfLine, finalPosOfLine, 'line'+lineIndex , true);
//Increse the index of the line for the next one.
lineIndex++;
});
//Draw the line when the user move the mouse
canvas.addEventListener('mousemove', event => {
//if we are not drawing, do nothing.
if(!drawingOverCanvas) return;
/*Calculate position relative to div -- Done by https://stackoverflow.com/questions/3234256/find-mouse-position-relative-to-element */
var rect = canvas.getBoundingClientRect();
var x = event.clientX - rect.left; //x position within the element.
var y = event.clientY - rect.top; //y position within the element.
//Store the mouse position as the "final" position
finalPosOfLine = new Vector2D(x, y);
//Draw a line from the initialPos to the current Mouse pos.
drawToPos(initialPosOfLine, finalPosOfLine, 'line'+lineIndex , true);
});
//Draw a line between 2 points, if move its true, it will move the line instead of making it
function drawToPos(initial, final, id, move){
//Declare a new Line in SVG
var line = document.createElementNS('http://www.w3.org/2000/svg','line');
//If we are moving and existent line, set "line" to the current line, else, give to the new line the id attribute.
if(move){ line = document.querySelector('#'+id) } else { line.setAttribute('id',id) };
// If we are creating a new line, define its initial position
if(!move) line.setAttribute('x1',initial.x);
if(!move) line.setAttribute('y1',initial.y);
//Define its final position
line.setAttribute('x2',final.x);
line.setAttribute('y2',final.y);
//Define its stroke.
line.setAttribute("stroke", "black")
//Apend the line to the SVG canvas
canvas.append(line);
}
</script>
</body>
</html>

Related

How to change the color of objects on hover in Javascript? [duplicate]

This question already has an answer here:
Mouse hover canvas/shape
(1 answer)
Closed 4 years ago.
I'm fairly new to Javascript/Canvas and I wanted to create an animation that creates circles whenever I click within the canvas, then it changes colors when I hover over them and reverts back to the original color when the mouse is not hovering over them. I was able to create the animation of drawing circles on click, but can't get the hover color to work. I'm trying to get this done completely with Javascript, using HTML only for creating the canvas. Any advice is appreciate!
let dots = [];
/** #type {HTMLCanvasElement} */
let canvas = ( /** #type {HTMLCanvasElement} */ document.getElementById("canvas"));
let context = canvas.getContext('2d');
//some state
let mouseX = -10;
let mouseY = -10;
//remember mouse click position
canvas.onclick = function (event) {
mouseX = event.clientX;
mouseY = event.clientY;
let box = (event.target).getBoundingClientRect();
mouseX -= box.left;
mouseY -= box.top;
};
canvas.onmouseleave = function () {
mouseX = -10;
mouseY = -10;
};
var drawCirc = function (hover) {
//clear the canvas
context.clearRect(0, 0, canvas.width, canvas.height);
//determine mouse location when outside
//if inwide canvas, make a dot
if ((mouseX > 0) && (mouseY > 0)) {
dots.push({
"x": mouseX,
"y": mouseY
});
}
//draw circles/dots
dots.forEach(function (d) {
context.fillStyle = "#808080";
context.beginPath();
context.arc(d.x - 3, d.y - 3, 10, 0, 2 * Math.PI);
context.fill();
});
window.requestAnimationFrame(drawCirc);
}
drawCirc();
canvas{
border:1px solid black
}
<canvas id="canvas" width="200" height="200"></canvas>
you can use mousehover method
for jquery here's the sample
$("p").mouseover(function(){
$("p").css("background-color", "yellow");
});
for javascript
<script>
document.getElementById("demo").addEventListener("mouseover", mouseOver);
document.getElementById("demo").addEventListener("mouseout", mouseOut);
function mouseOver() {
document.getElementById("demo").style.color = "red";
}
function mouseOut() {
document.getElementById("demo").style.color = "black";
}
</script>
Javascript:
object.addEventListener("mouseover", myScript);
example:
var e = document.getElementById('elementID')
e.onmouseover = function(){e.style.backgroundColor = "blue"}

Drawing a parallelogram HTML5 Canvas

I am new to Javascript and Canvas of HTML5. I have to complete a project where I have to draw a parallelogram with three mouse clicks.
Click 1: Starts the first line of the parallelogram.
Click 2: Ends of the first line.
Click 3: When the user drags the mouse up or down from the second click point, a line should be drawn from the second click point along the mouse move and at the same time a third line should be drawn from the first click point parallel to the second line.Upon the third click on the canvas the parallelogram should be complete i.e, a line should be drawn from the second line to the third line.
I am stuck on Click 3. While I conceptually understand how this needs to be done...for the last one week...I could not do much headway. The following is my code:
var canvas, context;
var dragging = false;
var dragStartLocation;
var dragStopLocation;
var dragThirdLocation;
var beginFourthLine;
var snapshot;
var pointsNum;
//Get mouse click coordinates
function getCanvasCoordinates(event) {
var x = event.clientX - canvas.getBoundingClientRect().left;
var y = event.clientY - canvas.getBoundingClientRect().top;
return {
x: x,
y: y
};
}
//save the canvas original state
function takeSnapShot() {
snapshot = context.getImageData(0, 0, canvas.width, canvas.height);
}
//restore the canvas original state
function restoreSnapShot() {
context.putImageData(snapshot, 0, 0);
}
//draw a point on mouse click
function drawPoint(position) {
context.beginPath();
context.lineWidth = 3;
context.strokeStyle = '#f4d03f';
context.arc(position.x, position.y, 5.5, 0, Math.PI * 2, false);
context.stroke();
}
//draw a line on mouse move
function drawLine(position) {
context.beginPath();
context.moveTo(dragStartLocation.x, dragStartLocation.y);
context.lineTo(position.x, position.y);
context.stroke();
}
//start the event with first mouse click
function dragStart(event) {
dragging = true;
dragStartLocation = getCanvasCoordinates(event);
drawPoint(dragStartLocation);
console.log(dragStartLocation.x, dragStartLocation.y);
takeSnapShot();
}
//draw a line along with the mouse move from the first click
function drag(event) {
var position;
if (dragging === true) {
restoreSnapShot();
position = getCanvasCoordinates(event);
drawLine(position);
}
}
//draw the third and fourth coordinates - this is where I am stuck
function drawThirdCoord(event) {
dragging = true;
var beginFourthLine = dragStopLocation.x - dragStartLocation.x;
restoreSnapShot();
dragThirdLocation = getCanvasCoordinates(event);
drawLine(event);
drawLine(beginFourthLine);
}
//stop the mouse movement and drawing line.
function dragStop(event) {
dragging = false;
restoreSnapShot();
var position = getCanvasCoordinates(event);
dragStopLocation = position;
drawLine(position);
drawPoint(position);
console.log(dragStopLocation.x, dragStopLocation.y);
drawThirdCoord(event);
}
function init() {
canvas = document.getElementById('canvas');
context = canvas.getContext('2d');
context.strokeStyle = 'green';
context.lineWidth = 6;
context.lineCap = "round";
canvas.addEventListener('mousedown', dragStart, false);
canvas.addEventListener('mousemove', drag, false);
canvas.addEventListener('mouseup', dragStop, false);
}
window.addEventListener('load', init, false);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<canvas id="canvas" width="800" height="600" style="border:solid 1px;margin:0;padding:0;"></canvas>
<p id="status"> | </p>
I'm not sure how the mouse drag should work, so I tried to keep the code as close to the question as possible. So you need to drag the first line then just click to end the shape.
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>parallelogram</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
</head>
<body>
<canvas id="canvas" width="800" height="600" style="border:solid 1px;margin:0;padding:0;"></canvas>
<p id="status"> | </p>
</body>
</html>
<script type="text/javascript">
var canvas, context;
var dragging = false;
var startLocation;
var dragStartLocation;
var dragStopLocation;
var dragThirdLocation;
var snapshot;
var pointsNum = 0;
var d = {x:0, y:0};
//Get mouse click coordinates
function getCanvasCoordinates(event) {
var x = event.clientX - canvas.getBoundingClientRect().left;
var y = event.clientY - canvas.getBoundingClientRect().top;
return {x: x, y: y};
}
//save the canvas original state
function takeSnapShot() {
snapshot = context.getImageData(0,0,canvas.width, canvas.height);
}
//restore the canvas original state
function restoreSnapShot() {
context.putImageData(snapshot,0,0);
}
//draw a point on mouse click
function drawPoint(position) {
context.beginPath();
context.arc(position.x, position.y, 5.5, 0, Math.PI * 2, false);
context.stroke();
}
//draw a line on mouse move
function drawLine(start, end) {
context.beginPath();
context.moveTo(start.x, start.y);
context.lineTo(end.x, end.y);
context.stroke();
}
//start the event with first mouse click
function dragStart(event) {
dragging = true;
dragStartLocation = getCanvasCoordinates(event);
drawPoint(dragStartLocation);
pointsNum++;
takeSnapShot();
if (pointsNum == 1) startLocation = dragStartLocation;
}
//draw a line along with the mouse move from the first click
function drag(event) {
var position;
if (snapshot && pointsNum && pointsNum < 3) {
restoreSnapShot();
position = getCanvasCoordinates(event);
drawLine(dragStartLocation, position);
drawPoint(position);
if (pointsNum == 2) drawFourthCoord(position)
}
}
//stop the mouse movement and drawing line.
function dragStop(event) {
dragging = false;
restoreSnapShot();
var position = getCanvasCoordinates(event);
dragStopLocation = position;
drawPoint(dragStopLocation);
pointsNum++;
drawLine(dragStartLocation, dragStopLocation);
takeSnapShot();
d = {
x: dragStartLocation.x - dragStopLocation.x,
y: dragStartLocation.y - dragStopLocation.y
};
dragStartLocation = position;
if (pointsNum > 3) pointsNum =0;
}
//draw the fourth coordinate
function drawFourthCoord(position) {
var p = {
x: position.x + d.x,
y: position.y + d.y
};
drawLine(position, p);
drawPoint(p);
drawLine(startLocation, p);
}
function init() {
canvas = document.getElementById('canvas');
context = canvas.getContext('2d');
context.lineCap = "round";
context.lineWidth = 3;
context.strokeStyle = '#f4d03f';
canvas.addEventListener('mousedown', dragStart, false);
canvas.addEventListener('mousemove', drag, false);
canvas.addEventListener('mouseup', dragStop, false);
}
window.addEventListener('load', init, false);
</script>

How to make drawing draggable on canvas in HTML5

I am a newbie to HTML5 and JavaScript, I know there's a lot of libraries can do that, but I am wondering if there's a way to do it just using plain javascript.
I have a canvas and when the canvas is clicked somewhere, there will be a little red dot appear at where the user clicked. I want to make each of the little dot draggable, any ideas on it? thanks.
Here's the code I have:
in HTML:
<div id="primal_plane" style="position:absolute; top:100px; left:10px;">
<canvas id="canvas_prime" onclick="drawDot('canvas_prime')" width="700" height="500"></canvas>
</div>
in JS file:
function drawDot(plane) {
var canvas = document.getElementById(plane);
var context = canvas.getContext("2d");
context.beginPath();
context.arc(mouseX * 50, mouseY * 50, 4, 0, 2 * Math.PI, false);
context.fillStyle = 'green';
context.fill();
context.lineWidth = 1;
context.strokeStyle = 'yellow';
context.stroke();
}
To outline your solution:
Listen for mousedown events and either (1) create a new circle if the mouse is not over a circle or (2) start a drag operation on a circle if the mouse is over a circle.
Listen for mousemove events and move the dragged circle by the distance the mouse has moved since the last mousemove event
Listen for mouseup events and stop the drag operation
Here is annotated code and a Demo: http://jsfiddle.net/m1erickson/ytUhL/
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" />
<!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"> </script>
<style>
body{ background-color: ivory; }
#canvas{border:1px solid red;}
</style>
<script>
$(function() {
// canvas related variables
// references to canvas and its context and its position on the page
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var $canvas = $("#canvas");
var canvasOffset = $canvas.offset();
var offsetX = canvasOffset.left;
var offsetY = canvasOffset.top;
var scrollX = $canvas.scrollLeft();
var scrollY = $canvas.scrollTop();
var cw = canvas.width;
var ch = canvas.height;
// flag to indicate a drag is in process
// and the last XY position that has already been processed
var isDown = false;
var lastX;
var lastY;
// the radian value of a full circle is used often, cache it
var PI2 = Math.PI * 2;
// variables relating to existing circles
var circles = [];
var stdRadius = 10;
var draggingCircle = -1;
// clear the canvas and redraw all existing circles
function drawAll() {
ctx.clearRect(0, 0, cw, ch);
for(var i=0; i<circles.length; i++){
var circle = circles[i];
ctx.beginPath();
ctx.arc(circle.x, circle.y, circle.radius, 0, PI2);
ctx.closePath();
ctx.fillStyle = circle.color;
ctx.fill();
}
}
function handleMouseDown(e) {
// tell the browser we'll handle this event
e.preventDefault();
e.stopPropagation();
// save the mouse position
// in case this becomes a drag operation
lastX = parseInt(e.clientX - offsetX);
lastY = parseInt(e.clientY - offsetY);
// hit test all existing circles
var hit = -1;
for (var i=0; i < circles.length; i++) {
var circle = circles[i];
var dx = lastX - circle.x;
var dy = lastY - circle.y;
if (dx*dx + dy*dy < circle.radius * circle.radius) {
hit = i;
}
}
// if no hits then add a circle
// if hit then set the isDown flag to start a drag
if (hit < 0) {
circles.push({x:lastX, y:lastY, radius:stdRadius, color:randomColor()});
drawAll();
} else {
draggingCircle = circles[hit];
isDown = true;
}
}
function handleMouseUp(e) {
// tell the browser we'll handle this event
e.preventDefault();
e.stopPropagation();
// stop the drag
isDown = false;
}
function handleMouseMove(e) {
// if we're not dragging, just exit
if (!isDown) { return; }
// tell the browser we'll handle this event
e.preventDefault();
e.stopPropagation();
// get the current mouse position
mouseX = parseInt(e.clientX - offsetX);
mouseY = parseInt(e.clientY - offsetY);
// calculate how far the mouse has moved
// since the last mousemove event was processed
var dx = mouseX - lastX;
var dy = mouseY - lastY;
// reset the lastX/Y to the current mouse position
lastX = mouseX;
lastY = mouseY;
// change the target circles position by the
// distance the mouse has moved since the last
// mousemove event
draggingCircle.x += dx;
draggingCircle.y += dy;
// redraw all the circles
drawAll();
}
// listen for mouse events
$("#canvas").mousedown(function(e) { handleMouseDown(e); });
$("#canvas").mousemove(function(e) { handleMouseMove(e); });
$("#canvas").mouseup(function(e) { handleMouseUp(e); });
$("#canvas").mouseout(function(e) { handleMouseUp(e); });
//////////////////////
// Utility functions
function randomColor(){
return('#' + Math.floor(Math.random()*16777215).toString(16));
}
}); // end $(function(){});
</script>
</head>
<body>
<canvas id="canvas" width=300 height=300></canvas>
</body>
</html>
You will have to store a list of the dots created, but you will have to check if a dot already exists. If so, set a boolean flag that identifies the dragging behavior when the mousedown event occurs and another to identify the dot being dragged. On the mouseup event clear the flag. The mousemove method should update a variable that stores the current mouse position and updates the position of the current dot being dragged. Use jQuery.

Drawing a rectangle on Canvas

I am trying to create a simple canvas program where the user can consistently create new shapes. This one is just a basic rectangle creator (I am hoping to expand it more to circles, lines, and maybe even other stuff). Right now though I have created something that is working in a really weird way.
<html>
<head>
<meta chartset="utf-8">
<title>Dragging a square</title>
<script type="text/javascript">
var canvas, context, startX, endX, startY, endY;
var mouseIsDown = 0;
function init() {
canvas = document.getElementById("canvas");
context = canvas.getContext("2d");
canvas.addEventListener("mousedown", mouseDown, false);
canvas.addEventListener("mousemove", mouseXY, false);
document.body.addEventListener("mouseup", mouseUp, false);
}
function mouseUp() {
mouseIsDown = 0;
//mouseXY();
}
function mouseDown() {
mouseIsDown = 1;
startX = event.clientX;
startY = event.clientY;
mouseXY();
}
function mouseXY(eve) {
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.beginPath();
context.rect(startX, startY, width, height);
context.fillStyle = "yellow";
context.fill();
context.lineWidth = 7;
context.strokeStyle = 'black';
context.stroke();
}
</script>
</head>
<body onload="init()">
<canvas id="canvas" width="400" height="400" style="border: 1px solid black; cursor: pointer;"></canvas>
</body>
</html>
Sorry about the slightly weird formatting when I copy and pasted my code. I think the problem is my mouseXY function. What I want is the user to click somewhere on the canvas a drag the mouse to create a rectangle, when the user lets go that is the end of that operation and they can create a whole new rectangle right after. At this point the program kind of just lets me click and create a new rectangle but if I let go of the mouse button it doesn't stop, in fact I have to click again to make it stop which then creates a new rectangle. I am still very new to this and I am having a lot of trouble with this, I will continue to work on this and if I figure it out I will let the site know. Thank you and have a great day!
Well I got this to work (thanks to #Ken) but now I am trying to solve a new problem. I want to be able to put multiple rectangles on the canvas. I created a function that represents the Rectangle and then created a draw function within the rectangle function to draw out a rectangle. I created a new function called addShape() that ideally creates the rectangle object and pushes into an array called square and drawShapes() that is supposed to erase everything on the canvas and redraws everything. Here is what I have so far:
<html>
<head>
<meta chartset="utf-8">
<title>Dragging a square</title>
<script type="text/javascript">
function Rectangle(canvas, x, y, width, height,color) {
//this.context = canvas.getContext("2d");
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.color = color;
this.draw = function() {
this.context.globalAlpha = 0.85;
this.context.beginPath();
this.context.rect(this.x, this.y, this.width, this.height);
this.context.fillStyle = this.color;
this.context.strokeStyle = "black";
this.context.lineWidth = 1;
this.context.fill();
this.context.stroke();
};
};
// hold the canvas and context variable, as well as the
// starting point of X and Y and the end ones
var canvas, context, startX, endX, startY, endY;
var mouseIsDown = 0;
// An array that holds all the squares
var squares = [];
window.onload = function() {
canvas = document.getElementById("canvas");
context = canvas.getContext("2d");
canvas.addEventListener("mousedown", mouseDown, false);
canvas.addEventListener("mousemove", mouseXY, false);
canvas.addEventListener("mouseup", mouseUp, false);
}
function mouseUp(eve) {
if (mouseIsDown !== 0) {
mouseIsDown = 0;
var pos = getMousePos(canvas, eve);
endX = pos.x;
endY = pos.y;
//Square(); //update on mouse-up
addShape(); // Update on mouse-up
}
}
function mouseDown(eve) {
mouseIsDown = 1;
var pos = getMousePos(canvas, eve);
startX = endX = pos.x;
startY = endY = pos.y;
// Square(); //update
addShape();
}
function mouseXY(eve) {
if (mouseIsDown !== 0) {
var pos = getMousePos(canvas, eve);
endX = pos.x;
endY = pos.y;
//Square();
addShape();
}
}
function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect();
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}
function addShape() {
var w = endX - startX;
var h = endY - startY;
var offsetX = (w < 0) ? w : 0;
var offsetY = (h < 0) ? h : 0;
var width = Math.abs(w);
var height = Math.abs(h);
var s = new Rectangle(startX + offsetX, startY + offsetY, width, height, "yellow");
squares.push(s);
// Update the display
drawShapes();
}
function drawShapes() {
context.clearRect(0,0,canvas.width,canvas.height);
for (var i = 0; i < squares.length; i++) {
var shape = squares[i];
shape.draw();
};
}
function clearCanvas() {
squares = [];
drawShapes();
}
</script>
</head>
<body onload="addShape()">
<canvas id="canvas" width="400" height="400" style="border: 1px solid black; cursor: pointer;"></canvas><br>
<button onclick="clearCanvas()">Clear Canvas</button>
</body>
</html>
I am pretty sure I broke the original code... thank you for any help!
You need to modify a couple of things in the code: (edit: there are many issues with this code. I went through some of them inline here, but haven't tested. If you put it in a fiddle it's easier for us to check)..
Fiddle
When mouse down occur initialize both start and end points. Call a common draw function that is not dependent on the event itself:
function mouseDown(eve) {
mouseIsDown = 1;
var pos = getMousePos(canvas, eve);
startX = endX = pos.x;
startY = endY = pos.y;
drawSquare(); //update
}
At mouse up, only register if isMouseDown is true, else this function will handle all incoming up-events (as you have attatched it to document, which is correct - window could have been used too):
function mouseUp(eve) {
if (mouseIsDown !== 0) {
mouseIsDown = 0;
var pos = getMousePos(canvas, eve);
endX = pos.x;
endY = pos.y;
drawSquare(); //update on mouse-up
}
}
Only draw if mouseisdown is true:
function mouseXY(eve) {
if (mouseIsDown !== 0) {
var pos = getMousePos(canvas, eve);
endX = pos.x;
endY = pos.y;
drawSquare();
}
}
In addition you will need to clear the previous area of the rectangle before drawing a new or else it won't show when you draw a bigger rectangle and then move the mouse back to draw a smaller one.
For simplicity you can do:
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();
}
Use this for mouse position:
function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect();
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}

Image appear at mouse location

I am trying to make an image appear to the location of the mouse coordinates when I click the canvas.
Right now I have it appearing, but I can only figure out how to do it with automatic updating coordinates and the image will follow the mouse after an "onclick".
I need to make it so the image will just move to the location I click, not follow the cursor.
<!DOCTYPE html>
<html lang="en">
<head>
<style>
body {
margin: 0px;
padding: 0px;
}
</style>
</head>
<title>Click to make a sad face</title>
</head>
<body>
<canvas id="myCanvas" width="2000" height="1000", onClick="makeface();"></canvas>
<script type="text/javascript">
function writeMessage(canvas, message) {
var ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.font = '18pt Calibri';
ctx.fillStyle = 'black';
ctx.fillText(message, 10, 25);
}
function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect();
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
canvas.addEventListener('mousemove', function(evt)
{
var mousePos = getMousePos(canvas, evt);
var message = 'Click to make a face appear at coordinates: ' + mousePos.x + ',' + mousePos.y;
writeMessage(canvas, message);
}, false);
function makeface()
{
canvas.addEventListener('mousemove', function(evt)
{
var mousePos2 = getMousePos(canvas, evt);
var headx = mousePos2.x;
var heady = mousePos2.y;
var message = 'You made the face appear, you are currently at coordinates: ' + mousePos2.x + ',' + mousePos2.y;
writeMessage(canvas, message);
var headrad = 50;
var smileoffsetx=0;
var frownoffsety = 33;
var smilerad=20;
var eyeoffsety = -10;
var lefteyeoffsetx = -15;
var righteyeoffsetx = -lefteyeoffsetx;
var eyerad = 8;
ctx.strokeStyle="blue";
ctx.lineWidth = 5;
ctx.beginPath();
ctx.arc(headx,heady,headrad,0,2*Math.PI,true);
ctx.closePath();
ctx.stroke();
ctx.beginPath()
ctx.arc(headx+smileoffsetx,heady+frownoffsety,smilerad,-.20*Math.PI,-.80*Math.PI,true);
ctx.stroke();
ctx.beginPath()
ctx.arc(headx+lefteyeoffsetx,heady+eyeoffsety,eyerad,0,2*Math.PI,true);
ctx.fillStyle="blue";
ctx.fill();
ctx.beginPath()
ctx.arc(headx+righteyeoffsetx,heady+eyeoffsety,eyerad,0,2*Math.PI,true);
ctx.fill();
}, false);
}
</script>
</body>
</html>
This is happening because your writeMessage function is clearing the entire canvas.
This is my quick and dirty fix:
<canvas id="myCanvas" width="2000" height="1000" onClick="document.madeFace = 0; makeface();"></canvas>
...
function makeface()
{
canvas.addEventListener('mousemove', function(evt)
{
var mousePos2 = getMousePos(canvas, evt);
document.madeFace = document.madeFace || mousePos2; /* added */
var message = 'You made the face appear, you are currently at coordinates: ' + mousePos2.x + ',' + mousePos2.y;
mousePos2 = document.madeFace; /* added */
var headx = mousePos2.x;
var heady = mousePos2.y;
...
What this code does is to store the coordinates of the face as soon as the user has clicked. When the user clicks again, the variable "document.madeFace" is reset to 0 and so the coordinates of the face are re-calculated.
But the face is still re-drawn every time the mouse moves, and so it will still appear even though the entire canvas gets cleared.
This is what to do to make it happen exactly onclick instead of after onclick.
Put this variable outside of the function:
var faceHandler = function(evt)
{
var mousePos2 = getMousePos(canvas, evt);
document.madeFace = document.madeFace || mousePos2;
... until the end of the function, i.e., the curly brace that is now in the line that looks like this:
}, false);
Then register the onclick outside the function and the mousemove inside the function:
canvas.addEventListener('click', faceHandler, false);
function makeface()
{
canvas.addEventListener('mousemove', faceHandler, false);
}

Categories

Resources