so I am trying to make thisgame called GO and I need to place circles in the edges like this. I've made the grid and now need to place the circles in there. I 'v tried different things like using the arc in canvas with mouse position and placing it but it isn't working something else I tried is to make an array that checks where the lines cross but it still didn't do anything. but i may have done it wrong. I'm not sure what's wrong so hope you guys could help me find a way to place the circles on the board every time I click the mouse. I've deleted the things that didn't work and this is my code now:
const canvas = document.getElementById("myCanvas")
const ctx = canvas.getContext("2d")
//canvas.style.border = "1px solid black"
let w = ctx.canvas.width
let h = ctx.canvas.height
goBoard = []
goCheckBoard = []
function drawGrid(w, h) {
for (x = 0; x <= w; x += 40) {
for (y = 0; y <= h; y += 40) {
ctx.moveTo(x, 0);
ctx.lineTo(x, h);
ctx.stroke();
ctx.moveTo(0, y);
ctx.lineTo(w, y);
ctx.stroke();
}
}
}
drawGrid(400, 400)
this just makes the grid
one example i've tried is this:
mouseClicked = function () {
ctx.beginPath()
ctx.strokeStyle = "black"
ctx.ellipse(mouseX, mouseY, 20, 20);
ctx.stroke()
};
another:
function rtn(n, r){
return Math.round(n/r)*r;
}
canvas.onclick = function(event){
ellipse(rtn(event.clientX, 40), rtn(event.clientY, 40), 180, 180);
};
im not sure if that is the correct way to do it
maybe make an array of all the possible places to place the circle but im not sure how
here is a fiddle if you want to test it out https://jsfiddle.net/pwe0vx7o/
you first need to change the ellipse(...) to ctx.ellipse(...), because ellipse isn't a global function, but a metod of the CanvasRenderingContext2D.
Through the docs I also found that this function takes 7 arguments so added ones for radiusX, radiusY, rotation, startAngle, endAngle.
Here is also a fiddle for the finished result: https://jsfiddle.net/c6udn9gf/8/
This will get you close, but you need to figure out something with your rounding function.
canvas.onclick = function (event) {
ctx.beginPath();
const x = rtn(event.clientX, 40);
const y = rtn(event.clientY, 40);
ctx.ellipse(x - 20, y - 20, 10, 10, 0, 0, 360);
ctx.fill();
};
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>
For a javascript animation, I am trying to create buttons with the numbers 1-9 on them. Right now my javascript for the number 1 looks like:
that1 = { thisx : 120, thisy: H-400, thisnumber= "1",
draw: function() {
var keywidth = 100;
var keyheight = 150 ;
var x = this.thisx;
var y = this.thisy;
var cornercut = 5;
ctx.beginPath();
//drawing the key
ctx.moveTo(x, y+cornercut);
ctx.quadraticCurveTo(x,y, x+cornercut, y);
ctx.lineTo(x+keywidth-cornercut, y);
ctx.quadraticCurveTo(x+keywidth, y, x+keywidth, y+cornercut);
ctx.lineTo(x+keywidth, y+keyheight-cornercut);
ctx.quadraticCurveTo(x+keywidth, y+keyheight, x+keywidth-cornercut, y+keyheight);
ctx.lineTo(x+cornercut, y+keyheight);
ctx.quadraticCurveTo(x, y+keyheight, x, y+keyheight-cornercut);
ctx.lineTo(x, y+cornercut);
ctx.closePath();
ctx.stroke();
ctx.fillText(this.thisnumber, x+.5*keywidth,y+.8*keyheight);
},
highlight: function() {
ctx.fillStyle="red";
ctx.fill();
}
} ;
I could just copy this to create this2, this3, this4, this5, etc., but I feel like there is an easier way. Can anyone help? I am using JS because I believe it will be the easiest way to control these objects using animation, but please let me know if you have another suggestion.
You could change the values of thisx and thisy and simply call the draw function again, but the code would probably be more elegant if you simply passed in the values as arguments to a draw function.
I am attempting to make a pong clone using canvas. I however seem to have a misunderstanding how the coordinate system works in canvas in regards to events.
I have created a playerPaddle class. With this class I want the center of the paddle to be drawn exactly where the mouse is hovering:
// Paddle Object
function Paddle( h, w, x, y, fill) {
this.h = h;
this.w = w;
this.midH = h / 2;
this.x = x;
this.y = y;
this.fill = fill;
}
Paddle.prototype.draw = function(ctx) {
ctx.fillStyle = this.fill;
ctx.fillRect(this.x, this.y, this.w, this.h);
}
Paddle.prototype.updatePos = function(y) {
this.y = y - this.midH
}
I thought the correct way to offset the paddle so that the center of the paddle is on the mousemove event would be to draw the rectangle by subtracting half the paddle height from the new position of the paddle like I am doing in the updatePos method above.
However this seems to not be working correctly as it is drawing the top of my paddle exactly where the mousemove event is occurring.
What does work though is if I subtract this.h from the y location of the event, which makes absolutely no sense to me.
Below is the code I use to instantiate the paddle, add the event handler to the canvas element itself, and the function I use to render everything.
// Paddle Globals
var paddleHeight = 50,
paddleWidth = 10,
paddleOffset = 10;
var playerPaddle = new Paddle( paddleHeight, paddleWidth, paddleOffset, midY, '#FFFFFF');
// Does the actual rendering
function render() {
ctx.clearRect(0, 0, cWidth, cHeight);
playerPaddle.draw(ctx);
}
//Event Handlers
canvas.addEventListener('mousemove', function(e) {
e.preventDefault();
var position = canvas.getBoundingClientRect();
var y = e.clientY - position.top;
playerPaddle.updatePos(y);
}, false);
Also here is an example of the behavior that I am describing: http://jsfiddle.net/u57QD/
I think I solve the problem.
Try to delete the css style on Canvas.
I think the padding-top is making you canvas downward. So it look like the y - this.midH is not working :D Good luck
Delete follow line of code in stylesheet
padding-top: 20px;
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