I am using a canvas element on my web page, and need to be able to draw circles on mouse click with a different color each click. Here is the code I have, which works on some sites but not others. My question is what am I missing for this to work? I know that it only has one color currently in the code, but as it stands, I click all over the canvas and nothing happens.
var canvas = document.getElementById("cirCanvas");
var context = canvas.getContext("2d");
function createImageOnCanvas(imageId) {
canvas.style.display = "block";
document.getElementById("circles").style.overflowY = "hidden";
var img = new Image(300, 300);
img.src = document.getElementById(imageId).src;
context.drawImage(img, (0), (0)); //onload....
}
function draw(e) {
var pos = getMousePos(canvas, e);
posx = pos.x;
posy = pos.y;
context.fillStyle = "#000000";
context.beginPath();
context.arc(posx, posy, 50, 0, 2 * Math.PI);
context.fill();
}
function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect();
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}
window.draw = draw;
<head>
<title></title>
<meta charset="utf-8">
<script src="clickCircle.js"></script>
</head>
<body>
<div id="circles"></div>
<canvas id="cirCanvas" width="250" height="250" onclick="draw (event)">
</canvas>
</body>
Below is example of a random color generator function.
Also you should try add the click event listener in an unobtrusive way.
var canvas = document.getElementById("cirCanvas");
var context = canvas.getContext("2d");
canvas.addEventListener('click', draw, false);
function draw(e) {
var pos = getMousePos(canvas, e);
posx = pos.x;
posy = pos.y;
context.fillStyle = randomColor();
context.beginPath();
context.arc(posx, posy, 50, 0, 2 * Math.PI);
context.fill();
}
function randomColor() {
var color = [];
for (var i = 0; i < 3; i++) {
color.push(Math.floor(Math.random() * 256));
}
return 'rgb(' + color.join(',') + ')';
}
function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect();
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}
#cirCanvas {
border: 1px solid black;
}
<div id="circles">
<canvas id="cirCanvas" width="250" height="250"></canvas>
</div>
Here is how to change color - you can randomize the colors:
Best way to generate a random color in javascript?
or use an array of fixed colors
colors = ["001100","AA0000","00BB00"];
using
context.fillStyle = "#"+colors[Math.round(Math.random()*colors.length)];
Random version:
var canvas = document.getElementById("cirCanvas"),
context = canvas.getContext("2d");
function createImageOnCanvas(imageId) {
canvas.style.display = "block";
document.getElementById("circles").style.overflowY = "hidden";
var img = new Image(300, 300);
img.src = document.getElementById(imageId).src;
context.drawImage(img, (0), (0)); //onload....
}
function draw(e) {
var pos = getMousePos(canvas, e);
posx = pos.x;
posy = pos.y;
context.fillStyle = '#'+(0x1000000+(Math.random())*0xffffff).toString(16).substr(1,6)
context.beginPath();
context.arc(posx, posy, 50, 0, 2 * Math.PI);
context.fill();
}
function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect();
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}
//window.draw = draw;
<div id="circles"></div>
<canvas id="cirCanvas" width="250" height="250" onclick="draw(event)">
</canvas>
You have to implement a function which is able to generate a random color.
just use sth. like this:
function getRandomColor() {
var letters = '0123456789ABCDEF';
var color = '#';
for (var i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}
JsFiddle example
Related
I have been studying JS for a few days, but I need to draw a parallelogram and allow user to change its angles by dragging one of its points. I took a code from a related question, and tried to change it (I know, it's a nightmare). But the 4th point doesn't work properly. I get this:
https://i.stack.imgur.com/PAjE6.png
How can I make the 4th point create a parallelogram?
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
var cw = canvas.width;
var ch = canvas.height;
var mouse = {};
var draggable = false;
context.lineWidth = 2;
context.strokeStyle = "blue";
var coordinates = [];
var isDone = false;
var clicks = 0;
canvas.addEventListener("mousedown", function(e) {
handleMouseDown(e);
});
function GetMassCenterAndFourthPoint(knownpoints) {
let point4X = knownpoints[2].x - knownpoints[1].x + knownpoints[0].x;
let point4Y = knownpoints[2].y - knownpoints[1].y + knownpoints[0].y;
coordinates.push({
x: point4X,
y: point4Y
});
}
function handleMouseDown(e) {
mouse = oMousePos(canvas, e);
//if isDone you can drag
if (isDone) {
for (index = 0; index < coordinates.length; index++) {
// you draw a small circle no stroke, no fill
context.beginPath();
context.arc(
coordinates[index].x,
coordinates[index].y,
5,
0,
2 * Math.PI
);
// if the mouse is inside the circle
if (context.isPointInPath(mouse.x, mouse.y)) {
// you can drag this point
// I'm using index + 1 because index == 0 is false
draggable = index + 1;
// if I have a point a can break the loop
break;
}
}
} else {
coordinates.push({
x: mouse.x,
y: mouse.y
});
drawPolygon();
clicks++;
if (clicks === 3) {
isDone = true;
}
}
}
function drawPolygon() {
context.clearRect(0, 0, cw, ch);
if (isDone) {
GetMassCenterAndFourthPoint(coordinates);
}
context.beginPath();
context.moveTo(coordinates[0].x, coordinates[0].y);
for (index = 1; index < coordinates.length; index++) {
context.lineTo(coordinates[index].x, coordinates[index].y);
}
context.closePath();
context.stroke();
// Additionaly I'm drawing a small circle around every point
// you can delete this.
for (index = 0; index < coordinates.length; index++) {
context.beginPath();
context.arc(coordinates[index].x, coordinates[index].y, 5, 0, 2 * Math.PI);
context.stroke();
}
}
canvas.addEventListener("mousemove", function(e) {
if (isDone) {
if (draggable) {
mouse = oMousePos(canvas, e);
// draggable - 1 is the index of the point in the coordinates array
coordinates[draggable - 1].x = mouse.x;
coordinates[draggable - 1].y = mouse.y;
drawPolygon();
}
}
});
canvas.addEventListener("mouseup", function(e) {
if (draggable) {
draggable = false;
}
});
// a function to detect the mouse position
function oMousePos(canvas, evt) {
var ClientRect = canvas.getBoundingClientRect();
return {
//objeto
x: Math.round(evt.clientX - ClientRect.left),
y: Math.round(evt.clientY - ClientRect.top)
};
}
canvas {
border: 1px solid black;
}
<canvas id="canvas" width="600" height="600"></canvas>
I also tried to draw my own parallelogram, but can't do it draggable
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
startX;
startY;
}
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
var cw = canvas.width;
var ch = canvas.height;
var mouse = {};
var draggable = false;
var points = [];
let isDone = false;
var clicks =0;
let click = false;
canvas.addEventListener("click", function(e) {
console.log(clicks);
clicks++;
if(!isDone){
const point = new Point(e.offsetX, e.offsetY);
points.push(point);
context.beginPath();
context.arc(point.x, point.y, 5, 0, 2 * Math.PI);
context.fillStyle = "red";
context.fill();
if(clicks===3){
isDone=true;
}
}
if(isDone){
GetMassCenterAndFourthPoint(points);
drawParallelogramAndCircle();
}
});
function GetMassCenterAndFourthPoint(knownpoints){
const point4X = knownpoints[2].x-knownpoints[1].x+knownpoints[0].x;
const point4Y = knownpoints[2].y-knownpoints[1].y+knownpoints[0].y;
context.beginPath();
context.arc(point4X, point4Y, 5, 0, 2 * Math.PI);
context.fillStyle = "red";
context.fill();
points.push(new Point(point4X, point4Y));
const massCenterX = (knownpoints[1].x+knownpoints[3].x)/2;
const massCenterY = (knownpoints[1].y+knownpoints[3].y)/2;
points.push(new Point(massCenterX, massCenterY));
}
function drawParallelogramAndCircle(){
context.beginPath();
context.moveTo(points[0].x, points[0].y);
for(let i=1;i<points.length-1;i++){
context.lineTo(points[i].x, points[i].y);
if(i===3){
context.lineTo(points[0].x, points[0].y);
}
}
context.strokeStyle = "blue";
context.closePath();
context.stroke();
// find square. Here will be the logic to calculate square
let square = 250;
context.beginPath();
context.arc(points[4].x, points[4].y, 30, 0, 2 * Math.PI);
context.strokeStyle = "yellow";
context.closePath();
context.stroke();
}
canvas {
border: 1px solid black;
}
<canvas id="canvas" width="600" height="600"></canvas>
Maybe this a stupid question but I can't figure out what is going on. I'm studying digital drawing with HTML CANVAS and I want to draw within several CANVAS (at the same time) with the same mouse movement output. I made a function to handle the context (ctx) of each CANVAS when drawing(ctx, xpos, ypos, bool). But every time I try to use it, it just draw in one of them.
I made an exemple here
https://jsfiddle.net/rboyart/Lgzwry02/1/
(If you click and move in the white space, it should draw in both CANVAS)
<style>
html, body {height: 100%}
.full-height {height: 100%}
canvas {background-color:#ddd; z-index:-1; float: left; margin-right:10px}
.objectBox {z-index: 0; position: relative; top:0; left:0 }
</style>
<canvas id="canvas1" width="200" height="200" ></canvas>
<canvas id="canvas2" width="200" height="200" ></canvas>
<div id="objectBox" class="full-height" style="width:100%; height:100%; background-color:transparent;">
</div>
<script type="text/javascript"> var canvas1 = document.getElementById('canvas1'); var ctxPaint = canvas1.getContext('2d'); var canvas2 = document.getElementById('canvas2'); var ctxPaint2 = canvas2.getContext('2d'); var isDrawing, lastPoint; function drawing(ctx, xpos, ypos, bool) { if(!bool){ lastPoint = { x: xpos, y: ypos } } if(bool) { ctx.lineJoin = "round"; ctx.lineCap = "butt"; ctx.strokeStyle = "#000000"; ctx.globalAlpha = "1"; ctx.globalCompositeOperation = "source-over"; if(ctx.lineWidth >= 5) { ctx.lineWidth -= 0.1; } var currentPoint = { x: xpos, y: ypos }; ctx.beginPath(); ctx.moveTo(lastPoint.x, lastPoint.y); ctx.lineTo(currentPoint.x, currentPoint.y); ctx.closePath(); ctx.stroke(); lastPoint = currentPoint; } } /*END FUNCTION DRAWING */ function findObjectCoords(mouseEvent) { var obj = document.getElementById("objectBox"); var widthOBJ = obj.clientWidth; var heightOBJ = obj.clientHeight; var obj_left = 0; var obj_top = 0; var xpos; var ypos; while (obj.offsetParent) { obj_left += obj.offsetLeft; obj_top += obj.offsetTop; obj = obj.offsetParent; } obj.onmousedown = function(e) { isDrawing = true; }; obj.onmouseup = function() { isDrawing = false; }; if (mouseEvent) { xpos = mouseEvent.pageX; ypos = mouseEvent.pageY; } else { xpos = window.event.x + document.body.scrollLeft - 2; ypos = window.event.y + document.body.scrollTop - 2; } xpos -= obj_left; ypos -= obj_top; var numX = map_range(xpos, 0, widthOBJ, 0, 200); var numY = map_range(ypos,0, heightOBJ, 0, 200); drawing(ctxPaint, parseInt(numX), parseInt(numY), isDrawing); drawing(ctxPaint2, parseInt(numX), parseInt(numY), isDrawing); } document.getElementById("objectBox").onmousemove = findObjectCoords; function map_range(value, low1, high1, low2, high2) { return low2 + (high2 - low2) * (value - low1) / (high1 - low1); } </script>
It's because of your lastPoint variable which you use for both canvases. When you call drawing the first time lastpoint is overwritten. So for calling drawing the 2nd time your lastPoint is already the current point => no point is drawing.
To fix this you can use 2 separate lastPoint variables or update lastPoint only the second time you call drawing like I did here: https://jsfiddle.net/ay45sx19/
I am trying to develop a simple canvas application using html5 and javascript. I want to make a circle depending on the position of mouse click in the canvas. Each time user clicks in canvas a circle should be drawn. Moreover the color of circle needs to be randomly selected. I have written the random color and position function to get x and y position of mouse in canvas. But when i run nothing is happening.
Here is my html code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<script src="circle.js"></script>
<style type="text/css">
#testCanvas {
border: 2px solid;
}
</style>
</head>
<body>
<canvas id="testCanvas" width="400" height="400"> </canvas>
</body>
Here's my javascript code:
window.onload = init;
function init() {
// access the canvas element and its context
var canvas = document.getElementById("testCanvas");
var context = canvas.getContext("2d");
var pos = getMousePos(canvas, e);
posx = pos.x;
posy = pos.y;
context.fillStyle = randomColor();
// fill a circle
context.beginPath();
context.arc(posx,posy, 30, 0, 2 * Math.PI, true);
context.fill();
context.closePath();
}
function randomColor() {
var color = [];
for (var i = 0; i < 3; i++) {
color.push(Math.floor(Math.random() * 256));
}
return 'rgb(' + color.join(',') + ')';
}
function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect();
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}
You need to implement a click handler for the canvas so that every time you click on it you will receive a notification in form of an event:
// access the canvas element and its context
var canvas = document.getElementById("testCanvas");
var context = canvas.getContext("2d");
// add click handler
canvas.onclick = function(e) {
var pos = getMousePos(canvas, e); // get position as before
context.fillStyle = randomColor(); // get the fill color
// fill a circle
context.beginPath(); // now we can draw the circle at click
context.arc(pos.x, pos.y, 30, 0, 2 * Math.PI); // use pos object directly like this
context.fill();
// closePath() not needed here and won't work after fill() has been called anyways
}
function randomColor() {
var color = [];
for (var i = 0; i < 3; i++) {
color.push(Math.floor(Math.random() * 256));
}
return 'rgb(' + color.join(',') + ')';
}
function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect();
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}
canvas {border: 1px solid #999}
<canvas id="testCanvas" width="400" height="400"> </canvas>
Here is another example / way of adding an event handler. You can change 'click' to 'mousemove' and others to try different things.
// access the canvas element and its context
window.onload = init;
function init(){
var canvas = document.getElementById("testCanvas");
var context = canvas.getContext("2d");
function drawCircle(pos,canvas){
posx = pos.x;
posy = pos.y;
context.fillStyle = randomColor();
// fill a circle
context.beginPath();
context.arc(posx,posy, 30, 0, 2 * Math.PI, true);
context.fill();
context.closePath();
}
function randomColor() {
var color = [];
for (var i = 0; i < 3; i++) {
color.push(Math.floor(Math.random() * 256));
}
return 'rgb(' + color.join(',') + ')';
}
function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect();
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
} ;
}
canvas.addEventListener('click', function(evt){
var mousePos = getMousePos(canvas,evt);
drawCircle(mousePos,canvas);
},false);
}
I'm trying to make a grid that when clicking in a square it turns green, but i keep having trouble with adding objects to my array, if there preset they display fine but if add them once i click my mouse they wont render.
var canvas = document.getElementById("ctx");
var ctx = canvas.getContext("2d");
var Img = {};
Img.tileMap = new Image();
Img.tileMap.src = 'TitleMap.png';
WIDTH = 1536;
HEIGHT = 896;
currentImage = [32, 32];
ctx.strokeStyle = '#ffffff';
function createGrid() {
ctx.strokeStyle = '#ffffff'
for (var i = 0; i < WIDTH; i++) {
ctx.beginPath();
ctx.moveTo(i * 32, 0);
ctx.lineTo(i * 32, HEIGHT);
ctx.stroke();
}
for (var i = 0; i < HEIGHT; i++) {
ctx.beginPath();
ctx.moveTo(0, i * 32);
ctx.lineTo(1536, i * 32);
ctx.stroke();
}
}
var tiles = [{
x: 1,
y: 1
}];
var mousePos = null;
function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect();
return {
x: Math.round((evt.clientX - rect.left) / (rect.right - rect.left) *
canvas.width),
y: Math.round((evt.clientY - rect.top) / (rect.bottom - rect.top) *
canvas.height)
};
}
canvas.addEventListener('mousemove', function(evt) {
mousePos = getMousePos(canvas, evt);
}, false);
document.body.onmousedown = function() {
pos = {
x: Math.floor(mousePos.x / 32),
y: Math.floor(mousePos.y / 32),
};
tiles.push(pos);
}
function drawTiles() {
ctx.clearRect(0, 0, WIDTH, HEIGHT);
createGrid();
if (tiles.length) {
for (var id in tiles) {
ctx.fillStyle = "#42f456";
ctx.strokeStyle = '#42f456';
ctx.fillRect(tiles[id].x, tiles[id].y, 32, 32);
}
}
}
setInterval(drawTiles(), 1000 / 30);
<center>
<canvas id="ctx" width="1536" height="896" style="border:1px solid #ffffff;">
</canvas>
</center>
You were doing your setInterval wrong-- you want to pass the function, not call it-- otherwise whatever the function returns is what is passed to setInterval.
<body bgcolor="#000000">
<center><canvas id="ctx" width="1536" height="896" style="border:1px solid #ffffff;">
</canvas></center>
<script>
var canvas = document.getElementById("ctx");
var ctx = canvas.getContext("2d");
var Img = {};
Img.tileMap = new Image();
Img.tileMap.src = 'TitleMap.png';
WIDTH = 1536;
HEIGHT = 896;
currentImage = [32,32];
ctx.strokeStyle = '#ffffff';
function createGrid(){
ctx.strokeStyle = '#ffffff'
for (var i = 0 ; i < WIDTH; i++){
ctx.beginPath();
ctx.moveTo(i*32,0);
ctx.lineTo(i*32,HEIGHT);
ctx.stroke();
}
for (var i = 0 ; i < HEIGHT; i++){
ctx.beginPath();
ctx.moveTo(0,i*32);
ctx.lineTo(1536,i*32);
ctx.stroke();
}
}
var tiles = [{x:1,y:1}];
var mousePos = null;
function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect();
return {
x: Math.round((evt.clientX-rect.left)/(rect.right-rect.left)*canvas.width),
y: Math.round((evt.clientY-rect.top)/(rect.bottom-rect.top)*canvas.height)
};
}
canvas.addEventListener('mousemove', function(evt) {
mousePos = getMousePos(canvas, evt);
}, false);
document.body.onmousedown = function() {
pos = {
x:Math.floor(mousePos.x/32),
y:Math.floor(mousePos.y/32),
};
tiles.push(pos);
}
function drawTiles(){
ctx.clearRect(0,0,WIDTH,HEIGHT);
createGrid();
if(tiles.length){
for (var id in tiles){
ctx.fillStyle = "#42f456";
ctx.strokeStyle = '#42f456';
ctx.fillRect(tiles[id].x,tiles[id].y,32,32);
}
}
}
setInterval(drawTiles,1000/30);
</script>
</body>
Also, a few quick notes-- you're playing fast and loose with your var statements-- make sure if you don't want a variable to be global you declare it with a var. And also note that for...in loops are for iterating over object keys-- to iterate over an array, use a standard for loop. And finally, consider if a setInterval is even required-- seems like it might be sufficient to simply call drawTiles in the onmousedown after you push the new position into the tiles array.
I want to draw rectangle on canvas. Below code is working fine except when i draw rectangle it does't show path when mouse is moving. When i left the mouse then rectangle is visible on canvas.
Please help,
Thanks
var canvas, ctx, flag = false,
prevX = 0,
currX = 0,
prevY = 0,
currY = 0,
currShape = 'rectangle',
mouseIsDown = 0,
startX, endX, startY, endY,
dot_flag = false;
var x = "white",
y = 2;
function init() {
canvas = document.getElementById('can');
ctx = canvas.getContext("2d");
var imageObj = new Image(); //Canvas image Obj
imageObj.onload = function() {
ctx.drawImage(imageObj, 69, 50); //Load Image on canvas
};
imageObj.src = 'http://www.html5canvastutorials.com/demos/assets/darth-vader.jpg'; //Load Image
w = canvas.width; // Canvas Width
h = canvas.height; // Canvas Height
//Check Shape to be draw
eventListener();
}
function eventListener(){
if(currShape=='rectangle'){
canvas.addEventListener("mousedown",function (e) {
mouseDown(e);
}, false);
canvas.addEventListener("mousemove",function (e){
mouseXY(e);
}, false);
canvas.addEventListener("mouseup", function (e){
mouseUp(e);
}, false);
}
}
function mouseUp(eve) {
if (mouseIsDown !== 0) {
mouseIsDown = 0;
var pos = getMousePos(canvas, eve);
endX = pos.x;
endY = pos.y;
if(currShape=='rectangle')
{
drawSquare(); //update on mouse-up
}
}
}
function mouseDown(eve) {
mouseIsDown = 1;
var pos = getMousePos(canvas, eve);
startX = endX = pos.x;
startY = endY = pos.y;
if(currShape=='rectangle')
{
drawSquare(); //update on mouse-up
}
}
function mouseXY(eve) {
if (mouseIsDown !== 0) {
var pos = getMousePos(canvas, eve);
endX = pos.x;
endY = pos.y;
//drawSquare();
}
}
function drawSquare() {
// creating a square
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);
ctx.beginPath();
ctx.globalAlpha=0.7;
ctx.rect(startX + offsetX, startY + offsetY, width, height);
ctx.fillStyle = x;
ctx.fill();
ctx.lineWidth = y;
ctx.strokeStyle = x;
ctx.stroke();
}
function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect();
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}
.colortool div {
width: 15px;
height: 15px;
float: left;
margin-left: 2px;
}
.clear {
clear: both;
}
<!DOCTYPE HTML>
<html>
<body onload="init()">
<div class="canvasbody">
<canvas id="can" width="400" height="400" style="border:1px dotted #eee;"></canvas>
</div>
</body>
</html>
Here is you new JavaScript
var canvas, cnvHid, cnvRender, ctx, flag = false,
prevX = 0,
currX = 0,
prevY = 0,
currY = 0,
currShape = 'rectangle',
mouseIsDown = 0,
startX, endX, startY, endY,
dot_flag = false;
var x = "white",
y = 2;
function init() {
canvas = document.getElementById('can');
cnvHid = document.getElementById( "canHid" );
cnvRender = document.getElementById( "canRend" );
ctx = canvas.getContext("2d");
var imageObj = new Image(); //Canvas image Obj
imageObj.onload = function() {
ctx.drawImage(imageObj, 69, 50); //Load Image on canvas
renderAllCanvas();
};
imageObj.src = 'http://www.html5canvastutorials.com/demos/assets/darth-vader.jpg'; //Load Image
w = canvas.width; // Canvas Width
h = canvas.height; // Canvas Height
//Check Shape to be draw
eventListener();
}
function eventListener(){
if(currShape=='rectangle'){
cnvRender.addEventListener("mousedown",function (e) {
mouseDown(e);
renderAllCanvas();
}, false);
cnvRender.addEventListener("mousemove",function (e){
mouseXY(e);
renderAllCanvas();
}, false);
cnvRender.addEventListener("mouseup", function (e){
mouseUp(e);
renderAllCanvas();
}, false);
}
}
function mouseUp(eve) {
if (mouseIsDown !== 0) {
mouseIsDown = 0;
var pos = getMousePos(canvas, eve);
endX = pos.x;
endY = pos.y;
if(currShape=='rectangle')
{
drawSquare( canvas ); //update on mouse-up
cnvHid.getContext( "2d" ).clearRect( 0, 0, cnvHid.width, cnvHid.height );
}
}
}
function mouseDown(eve) {
mouseIsDown = 1;
var pos = getMousePos(canvas, eve);
startX = endX = pos.x;
startY = endY = pos.y;
if(currShape=='rectangle')
{
drawSquare( canvas ); //update on mouse-up
}
}
function mouseXY(eve) {
if (mouseIsDown !== 0) {
var pos = getMousePos(canvas, eve);
endX = pos.x;
endY = pos.y;
drawSquare( cnvHid, true );
}
}
function drawSquare( cnv, clear ) {
var ctx = cnv.getContext( "2d" );
if( clear && clear === true ){
ctx.clearRect( 0, 0, cnv.width, cnv.height );
}
// creating a square
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);
ctx.beginPath();
ctx.globalAlpha=0.7;
ctx.rect(startX + offsetX, startY + offsetY, width, height);
ctx.fillStyle = x;
ctx.fill();
ctx.lineWidth = y;
ctx.strokeStyle = x;
ctx.stroke();
ctx.closePath();
}
function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect();
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}
function renderAllCanvas(){
var cnxRender = cnvRender.getContext( "2d" );
cnxRender.drawImage(
canvas
,0,0
,cnvRender.width,cnvRender.height
);
cnxRender.drawImage(
cnvHid
,0,0
,cnvRender.width,cnvRender.height
);
}
And here is you new HTML
<!DOCTYPE HTML>
<html>
<body onload="init()">
<div class="canvasbody">
<canvas id="can" width="400" height="400" style="display: none;"></canvas>
<canvas id="canHid" width="400" height="400" style="display: none;"></canvas>
<canvas id="canRend" width="400" height="400" style="border:1px dotted #eee;"></canvas>
</div>
</body>
</html>
In some way, you would need to keep track on the changes you make to a shape you draw on the canvas. In your case, you would start by creating a very small rectangle and then scale it according to your mouse position during your dragmove.
Currently, you only have a function which draws an entirely new rectangle but does not take any previous "state" into consideration.
I found this blogpost which could be helpful. It doesn't explain scaling in particular but it could help with the basic concepts behind so I think this would be a good way for you to find a suitable solution.
Since we are finding the canvas tag in the DOM using it’s id and then setting the drawing context of the canvas to 2D. Two things is importent here is store the information as we draw the recatangle and a bolean to check user is drawing the rectangleor not.
You can reffer these links:Drawing a rectangle using click, mouse move, and click
Draw on HTML5 Canvas using a mouse
Check the js fiddle in the given link.
Hope this will help you..
Your current code has the redraw commented out on the mouse move, which would be required to update the canvas. However your code is also destroying the image the way the rectangle is being drawn. If you retain the image as shown below and redraw it on each frame before drawing the rectangle, it might have the desired effect.
var canvas, ctx, flag = false,
prevX = 0,
currX = 0,
prevY = 0,
currY = 0,
currShape = 'rectangle',
mouseIsDown = 0,
startX, endX, startY, endY,
dot_flag = false;
var x = "white",
y = 2,
image = null;
function init() {
canvas = document.getElementById('can');
ctx = canvas.getContext("2d");
var imageObj = new Image(); //Canvas image Obj
imageObj.onload = function() {
image = imageObj;
ctx.drawImage(image, 69, 50); //Load Image on canvas
};
imageObj.src = 'http://www.html5canvastutorials.com/demos/assets/darth-vader.jpg'; //Load Image
w = canvas.width; // Canvas Width
h = canvas.height; // Canvas Height
//Check Shape to be draw
eventListener();
}
function eventListener(){
if(currShape=='rectangle'){
canvas.addEventListener("mousedown",function (e) {
mouseDown(e);
}, false);
canvas.addEventListener("mousemove",function (e){
mouseXY(e);
}, false);
canvas.addEventListener("mouseup", function (e){
mouseUp(e);
}, false);
}
}
function mouseUp(eve) {
if (mouseIsDown !== 0) {
mouseIsDown = 0;
var pos = getMousePos(canvas, eve);
endX = pos.x;
endY = pos.y;
if(currShape=='rectangle')
{
drawSquare(); //update on mouse-up
}
}
}
function mouseDown(eve) {
mouseIsDown = 1;
var pos = getMousePos(canvas, eve);
startX = endX = pos.x;
startY = endY = pos.y;
if(currShape=='rectangle')
{
drawSquare(); //update on mouse-up
}
}
function mouseXY(eve) {
if (mouseIsDown !== 0) {
var pos = getMousePos(canvas, eve);
endX = pos.x;
endY = pos.y;
drawSquare();
}
}
function drawSquare() {
// draw background image
if(image) {
ctx.drawImage(image, 69, 50);
}
// creating a square
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);
ctx.beginPath();
ctx.globalAlpha=0.7;
ctx.rect(startX + offsetX, startY + offsetY, width, height);
ctx.fillStyle = x;
ctx.fill();
ctx.lineWidth = y;
ctx.strokeStyle = x;
ctx.stroke();
}
function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect();
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}
.colortool div {
width: 15px;
height: 15px;
float: left;
margin-left: 2px;
}
.clear {
clear: both;
}
<!DOCTYPE HTML>
<html>
<body onload="init()">
<div class="canvasbody">
<canvas id="can" width="400" height="400" style="border:1px dotted #eee;"></canvas>
</div>
</body>
</html>