Javascript paint canvas - javascript

I have a problem with my code. It is a simple canvas element drawing circles. There are two things I cannot figure out. The first one is how to draw circles continously (not one at a time) while I keep left mouse button pressed. "Onmousehold" doesn't seem to work here. Secondly is it possible to get rid of the first reference error from the console? It appears only once when coordinates of a click are not yet specified. My code here:
var outer = document.getElementById("outer");
var ctx = outer.getContext("2d");
function getMousePos(e) {
var cursorX = e.clientX;
var cursorY = e.clientY;
x = cursorX;
y = cursorY;
}
function showBox() {
ctx.beginPath();
ctx.arc(x,y,20,0,2*Math.PI);
ctx.stroke();
console.log(x,y);
}
outer.addEventListener("click",getMousePos);
outer.addEventListener("click",showBox);
outer.addEventListener("mousedown",showBox);
#outer {
position:relative;
overflow: hidden;
border: 1px solid green;
}
.popup {
width: 50px;
height: 50px;
border-radius: 25px;
background-color: blue;
position: absolute;
}
<canvas id="outer" width="600" height="600">
</canvas>
And jsfiddle
jsfiddle

see this: http://jsfiddle.net/4ovgzk07/2/
var outer = document.getElementById("outer");
var ctx = outer.getContext("2d");
function getMousePos(e) {
var cursorX = e.clientX;
var cursorY = e.clientY;
x = cursorX;
y = cursorY;
}
function showBox() {
ctx.beginPath();
ctx.arc(x,y,20,0,2*Math.PI);
ctx.stroke();
console.log(x,y);
outer.addEventListener("mousemove",getMousePos);
outer.addEventListener("mousemove",showBox)
outer.addEventListener("mouseup",removelisteners);
}
function removelisteners() {
outer.removeEventListener("mousemove",getMousePos);
outer.removeEventListener("mousemove",showBox)
}
outer.addEventListener("mousedown",getMousePos);
outer.addEventListener("mousedown",showBox);
;
Youu need to attach events for mousemove when mousedown occurs, similarly remove those events on mouseup

Related

adding image inside html canvas using javascript not working

i am trying to create an image canvas where user can zoom into the image, the code which i got from here enter link description here, now i tried to add image inside it and i did the following code:
function draw(scale, translatePos) {
var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d");
make_base(context);
}
function make_base(context) {
var base_image = new Image();
base_image.src = 'https://www.gstatic.com/webp/gallery3/1.sm.png';
base_image.onload = function() {
context.drawImage(base_image, 0, 0);
}
}
window.onload = function() {
var canvas = document.getElementById("myCanvas");
var translatePos = {
x: canvas.width / 2,
y: canvas.height / 2
};
var scale = 1.0;
var scaleMultiplier = 0.8;
var startDragOffset = {};
var mouseDown = false;
// add button event listeners
document.getElementById("plus").addEventListener("click", function() {
scale /= scaleMultiplier;
draw(scale, translatePos);
}, false);
document.getElementById("minus").addEventListener("click", function() {
scale *= scaleMultiplier;
draw(scale, translatePos);
}, false);
// add event listeners to handle screen drag
canvas.addEventListener("mousedown", function(evt) {
mouseDown = true;
startDragOffset.x = evt.clientX - translatePos.x;
startDragOffset.y = evt.clientY - translatePos.y;
});
canvas.addEventListener("mouseup", function(evt) {
mouseDown = false;
});
canvas.addEventListener("mouseover", function(evt) {
mouseDown = false;
});
canvas.addEventListener("mouseout", function(evt) {
mouseDown = false;
});
canvas.addEventListener("mousemove", function(evt) {
if (mouseDown) {
translatePos.x = evt.clientX - startDragOffset.x;
translatePos.y = evt.clientY - startDragOffset.y;
draw(scale, translatePos);
}
});
draw(scale, translatePos);
};
jQuery(document).ready(function() {
$("#wrapper").mouseover(function(e) {
$('#status').html(e.pageX + ', ' + e.pageY);
});
})
body {
margin: 0px;
padding: 0px;
}
#wrapper {
position: relative;
border: 1px solid #9C9898;
width: 578px;
height: 200px;
}
#buttonWrapper {
position: absolute;
width: 30px;
top: 2px;
right: 2px;
}
input[type="button"] {
padding: 5px;
width: 30px;
margin: 0px 0px 2px 0px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<body onmousedown="return false;">
<div id="wrapper">
<canvas id="myCanvas" width="578" height="200">
</canvas>
<div id="buttonWrapper">
<input type="button" id="plus" value="+"><input type="button" id="minus" value="-">
</div>
</div>
<h2 id="status">
0, 0
</h2>
</body>
however the image is not getting displayed inside the canvas, can anyone please tell me what could be wrong in here, thanks in advance
Your draw function never actually draws to the canvas. You get the canvas and context in the first 2 lines, but you need to call drawImage with the image to actually add it to the canvas itself.
I suspect you want to be calling make_base inside it like so:
function draw(scale, translatePos) {
var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d");
make_base();
}
You also need to have the context in the same scope as you use it. At the moment, the variable context only exists inside the draw function and not the make_base function, so you can't access it from inside make_base.
You can pass it as a variable like so:
function draw(scale, translatePos) {
var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d");
make_base(context);
}
function make_base(context) {
var base_image = new Image();
base_image.src = 'a2.jpg';
base_image.onload = function() {
context.drawImage(base_image, 0, 0);
}
}
Every time you want to change anything on an HTML canvas you need to call draw functions to change what's there.

How do I make multiple moving squares on a canvas?

So far I have made a moving square that when the button is clicked in the HTML file, calls the draw() function and draws a red square in the canvas area that moves accross the canvas. How do I make it so that the same function draw() can create multiple moving sqaures?
Here's the code so far:
var x = 10;
var y = 10;
function draw(){
var can = document.getElementById("myCanvas");
var ctx = can.getContext("2d");
var x = 1;
setInterval(function(){
ctx.clearRect(0,0, can.width, can.height);
ctx.fillRect(x, 20, 75, 75);
ctx.fillStyle ="red";
x=x+5;
}, 500
);
}
Not sure that my solution is good, I'm just starting to learn js, but hope it will helpful.
// variables declaration. I suggest to use Arrays
// for store individual rectangle parameters.
// rectangle start coords x and y
var rcx = [];
var rcy = [];
// delta to move x, y
var dx = [];
var dy = [];
// rectangle size (if you want it variable)
var size =[];
// init canvas
let canvas = document.getElementById('canvas');
let ctx = canvas.getContext('2d');
// create and collect rectangles parameters
// on window load (here 100 rectangles created)
// with unique coords, deltas to move,
// and sizes for each rectangle.
window.onload = function() {
for (var i=0; i<100; i++) {
// in this solution all parameters randomized,
// but you can set whatever you want.
rcx[i]=(Math.floor(Math.random() * Math.floor(canvas.width)));
rcy[i]=(Math.floor(Math.random() * Math.floor(canvas.height)));
dx[i]= (Math.floor(Math.random() * Math.floor(3))-1);
dy[i]=(Math.floor(Math.random() * Math.floor(3))-1);
size[i] = (Math.floor(Math.random() * Math.floor(8)));
}};
// it is optional, but i decide
// made function for rectangle declaration.
// It will looks more compact when rendering.
function rect(x, y, size){
ctx.fillRect(x, y, size, size/2 );
ctx.fillStyle = "rgba(255,255,255,1)";
}
// finally all together into function draw()
function draw(){
setInterval(function(){
ctx.clearRect(0,0, canvas.width, canvas.height);
for (var j=0; j<100; j++) {
// read arrays
// render rectangle with params from arrays
rect(rcx[j],rcy[j],size[j]);
// add delta to move (x,y)
// and rewrite new coords to arrays
rcx[j]=rcx[j]+dx[j];
rcy[j]=rcy[j]+dy[j]};
}, 100
);
};
//rendering animation
draw();
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
#canvas {
width: 500px;
height: 500px;
background-color: #ccc;
}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<script src="js1.js"></script>
</body>
</html>
Sorry, didn't mention about button. So for the btn changes are simple.
Create btn div in html,
Add listener on this div. Рut params in arrays if button is pushed. Instead of generation by random as it was in my solution before.
Read arrays and render all rectangles from it.
// variables declaration. I suggest to use Arrays for store individual rectangle parameters.
// rectangle start coords x and y
var rcx = [];
var rcy = [];
// delta to move x, y
var dx = [];
var dy = [];
// rectangle size (if you want it variable)
var size =[];
//counter for created rectangles
var i=0;
// init canvas
let canvas = document.getElementById('canvas');
let ctx = canvas.getContext('2d');
// create and collect rectangles parameters on btn push
// with unique coords, deltas to move, and sizes for each rectangle.
var btn =document.getElementById('btn');
btn.addEventListener( 'click', function() {
//count every time you push the btn and create rect
i=i+1;
//generate rect params x,y, delta x, delta y, size
rcx[i]=20;
rcy[i]=20;
dx[i]=1
dy[i]=0
size[i] = 8;
});
// it is optional, but i decide made function for rectangle declaration. It will looks more compact when rendering.
function rect(x, y, size){
ctx.fillRect(x, y, size, size/1.5);
ctx.fillStyle = "red";
}
// finally all together into function draw()
function draw(){
setInterval(function(){
ctx.clearRect(0,0, canvas.width, canvas.height);
for (var j=1; j<rcx.length; j++) {
// read arrays
// render rectangle with params from arrays
rect(rcx[j],rcy[j],size[j]);
// add delta to move (x,y) and rewrite new coords to arrays
rcx[j]=rcx[j]+dx[j];
rcy[j]=rcy[j]+dy[j]};
}, 100
);
};
//rendering animation
draw();
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
body{
margin: 0 auto;
padding: 0;
background-color: rgb(17, 0, 28);
}
#container{
position: relative;
margin-top: 10px;
margin-left: 50px;
}
#canvas {
z-index: 0;
position:fixed;
align-self: center;
justify-self: center;
width: 80vw;
height: 50vw;
background-color: #ccc;
}
#btn {
margin: 20px 20px 20px 0px;
padding: 10px;
position:static;
top: 30px;
font-family: 'Roboto', sans-serif;
width: 65px;
background-color: brown;
cursor: pointer;
}
#btn:hover {
background-color: red;
}
#btn:active {
background-color: coral;
}
</style>
</head>
<body>
<div id="container">
<div id="btn"> Push me </div>
<canvas id="canvas"></canvas>
</div>
<script src="js1.js"></script>
</body>
</html>

Creating Circles(div) and appending it to div#canvas

I am trying to create new circles as my pen hovers on window.
I am having issues where I cannot add circles to the page. It just hovers around. How would i be able to modify my code to add circles as it hovers.
<!doctype html>
<html>
<head>
<title> JavaScript Environment: Project </title>
<meta charset="utf-8">
<style>
html, body {
width: 100%;
height: 100%;
margin: 0px;
padding: 0px;
}
#canvas {
background-color: yellow;
width: 100%;
height: 100%;
}
.pen {
position: absolute;
background-color: lightblue;
width: 10px;
height: 10px;
border-radius: 5px;
}
</style>
<script>
window.onload = function() {
function Circle(x, y) {
this.x = x;
this.y = y;
}
var canvas = document.getElementById("canvas");
canvas.onmousedown = function() {
mouseDown();
};
canvas.onmouseup = function() {
mouseUp()
};
canvas.onmousemove = function() {
mouseMove(event)
};
function mouseDown (){
console.log ("mouse down");
}
function mouseUp (){
console.log ("mouse up");
}
function mouseMove(e) {
var canvas = document.getElementById("canvas");
var pen = document.createElement("div");
var x = e.clientX;
var y = e.clientY;
var coor = "Coordinates: (" + x + "," + y + ")";
pen.setAttribute("class", "pen");
pen.style.left = x + "px";
pen.style.top = y + "px";
document.getElementById("canvas").innerHTML = coor;
canvas.appendChild(pen);
addCircles(x, y);
console.log("location # " + x + " : " + y);
}
function addCircles(x, y) {
var canvas = document.getElementById("canvas");
var circle = document.createElement("div");
circle.setAttribute("class", "pen");
circle.style.left = x + "px";
circle.style.top = y + "px";
canvas.appendChild(circle);
}
canvas.addEventListener("mouseMove", mouseMove, false);
};
</script>
</head>
<body>
<div id="canvas"></div>
</body>
</html>
The problem is in the line document.getElementById("canvas").innerHTML = coor;
Try adding a span <span id="canvasText"></span> inside of your canvas div and then changing the above line to document.getElementById("canvasText").innerHTML = coor;.
As it stands, you "reset" the contents of the canvas every time the mouse moves, so the circles are instantly removed from it. Reset only the span inside the canvas to keep the circles around.

Get Click Coordinates on canvas inside DIV

I have a canvas inside a div which makes it scrollable to the right/left if its to large. I need to get the click coordinates on the canvas. I have tried so many different things I have seen but nothing is giving me the right coordinates. I have a rectangle in the canvas and when i click on the rectangle which is at a set coordinate.The "clicked" coordinates are not what they should be the x coordinate is 100px short. Could anyone point me in the right direction ?
HTML:
<div id="cv">
<canvas id="canvas" width="30000" height="600"></canvas>
</div>
CSS:
<style>
#cv{
display: block;
width: 1500px;
height: 500px;
overflow: auto;
}
<script>
canvas.addEventListener("mousedown", doMouseDown, false);
function doMouseDown(event){
var totalOffsetX = 0;
var totalOffsetY = 0;
var canvasX = 0;
var canvasY = 0;
var currentElement = this;
do{
totalOffsetX += currentElement.offsetLeft - currentElement.scrollLeft;
totalOffsetY += currentElement.offsetTop - currentElement.scrollTop;
}
while(currentElement = currentElement.offsetParent)
canvasX = event.pageX - totalOffsetX;
canvasY = event.pageY - totalOffsetY;
}
</script>
I just used a mouse following function, and if there was a click it takes the coordinates of that. It isnt how I wanted it to go but it seems to be working fine.

canvas offset- mouse pointer not synced

the drawing not synced with mouse pointer, same goes to touch screen. I have set function getMouse(e) offset for mouse coordinates and function draw(event) for touch coordinates. It is only works for my pc. It doesn't compatible with different touch screen pcs. Where i should make changes and how. Please help.
here is the coding
http://jsfiddle.net/gFXam/
HTML
<button onClick="openPopup();">drawing</button>
<div id="test" class="popup" >
<canvas id="canvas1" width="790" height="1110" style=" border:solid #00F"> </canvas>
<p> </p>
</div>
CSS
<style>
#canvas1 {
left:0; /* adjust as needed */
top:0;
position: inline;
width: 100%;
height: 100%;
}
.popup{
position:absolute;
top:0px;
left:0px;
margin:0px;
width: 764px;
height: 1120px;
font-family:verdana;
font-size:13px;
background-color:rgba(255, 255, 255, 0);
border:2px solid green;
z-index:100000000000000000;
display:none;
opacity:0.6;
filter:alpha(opacity=60);
margin-left: 400px;
margin-top: 100px;
}
.cancel{
display:relative;
cursor:pointer;
margin:0;
float:right;
height:10px;
width:14px;
padding:0 0 5px 0;
background-image:url(/images/icon-cross.png);
text-align:center;
font-weight:bold;
font-size:11px;
color:white;
border-radius:3px;
z-index:100000000000000000;
}
.cancel:hover{
background-color:#09F;
}
</style>
SCRIPT :
<script>
function openPopup() {
var p = document.getElementById('test');
p.style.display = 'block';
canvas.width = parseInt(p.style.width, '10'); //only when you use pixels
canvas.height = parseInt(p.style.height, '10');
}
function closePopup() {
document.getElementById('test').style.display = 'none';
}
function choosecolor(cps) {
ctx.strokeStyle = cps; // red
}
var can = document.getElementById('canvas1');
var ctx = can.getContext('2d');
var isPressed = false;
var mx = 4, my = 4;
//http://stackoverflow.com/questions/2142535/how-to-clear-the-canvas-for-redrawing
function clear_canvas_width ()
{
var s = document.getElementById ("canvas1");
var w = s.width;
s.width = 4;
s.width = w;
ctx.clear();
}
function move(e) {
getMouse(e);
if (isPressed) {
ctx.lineTo(mx, my);
ctx.stroke()
}
}
function up(e) {
getMouse(e);
isPressed = false;
}
function down(e) {
getMouse(e);
ctx.beginPath();
ctx.moveTo(mx, my);
isPressed = true;
}
can.onmousemove = move;
can.onmousedown = down;
can.onmouseup = up;
// for mouse:
function getMouse(e) {
var element = can, offsetX = 0, offsetY = 0;
mx = e.pageX - 400;
my = e.pageY - 108;
}
/*For touch screen*/
window.addEventListener('load',function(){
// get the canvas element and its context
var canvas = document.getElementById('canvas1');
var context = canvas.getContext('2d');
// create a drawer which tracks touch movements
var drawer = {
isDrawing: false,
touchstart: function(coors){
context.beginPath();
context.moveTo(coors.x, coors.y);
this.isDrawing = true;
},
touchmove: function(coors){
if (this.isDrawing) {
context.lineTo(coors.x, coors.y);
context.stroke();
}
},
touchend: function(coors){
if (this.isDrawing) {
this.touchmove(coors);
this.isDrawing = false;
}
}
};
// create a function to pass touch events and coordinates to drawer
function draw(event){
// get the touch coordinates
var coors = {
x: event.targetTouches[0].pageX - 400,
y: event.targetTouches[0].pageY - 100
};
// pass the coordinates to the appropriate handler
drawer[event.type](coors);
}
// attach the touchstart, touchmove, touchend event listeners.
canvas.addEventListener('touchstart',draw, false);
canvas.addEventListener('touchmove',draw, false);
canvas.addEventListener('touchend',draw, false);
// prevent elastic scrolling
document.body.addEventListener('touchmove',function(event){
event.preventDefault();
},false); // end body.onTouchMove
},false); // end window.onLoad
</script>
Change your getMouse to this and it should work:
function getMouse(e) {
mx = e.clientX - canvas.offsetLeft;
my = e.clientY - canvas.offsetTop;
}
The mouse positions are relative to the whole page so you need to subtract the offset of the canvas element to get them relative to the canvas.

Categories