I'm working in a tool to draw in a canvas using the framework Paper.js
I got an issue using iPad. When I'm drawing with one finger, that works. When I'm drawing with two fingers, one in the canvas and one outside the canvas, the second finger event is caught by the event onMouseDrag, and that put some stroke from the first finger to the second finger, not a good behaviour for me.
Example:
At the beginning, I start to draw with one finger. After I put the second finger outside the canvas and I continue to move my first finger. This is what happen.
Do you have any idea to avoid event when I'm outside the canvas?
Thanks.
If you don't want the finger outside to be detected, limit the target to your canvas.
var canvasElement = document.getElementById('canvasId') //or element
tool.onMouseDrag = function(event) {
if (event.event.target === canvasElement) { //my target canvas was nested like this
path.add(event.point);
path.smooth();
}
}
Well, you could test event.point.isInside(view.bounds). This will likely kill your performance if you test it while drawing, but you could cull the points after you're finished.
Related
I have a Konva stage that currently displays a series of shapes. I would like to have a shapes panel, where I can drag shapes and insert into the canvas.
There are currently two ways of doing this:
Adding the Shapes Panel to the Konva stage as it's own layer and entity
Having the Shapes Panel as a standalone HTML element outside the Konva stage and implement a draggable js library to handle dragging behaviour
I'd rather option 2; being able to style the shapes panel with CSS and yield a number of other DOM related benefits is more attractive to me right now.
I have the dragging behaviour sorted, but there is one issue: even though I've implemented stage mouseover events, dragging an element that originates from outside the canvas to on top of the canvas doesn't actually trigger the stage event listeners.
Is there a way around this?
What's interesting is that if you click and hold the mouse outside the element and hover over the canvas, the event listeners fire. But, when you're actually dragging an element (text, image), the event listeners do not fire...
Take a look into this demo: https://konvajs.org/docs/sandbox/Drop_DOM_Element.html
var con = stage.container();
con.addEventListener('dragover', function(e) {
e.preventDefault(); // !important
});
con.addEventListener('drop', function(e) {
e.preventDefault();
// now we need to find pointer position
// we can't use stage.getPointerPosition() here, because that event
// is not registered by Konva.Stage
// we can register it manually (with private method):
stage.setPointersPositions(e);
// now you can add a shape. We will add an image
Konva.Image.fromURL('/assets/yoda.jpg', function(image) {
layer.add(image);
image.position(stage.getPointerPosition());
image.draggable(true);
layer.draw();
});
});
I want to be able to click and drag to draw a rectangle on a javascript canvas.
I need to be able to see the rectangle as I'm dragging to change size as I'm dragging like a "rubber band" as I've heard it been called. And then it creates on mouseup.
I'm having serious difficulties with this, any help is appreciated, thanks!
An algorithm to investigate would be to
Use animation frame callback to clear and write a new rectangle to the canvas. ( See requestAnimationFrame )
Use mousedown and mouseup events over the canvas to initiate tracking mouse movement. The mousedown event could start animation calls to draw a 1x1 pixel rectangle.
mousemove events record the position of the mouse for use by animation frame drawing code - and may call requestAnimationFrame if no callback is pending.
If you can clear the canvas of previous content to create the rubber band effect, the last drawn rectangle on mouseup is the result.
If existing content needs to be preserved, investigate making a copy of the canvas on mousedown, and copying it back to the canvas before drawing new rectangles. See questions like how to copy a canvas locally and/or how to (deep) clone a canvas
Happy coding, there's a lot to learn!
First of all, to draw rect on drag (or mouse move), you just clear the canvas, and draw a new rect. Second of all, canvas shapes are not object, so you can't interact with them as far as I know, if you want interactivity, consider using svg. Here is a sloppy implementation of drawing on dragging.
$("canvas").mousedown(function(event){
var ctx = this.getContext("2d");
ctx.clearRect(0,0,$(this).width(),$(this).height());
var initialX = event.clientX - this.getBoundingClientRect().left;
var initialY = event.clientY - this.getBoundingClientRect().top;
$(this).mousemove(function(evt) {
ctx.strokeRect(initialX, initialY, evt.clientX - event.clientX, evt.clientY - event.clientY);
});
});
I am working on a Transformer Pad and developing a drawing plate.
I use PhoneGap(javascript) to write the code instead of JAVA.
But the touchmove event is quite weird.
I think as I move my finger on the pad, it will continuously to collect the coordinates which I
touch on the canvas. BUT IT DOES NOT!
It's ridiculous, it only collect "1" coordinate: the first point on the canvas my finger moves to.
Here are my code about the "Touch && Move event":
function touchStart(event){
if (event.targetTouches.length == 1) {
var touch = event.targetTouches[0];
if (event.type == "touchstart") {
line_start_x= touch.pageX- canvas_org_x;
line_start_y= touch.pageY- canvas_org_y;
context.beginPath();
context.moveTo(line_start_x, line_start_y);
}//if
}//if 1
}//function.
function Touch_Move(event){
line_end_x= event.touches[0].pageX- canvas_org_x;
line_end_y= event.touches[0].pageY- canvas_org_y;
context.lineTo(line_end_x, line_end_y);
context.stroke();
test++;
}
I don't know why each time I move my finger on the pad, trying to draw a line, curve, or anything
I want. As the finger moves, only a VERY SHORT segment appears. So I declare a variable:"var test=0" in the beginning of this js file. I found that although I move my finger on the pad without leaving it or stopping, the value of "test" remains 1. It means that I move my finger on it. But it doesn't
continuously to trigger the event: "Touch_Move".
What can I do now? I need a corresponding event to "mousemove" on touch pad. At least, the event has to continuously be triggered.
Thank you!
Oh, Jesus. I finally find the answers:
Please take reference for this site.
If you work on an Android System,remember the 'touchmove' only fire ONCE as your finger
moves around the pad. So if you wanna draw a line or something, you have to do this:
function onStart ( touchEvent ) {
if( navigator.userAgent.match(/Android/i) ) { // if you already work on Android system, you can skip this step
touchEvent.preventDefault(); //THIS IS THE KEY. You can read the difficult doc released by W3C to learn more.
}
And if you have more time, you can read the W3C's document about introducing the
'movetouch', it is REALLY hard to understand. The doc sucks.
I'm making a game where the bubbles (circles) appear on the screen and move upwards and I'm using HTML5 and JavaScript only which means no frameworks like kinetic and no jQuery at all.
I've come to a point where I want to add an event listener to the bubble itself, now I understand that because the bubble is an object on the canvas, it has no method 'addEventListener' so I can't directly add a click event to the bubble, I was wondering if anybody could help me with this problem I'm having? Here is a fiddle of what happens so far...
Bubbles
I have tried to add the event listener to the bubble as specified before by doing this...
bubbles[i].addEventListener('click', function);
I have also tried adding mouseevents such as
bubbles[i].onmouseenter = function () { console.log("blah") }
But now, I'm seriously at a loss
Thanks in advance!
I have updated your sample on jsfiddle demonstrating hit-testing. This sample uses an onmousemove event handler bound to the canvas and performs the actual hit-test when this event occurs. The hit-test in your case is "Is the mouse coordinate with in the bubble's circle?"
Summary of changes:
A "bubble" has a color property to demonstrate the effect of a hit test.
function hitTest(x, y) { ... } used to test whether the passed in coordinates are within the bubble.
function getMouse(e, canvas) ... used to transform the mouse coordinates to canvas relative coordinates. i.e, the mouse coordinate needs to be relative to the upper left hand corner of the canvas to be accurate.
I am having trouble finding a good method to limit my mouse to be only able to click on a pre existing line in canvas (stroke width of 3)
What I need to know
how to limit mouse so can only click on pre- existing line, add a dot on click
line is drawn with this function
function createLine(startX:Float, startY:Float, endX:Float, endY:Float)
{
surface.beginPath();
surface.moveTo(startX, startY);
surface.lineTo(endX, endY);
surface.closePath();
surface.strokeStyle = '#ffffff';
surface.lineWidth = 2;
surface.stroke();
}
I am working in haxe, but solution in JS is fine
Thanks in advance.
The only way is for you to keep track of what you have drawn and do the collision/mouse over detection on your own.
If you need your canvas to be highly interactive, you should probably be looking at SVG. http://raphaeljs.com/ is a great library for drawing which will use canvas or SVG, whichever is available.