I have a rectangle that is drawn using canvas. I know its startPosition(x: 731, y: 13) and endPosition(x: 768, y: 113). Can I get this element using JavaScript?
Here I got a JavaScript function document.elementFromPoint(x, y), but it doesn't serve my purpose, because it doesn't accept start and end position.
Can anybody give me idea of how can I retrieve my HTML rectangle element?
You can't "get" elements from a canvas as you can with dom elements, as they aren't actually elements. The canvas just stores the pixel data rather than the individual objects that make up the image (eg lines and rectangles). Source.
If you're set on using the canvas, the typical method is to clear the parts being updated and re-draw anything being changed. You might store the canvas "elements" as a series of points which you reference when you redraw
Can anybody give me idea of how can I retrieve my HTML rectangle element?
You can't, because it's not an element in the first place. Drawing in the canvas doesn't create any elements, it just changes the pixels in the canvas buffer.
If you want to draw shapes using JavaScript that you can later modify, I would suggest using the DOM with SVG.
Related
I'm randomly drawing little stars on a canvas with the beginPath() method like this:
function makeStars(){
for(let i=0; i<100; i++){
let startingX = Math.floor(Math.random()*canvasWidth);
let startingY = Math.floor(Math.random()*canvasHeight);
ctx.beginPath();
ctx.moveTo(startingX, startingY);
ctx.lineTo(startingX-3,startingY+9.4);
ctx.lineTo(startingX+4.5, startingY+3.5);
ctx.lineTo(startingX-4.5, startingY+3.4);
ctx.lineTo(startingX+3, startingY+9.4);
ctx.closePath();
ctx.fill();
}
Is it possible to give each path a class? Something like ctx.classList.add('star');? Ultimately, I was hoping to be able to animate them with CSS.
Thanks!
Edit
Looks like CSS is not the way to go. I think I'll just try to animate my stars with javaScript in a setInterval loop. Here's a codepen of what I'm working with. Twinkling Stars Canvas
No, CSS cannot animate or interact with canvas drawing.
But You can create a Star class which will provide OOP way of updating, rendering and animating the stars.
and then push all of the stars in an array and update/render them on animate loop.
https://codepen.io/anuraghazra/pen/WLLQJv
The short answer is: No. CSS doesn't act on elements drawn on a canvas.
Drawing to a canvas is like drawing directly to paper. You're using the 2D context to act on the pen. While you could figure out a way to read the CSS and perform the animations (by redrawing and redrawing the canvas), I would think that would be way more difficult than any other alternative.
If you're set on using CSS, one alternative is to use SVG+CSS. The elements within the SVG can react to your CSS, much like HTML elements.
If you absolutely have to use a canvas, you could also draw the SVG to your canvas. Convert the SVG to a Data URI, then load that URI into an Image object, which you can then putImage onto the canvas. You would have to figure out how to draw each time the SVG updates, or poll for the new SVG information at an interval (like requestAnimationFrame).
I have a polygon object (say a car) drawn inside a HTML5 canvas with help of methods moveTo and lineTo. I want to repeatedly draw that object at different positions in the canvas (simulating a moving object). My problem is that the previous drawn object is not getting cleared. Instead, multiple images are drawn on the canvas. How can I fix this issue?
You have to clear the canvas at the start of every draw frame
context.clearRect(0, 0, canvas.width, canvas.height);
Canvases are just arrays of pixels, they know nothing of the shapes you have drawn.
There are animation tricks that used to be used on bitmapped displays (e.g. "xor drawing") that can be used to remove the old shape before you draw the new one, but on modern machines it's generally far simpler (and perfectly fast) to just erase the canvas and start again for each frame.
Given your comments to other answers, I'd suggest just using two Canvases - one for the static background and one for the car. If the background image is static it could even be an <img> element instead of a Canvas.
If the car image is static you could also just draw that once, and then use CSS positioning to set its position relative to the background for each frame.
suppose your shape is car then you first have to assign a new graphic like:
car.graphics = new createjs.Graphics();
car.graphics
.setStrokeStyle(1)
.beginStroke("#000000")
.moveTo()
.lineTo()
.lineTo()
I am looking for a way to capture the complete canvas (including elements that are moved outside the canvas) to an image. I am using the KineticJS library and I am aware of the toDataURL function. The problem is that the image is clipped to the canvas bounds.
As a workaround I thought to copy all elements on the canvas to a temporary hidden canvas which is big enough to fit all elements and then use the toDataURL function. I was wondering if there is a cleaner approach?
Interesting problem. I like the temporary canvas idea. Also, you could just resize the main canvas, apply an offsetting translation to all child elements, capture the image, then reverse-translate and resize back. This wouldn't be any more complex than copying to a hidden canvas. Plus, the single canvas approach would be more memory efficient.
Just my 3 cents.
I would agree with Alvin, you could just resize the canvas, here's how:
stage.setWidth(window.innerWidth); // inner width of your window
stage.setHeight(window.innerHeight); // inner height of your window
stage.draw(); //redraw
This would resize your stage to the width and height of your window, but this would not account for the possibility that elements would be farther than your window, but you can just modify the number inside the .set functions to account for the farthest right/left one.
If you were looking for a quick way to copy all elements in your canvas to another stage you could serialize it:
var json = stage.toJSON();
var newStage = Kinetic.Node.create(stageJson, 'newContainer');
I have created Raphael content here .. http://jsfiddle.net/ryWH3/76/
Now I need to move the whole content of Raphael Canvas from one
co-ordinate to another co-ordinate.
For Example:
My Raphael Canvas is at -- x_coordinate:100,y_coordinate:100
Now I want to move it to -- x: 200, y :200
From the old co-ordinates I want to move that whole content to -- x:150, y:150
again to some other co-ordinates from the last co-ordinates
Please suggest me in moving this content
Ok I don't think you can actually more the paper itself, which is what is returned by Raphael to your r variable. You can iterate over the elements and do whatever you like to them:
r.forEach(function (el) {
el.translate(200,200);
});
I updated your fiddle to demonstrate it moving:
updated fiddle
EDIT
I have also added the following to demonstrate animating your various sets:
Text.animate({transform: "t100,100"}, 1000);
smallCircles.animate({transform: "t100,100"}, 1000);
bigCircles.animate({transform: "t100,100"}, 1000);
updated fiddle with above animation
using jquery for example...
$(paper.canvas).css({top:topPosition, left: leftPosition});
The paper.canvas is how you get a hold of the dom element its within.
I'm writing drag & drop functionality in my HTML5 Canvas application and am wondering how to detect if I'm clicking on a shape other than a rectangle or square, in which case I would do something like this inside of my 'mousedown' event handler:
if (evt._x > 13 && evt._x < 202 .... ) {}
I don't see how to easily do something like that with an arc like this:
ctx.arc(25, 25, 20, 0, (Math.PI/180)*360);
I hope that is clear, thank you in advance.
Just use isPointInPath, which checks if a given point is within the current drawing path. If you're drawing multiple shapes to the canvas, than a good technique is to associate each of your shapes with a "hidden" canvas, draw each path to its respective canvas, than test isPointInPath against each of these, offsetting the destination/mouse coordinates as needed. Theres no reason to resort to your own calculations for this.
First you check if the click is within a shape's bounding box (the smallest rectangle which fully encloses the shape). If it is, then you do the more complex math to determine if the click is within the shape itself. You'll have to implement this math yourself as I don't think there's anything built-in for it.
You'll get the formula you need here and also in Polygon article of Wikipedia.
This may sound stupid, but you can use <area> tags inside a <map> over an <img> to create interactive polygonal shapes. They have their own onclicks/mouseovers/etc. already implemented by all browsers.