Hi i have a ball dropping in a html5 canvas, i would like to have a counter that displays how far the ball is dropping.
var ball = new Kinetic.Shape(function(){
var context = this.getContext();
context.beginPath();
context.arc(0, 0, radius, 0, 2 * Math.PI, false);
context.fillStyle = "black";
context.fill();
});
Someone any idea how to do this ?
Your shape has a position on the canvas, you should clearly define it just to be sure.
But if you want to count how your object moves on the screen you can just do:
ball.getPosition();
This will return you a point in the form of
{x: number, y: number}
you can save the individual x,y values like so:
var xPosition = ball.getPosition().x;
var yPosition = ball.getPosition().y;
you can save those positions in your animation and do a sum of how much the ball moved.
Related
I have been given the following task, but I am getting errors that can be seen when the code snippet is run. I would like some help figuring out what exactly I am doing wrong.
Basically, I need to draw a circle, make it so that it moves and changes the direction/color when touching the walls of the screen.
Task: create a Circle class with the following properties:
x - the initial value of the coordinate x
y is the initial value of the y coordinate
radius - values of width and height
color - fill color Describe the methods:
draw () - marks off on the screen an element that is described by the given properties
setColor (newColor) - Changes the fill color to newColor
move ({x = 0, y = 0}) - moves the captured object by the vector (x, y) - each time period (for example, 100 ms) changes (adds \ subtracts)
to the values x and y, respectively. When a circle collides with any
edge of the screen it is necessary to realize its mirror reflection
(change the value of the corresponding coordinate of the vector on the
opposite of the value of the sign, and call this method with the new
vector) and generate the collision event, collision, which is captured
at the document level.Hang on this event a handler that will change
the color of the pouring of the circle into another (random) value.
Movement occurs until the stop method is called.
stop () - stops the circle movement
If the Escape button on the keyboard was pressed, the movement should stop.
I created a canvas and set the frame to move. I drew a circle and tried to move it using setInterval(), but it seems like I'm losing the context.
let c = document.getElementById("mycanvas");
let ctx = c.getContext("2d");
let xinc = 1;
let yinc = 1;
class Circle {
constructor(xpos, ypos, radius, color) {
this.xpos = xpos;
this.ypos = ypos;
this.radius = radius;
this.color = color;
}
draw() {
ctx.beginPath();
ctx.arc(this.xpos, this.ypos, this.radius, 0, Math.PI * 2);
ctx.fillStyle = "red";
ctx.fill();
}
move(xpos, ypos) {
ctx.clearRect(0, 0, c.width, c.height);
ctx.beginPath();
this.draw();
xpos += xinc;
ypos += yinc;
console.log(xpos, ypos);
if ((this.xpos > c.width - this.radius) || (this.xpos < 0 + this.radius)) {
xinc = -xinc;
}
if ((this.ypos > c.height - this.radius) || (this.ypos < 0 + this.radius)) {
yinc = -yinc;
}
setInterval(this.move, 10);
//this.draw();
}
}
let circle = new Circle(200, 300, 50, "red");
circle.draw();
circle.move(200, 300);
<canvas id="mycanvas" width="1335" height="650" style="border: 1px solid"> </canvas>
I am just starting to learn events and DOMs, please help me correctly implement this task
You are passing this.move to setInterval with no context - just a function, with no this to call it in. You can pass in this.move.bind(this) to create a bound function. You can also do it once in the constructor: this.move = this.move.bind(this).
Also, the call to beginPath in move seems unnecessary.
I've created a grid of several distorted rectangles made with Bezier curves. Each rectangle has its own color on the picture.
Let's say, I want to add hover effect for each of these rectangles, therefore I need to know its dimensions. Since I can fill or stroke the figure I assume that there is some way to get them, but I'm not sure.
Here is the example of the rectangles:
So the question is, is there some method in the canvas API with which I can achieve the desired effect?
Yes you can use isPointInPath(Path2D, x, y) method.
Note that if you don't use the Path2D object, you can also call it just with isPointInPath(x, y), but then it will check on the currently being drawn path (declared with beginPath()).
var ctx = canvas.getContext('2d');
var myPath = new Path2D();
myPath.bezierCurveTo(50, 100, 180, 10, 20, 10);
myPath.lineTo(50, 100);
function draw(hover) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = hover ? 'red' : 'green';
ctx.fill(myPath);
}
canvas.onmousemove = function(e) {
var x = e.clientX - canvas.offsetLeft,
y = e.clientY - canvas.offsetTop;
var hover = ctx.isPointInPath(myPath, x, y)
draw(hover)
};
draw();
<canvas id="canvas"></canvas>
I am drawing circles on an html5 canvas (this.ctx) with the drawCircle function. Now I would like to move the cirlce to a different position with a move Circle function. Is there any way to see the circle move from one place to the other? At this point I am not even sure how to remove the previous circle for a user. Could I assign the arc to an object or so?
customobject.prototype.drawCircle = function drawCircle(userID, x, y) {
var radius = 10;
this.ctx.beginPath();
this.ctx.arc(100, 00, 10, 0, Math.PI*2, true);
this.ctx.closePath();
this.ctx.fillStyle = 'blue';
this.ctx.fill();
this.ctx.lineWidth = 2;
this.ctx.strokeStyle = '#003300';
this.ctx.stroke();
}
customobject.prototype.moveCircle = function moveCircle(userID, x, y) {
}
I did see a way to potentially delete a circle (not animate - move it):
remove circle(x, y, radius){
this.ctx.globalCompositeOperation = 'destination-out'
this.ctx.arc(x, y, radius, 0, Math.PI*2, true);
this.ctx.fill();
}
-> so in this case I would specify the coordinates of the original circle and it would be cut?
I also saw this post on making a circle move. But I don't know how to do that with multiple circles. (Each userID would have a circle)
Removing a Circle from the canvas once it is drawn is not possible a priori, you could draw another circle in the place but with the background color set, but that will fast conflict with other drawn objects.
If I am getting this right, you would like to animate the movement of the circle. That is basically done like that:
var start = new Date().getTime(),
end = start + 1000; //one second of animation
p1 = { x: 0, y: 0 }, //start coordinates
p2 = { x: 100, y: 10 }; // end coordinates
function render (progress) {
var x = p1.x + progress * (p2.x - p1.x),
y = p1.y + progress * (p2.y - p1.y);
clearCanvas();
drawCircle(x,y);
}
function loop () {
var now = new Date().getTime(),
progress = (now - start)/(end - start);
if (progress >= 0 && progress <= 1) {
render(progress);
window.requestAnimationFrame(loop);
}
}
loop();
The basics:
you need an animation loop, no for or while loop, something that uses a timer, setTimeout() or setInterval() would do, but requestAnimationFrame() is made for such things.
Find the progress, in animation this is usually a Number between 0 and 1, where 0 refers to the start, 1 to the end and everything in between the progress.
clear the canvas and re-render everything, depending on the progress.
repeat until the progress is bigger than one.
I've been working on a game that's sort of a Worms clone. In it, the player rotates a cannon with the up up and down keys (it's a 2D game) to fire at enemies coming from above. I use the context.rotate() and context.translate() methods when drawing the cannon, then immediately context.restore() back to the default canvas.The cannon is the only thing (for now) that's rotated.
The problem is, I want to accurately show projectiles coming from the top of the cannon. For this, I need to know the top of the cannon's coordinates at all times. Normally, this is something I could easily calculate. However, because the canvas is rotated only before the cannon is drawn, it's not as simple.
Just use simple trigonometry to track the top:
var canonTopX = pivotX + Math.cos(angleInRadians) * canonLength;
var canonTopY = pivotY + Math.sin(angleInRadians) * canonLength;
You can choose to render the canon using transformations of course, or share the math.
ctx.translate(pivotX, pivotY);
ctx.rotate(angleInRadians);
//render canon from (0,0) pointing right (0°)
ctx.setTransform(1,0,0,1,0,0); // instead of save/restore
// calc canon top for projectiles here
var ctx = c.getContext("2d");
var canonLength = 70;
var angleInRadians = 0;
var angleStep = 0.03;
var pivotX = ctx.canvas.width>>1;
var pivotY = ctx.canvas.height>>1;
ctx.fillStyle = "#000";
ctx.strokeStyle = "#c00";
(function loop() {
angleInRadians += angleStep;
render();
requestAnimationFrame(loop);
})();
function render() {
ctx.clearRect(0,0,ctx.canvas.width,ctx.canvas.height);
ctx.translate(pivotX, pivotY);
ctx.rotate(angleInRadians);
ctx.fillRect(0, -5, canonLength, 10);
ctx.setTransform(1,0,0,1,0,0); // instead of save/restore
var canonTopX = pivotX + Math.cos(angleInRadians) * canonLength;
var canonTopY = pivotY + Math.sin(angleInRadians) * canonLength;
ctx.beginPath();
ctx.arc(canonTopX, canonTopY, 9, 0, 6.3);
ctx.stroke();
}
<canvas id=c width=600 height=180></canvas>
I am working on a HTML5 Project.There is a drawing graphics API to draw Rectangle (fillRectStrokeRect).But how can i draw a SQUARE. I have tried the following way to draw it
CODE
getMouse(e);
x2=mx; y2=my;
var width=endX-startX;
var height=endY-startY;
annCanvasContext.beginPath();
annCanvasContext.lineWidth=borderWidth;
var centerX=width/2;
var centerY=width/2;
var radius=width/2;
annCanvasContext.arc(centerX+5, centerY+5, radius, 0, 2 * Math.PI, false);
annCanvasContext.stroke();
Use fillRect or strokeRect with the width and height being equal.
var x = 0, y = 0,
side = 10;
ctx.fillRect(x, y, side, side);
Demo
As you say in the comments, if you want to fit the largest square in a circle, it's more Math related than about code. I'll trying explaining it to you, but you'll probably find better, more visual explanations elsewhere on the Internet.
Draw the diameter of the circle in a way that it divides your square into two equal parts. Now one part is a right angled triangle, which has two of its sides equal. We know the diameter. Using the Pythogorean theorem, you get this equation:
side^2 + side^2 = diameter^2.
Let's find the side now.
2(side^2) = diameter^2
side^2 = (diameter^2)/2
side = Math.sqrt( (diameter^2)/2 )
Now, to turn this into code.
var ctx = document.getElementById('canvas').getContext('2d'),
radius = 20;
ctx.canvas.addEventListener('click', function (e){
ctx.fillStyle = 'black';
ctx.arc(e.pageX, e.pageY, radius, 0, Math.PI*2, false);
ctx.fill();
ctx.beginPath();
ctx.fillStyle = 'red';
var diameter = radius * 2;
var side = Math.sqrt( (diameter * diameter)/2 );
ctx.fillRect(e.pageX - side/2, e.pageY - side/2, side, side);
ctx.closePath();
}, false);
This would draw a square inside a circle wherever you click on the canvas.
Demo