Is it possible to create HTML5 canvas dynamically with the mouse?
For example: I want to use my mouse to draw HTML5 canvas then load content into the different canvas.
3 hour I search over the internet for a demo and I found nothing about that possibility.
You can create a canvas on the mouse location
http://jsfiddle.net/v4nm487b/
document.onmousedown=mouseDown;
document.onmouseup=mouseUp;
var x1,y1;
function mouseDown(e){
x1=e.clientX;
y1=e.clientY;
}
function mouseUp(e){
var can = document.createElement("CANVAS");
can.style.position = "absolute";
can.style.left = x1+"px";
can.style.top = y1+"px";
can.width=Math.abs(x1-e.clientX);
can.height=Math.abs(y1-e.clientY);
can.style.border="1px solid black"
document.body.appendChild(can);
}
But what do you mean with load the content?
edit: dynamic content
You can give the canvas an id and use that to draw on it
In this exemple the created canvases have the id canN (can0,can1,canN)
If we presse 0 on the numpad (keycode 48), I fill canvas can(48-48)= can0
This ofcourse only work up to 9 but it does prove it can(vas) be done
http://jsfiddle.net/v4nm487b/6/
I can't say this for certain, as I've never tried it, but you might look into the mousedown and mouseup events. You could create an element that the user can drag in and listen for those events on it like this:
var startX, startY, endX, endY;
$('#drag')
.mousedown(function(e) {
startX = e.pageX;
startY = e.pageY;
$('#start').text(startX + ", " + startY);
})
.mouseup(function(e) {
endX = e.pageX;
endY = e.pageY;
$('#end').text(endX + ", " + endY);
});
#drag {
width: 100%;
height: 500px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="start"></div>
<div id="end"></div>
<div id="drag"></div>
That gives you the start and end positions of the drag, you can then append a canvas element with some absolute positioning based on those coordinates. Hope this helps!
Related
I used onmousedown, onmousemove and onmouseup events to draw with JavaScript on a HTML5 canvas object. Everything is working.
Now I want to replace the mouse with a sylus (Wacom Intous Pro)
Therefore I replaced the mouse Events with onpointerdown, onpointerup and onpointermove.
But now, if I touch and move the pen, I do not get any onpointermove Events, instead the whole page is draged. By adding html, body {overflow: hidden} to the HTML construct I could Prevent this behaviour, but still I do not get any onpointermove Events. These I only get when the pen is above the tablet.
Has somebody an idea how to solve it?
Corrently this is the concept I use (but not working):
$(function() {
var el=document.getElementById("myDraw");
el.onpointerdown = down_handler;
el.onpointerup = up_handler;
el.onpointermove = move_handler;
ctx = el.getContext("2d");
ctx.canvas.width = window.innerWidth*0.75;
ctx.canvas.height = window.innerHeight*0.75;
});
function move_handler(ev)
{
if (onTrack>0)
{
var xPosition = ev.clientX-getPosition(document.getElementById("myDraw")).x;
var yPosition = ev.clientY-getPosition(document.getElementById("myDraw")).y;
ctx.beginPath();
ctx.lineWidth=10*ev.pressure;
ctx.moveTo(lastX,lastY);
ctx.lineTo(xPosition,yPosition);
ctx.stroke();
lastX = xPosition;
lastY = yPosition;
}
}
function down_handler(ev)
{
var xPosition = ev.clientX-getPosition(document.getElementById("myDraw")).x;
var yPosition = ev.clientY-getPosition(document.getElementById("myDraw")).y;
ctx.beginPath();
ctx.arc(xPosition, yPosition, 5, 0, 2 * Math.PI);
ctx.stroke();
startX = xPosition;
startY = yPosition;
lastX = xPosition;
lastY = yPosition;
onTrack=1;
var el=document.getElementById("myRemoteDraw");
el.setPointerCapture(ev.pointerId);
console.log('pointer down '+ev.pointerId);
}
function up_handler(ev)
{
var xPosition = ev.clientX-getPosition(document.getElementById("myDraw")).x;
var yPosition = ev.clientY-getPosition(document.getElementById("myDraw")).y;
ctx.beginPath();
ctx.rect(xPosition-5, yPosition-5, 10, 10);
ctx.stroke();
onTrack = 0;
var el=document.getElementById("myRemoteDraw");
el.releasePointerCapture(ev.pointerId);
console.log('pointer up '+ev.pointerId);
}
This CSS should help you:
<style>
/* Disable intrinsic user agent touch behaviors (such as panning or zooming) */
canvas {
touch-action: none;
}
</style>
or in JavaScript:
ctx.canvas.style.touchAction = "none";
More details from this link about "touch-action" and some general info in this link about inputs:
The touch-action CSS property is used to specify whether or not the browser should apply its default (native) touch behavior (such as zooming or panning) to a region. This property may be applied to all elements except: non-replaced inline elements, table rows, row groups, table columns, and column groups.
A value of auto means the browser is free to apply its default touch behavior (to the specified region) and the value of none disables the browser's default touch behavior for the region. The values pan-x and pan-y, mean that touches that begin on the specified region are only for horizontal and vertical scrolling, respectively. The value manipulation means the browser may consider touches that begin on the element are only for scrolling and zooming.
I've been playing around with the HTML5 canvas lately and one of the things I've wanted to do is create a simple page with a canvas that'll draw a circle wherever you click. I have some code that looks like it should work, and I've been attempting to debug with some console output, but I've been unable to see any errors at the moment.
I'm using Codepen though, so I'm unsure how fully featured that console is, and I unfortunately can't use the dev console on my laptop at the moment (locked down school Chromebook).
Could someone take a look? I'll put the code in here and drop a link to the pen as well. Thanks!
HTML:
<canvas id="canvas" onclick="drawCircle(event)"></canvas>
CSS:
canvas {
position: relative;
background: #f1c40f;
width: 100%;
height: 100%;
}
JS:
var c = document.getElementById("canvas");
var ctx = c.getContext("2d");
function drawCircle(e) {
var pos = getCursorPosition(c, e);
var clickX = pos.x;
var clickY = pos.y;
ctx.fillStyle = "#2980b9";
ctx.beginPath();
ctx.arc(clickX, clickY, 10, 0, 2 * Math.PI);
ctx.fill();
console.log(clickX, clickY);
console.log("drawcircle");
}
function getCursorPosition(canvas, e) {
// Gets click position
rect = canvas.getBoundingClientRect();
console.log('getcursorpos');
return {
x: e.clientX - rect.left,
y: e.clientY - rect.top
};
}
Codepen link: https://codepen.io/wolverine1621/pen/gWvjgx
Any help is appreciated. It's probably something pretty simple but this is really my first time working with canvas, so any input is helpful!
Thanks!
The issue is occurring because, you set the canvas's width and height using css.
You should rather set it using javascript, like so ...
c.width = window.innerWidth;
c.height = window.innerHeight;
and to make the canvas flexible, so that it maintains it's size, use ...
window.onresize = function() {
c.width = window.innerWidth;
c.height = window.innerHeight;
}
Here is the working codepen
A couple of things:
1) you are not setting a width and height for your canvas, so there is going to be distortion and the x/y values are going to be weird. Solution: set the width and height of the canvas to the window height and width
2) Your method for determining clickX and clickY is overly complicated. Solution: use event.clientX and event.clientY
After getting your context, set the width and height:
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
Note: I would also encourage you to remove the margin on the body in CSS
body { margin: 0 }
Now you can get rid of getCursorPosition (because it is giving you wrong values)
var clickX = e.clientX
var clickY = e.clientY
I need a function for my simple canvas in javascript:
The function determines where the mouse pointer is on the canvas and outputs the coordinates into two variables, pointerX, and pointerY.
The function constantly updates so the variables are always accurate.
Thank you for your time, and if you have any questions for details unmentioned, please reply below and I will respond. Thanks!
Take a look at MouseEvent
and here you go:
var canvas = document.querySelector("canvas");
var h1 = document.querySelector("h1");
canvas.addEventListener("mousemove", function(e){
var x = e.pageX - canvas.offsetLeft;
var y = e.pageY - canvas.offsetTop;
h1.innerText = `x:${x},y:${y}`
})
canvas{
border:solid;
}
<canvas width="100" height="100"></canvas>
<h1></h1>
I have a <canvas> element that spans the width and height of my webpage, like a background. It has interactive elements that rely on mouse coordinates. When the canvas was in it's own block (i.e. nothing over it) the interactive elements worked fine. But now that it's got divs over it it's not picking up any of the mouse interactions.
Below is my javascript code for the mousemove stuff. Why would items on top affect it picking up mouse xy coordinates, and how do I fix it?
var mouse = {x:-100,y:-100};
var mouseOnScreen = false;
canvas.addEventListener('mousemove', MouseMove, false);
canvas.addEventListener('mouseout', MouseOut, false);
var MouseMove = function(e) {
if (e.layerX || e.layerX == 0) {
//Reset particle positions
mouseOnScreen = true;
mouse.x = e.layerX - canvas.offsetLeft;
mouse.y = e.layerY - canvas.offsetTop;
}
}
var MouseOut = function(e) {
mouseOnScreen = false;
mouse.x = -100;
mouse.y = -100;
}
var update = function(){
var i, dx, dy, sqrDist, scale;
//...... this chunk is the only part of the function that references the mouse
dx = parts[i].x - mouse.x;
dy = parts[i].y - mouse.y;
sqrDist = Math.sqrt(dx*dx + dy*dy);
if (sqrDist < 20){
parts[i].r = true;
}
.....
}
If you don't need the top divs to be mouse-aware then set their CSS pointer-events:none; and the mouse events will filter down to your canvas underneath. Questioner needs responsive buttons placed over the canvas.
If the top divs do need to respond to mouse events, you might have to listen for mouse events on the window and convert those to canvas coordinates that your app can respond to.
You can listen for mousemove events on the window and get all moves -- even when over button elements. Also listen for mouseout events on the window. Since the canvas spans the window, you know mouseout happens when mouseevent.clientX & mouseevent.clientY report the coordinates are outside the window
Solved the issue with this code I found from another SO answer that I modified a bit.
function simulate(e) {
var evt = document.createEvent("MouseEvents");
evt.initMouseEvent("mousemove", true, true, window,
0, e.screenX, e.screenY, e.clientX, e.clientY, false, false, false, false, 0, null);
canvas.dispatchEvent(evt);
console.log("Emulated.");
}
$("body > section, body > header").each(function(){
this.addEventListener("mousemove", simulate);
});
Also, as a side note. Changed original layerX and layerY in mouse code to offsetX and offsetY to work in firefox (in addition to all other browsers)
I have a a canvas inside another canvas.
<canvas id ='canvas2' height="718" width="1316"></canvas>
its css is something
#canvas2{
position:absolute;
width :95%;
height:90%;
top:5%;
left:2.5%;
background: #ffff56;
cursor:pointer;
}
next I have drawn some rectangles on it. I need to colour those with mouse click. I used an action listener.
var canvas = document.getElementById("canvas2");
var ctx = canvas.getContext("2d");
canvas.addEventListener("mousedown", doMouseDown, false);
var $canvas = $("#canvas2");
var canvasOffset = $canvas.offset();
var offsetX = canvasOffset.left;
var offsetY = canvasOffset.top;
function doMouseDown(event){
event.preventDefault();
event.stopPropagation();
var x= parseInt(event.clientX - offsetX);
var y = parseInt(event.clientY - offsetY);
}
But this is not the right way I know as I am getting all the wrong canvas co-ordinates on x and y.
Can someone show the right way?
Has your canvas been scrolled?
If yes, then you also need to account for the distance the canvas has been scrolled in the browser.
You might check out canvas.getBoundingClientRect() as a way to get the canvas position with the scrolling accounted for:
function handleMousemove(e){
e.preventDefault();
e.stopPropagation();
// if the canvas is stationary (not scrolling) then you can do
// .getBoundingClientRect once at the start of the app
var BB=canvas.getBoundingClientRect();
// calc mouse position based on the bounding box
var mouseX=parseInt(e.clientX-BB.left);
var mouseY=parseInt(e.clientY-BB.top);
console.log(mouseX+"/"+mouseY);
}