Aligning text inside rectangle of html5 canvas - javascript

I have resizable rectangle, and I wish to have right-aligned text (day numbers) next to it.
what I have now:
(also when resizing the text does not really align vertically)
what I wish to have:
Is there a way to fill the text and align it inside a drawn rectangle? Other suggestions are welcome too.
js.do code
function dayRect(day) {
const days = ["I","II","III","IV","V","VI","VII"];
context.beginPath();
//maybe align the text inside this rect somehow
context.rect(0, day*h/7, 3*w/27, h/7);
context.stroke();
context.font = "0.5rem Arial";
context.fillStyle = "#fff";
context.fillText(days[day], 0, (day+1)*h/7);
}

I've changed a few things in your code since I wasn't able to see anything. You need to use context.textAlign="right" for your text and move it to a different position. I hope it helps.
function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect();
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}
var canvas = document.getElementById("posHourCanvas");
var context = canvas.getContext('2d');
canvas.width=600,canvas.height=300;
var boxes = [];
function init() {
context.clearRect(0, 0, canvas.width, canvas.height);
boxes.length = 0;
const strokeWidth = 0.6;
//canvas.width = $('#two')[0].clientWidth;
var cellSize = canvas.width/27;
canvas.height = 7/27 * canvas.width;
var x = y = 0;
draw(x,y,canvas.width,canvas.height,cellSize,strokeWidth);
}
function Box(x, y, day, hour) {
this.x = x;
this.y = y;
this.day = day;
this.hour = hour;
}
function draw(x, y, w, h, cellSize, strokeWidth) {
let onePixel = cellSize * strokeWidth;
cellSize = cellSize * (1 - strokeWidth);
context.beginPath();
context.lineWidth = 1;
context.strokeStyle = 'rgba(0, 0, 0, 1)';
const rectCoordinates = {
x: x+3*w/27,
y: y,
w: w-3*w/27,
h: h
}
context.rect(rectCoordinates.x, y, rectCoordinates.w, h);
context.fillStyle = 'white';
context.fill();
context.stroke();
let offX = rectCoordinates.w/24 + rectCoordinates.x;
let offY = h/7;
for (let i = 0; i < 7; i++) {
dayRect(i);
context.beginPath();
context.moveTo(0, offY);
context.lineTo(w, offY);
context.strokeStyle = "black";
context.stroke();
offY+=h/7;
}
for (let i = 0; i < 24; i++) {
context.beginPath();
context.moveTo(offX, 0);
context.lineTo(offX, h);
context.stroke();
offX+=rectCoordinates.w/24;
}
function dayRect(day) {
const days = ["I","II","III","IV","V","VI","VII"];
context.beginPath();
context.rect(0, day*h/7, 3*w/27, h/7);
context.stroke();
context.font = "0.5rem Arial";
context.fillStyle = "#fff";
context.textAlign="right";
context.fillText(days[day], 60, (day+1)*h/7);
}
}
init();
body {
margin: auto;
color: white;
background-color: black;
min-height: 100vh;
}
<div id="parent">
<div>text above</div>
<div id="two">
<canvas id="posHourCanvas" width="600" height="300"></canvas>
</div>
<div>text under</div>
</div>

Related

Change color inside circle

I want to change color inside circle example:(two color) from red to blue and blue to red.
I tried this using if else but it didn't work for me.
let canvas = document.getElementById("canvas");
let context = canvas.getContext("2d");
// for canvas size
var window_width = window.innerWidth;
var window_height = window.innerHeight;
canvas.width = window_width;
canvas.height = window_height;
let hit_counter = 0;
// object is created using class
class Circle {
constructor(xpos, ypos, radius, speed, color, text) {
this.position_x = xpos;
this.position_y = ypos;
this.radius = radius;
this.speed = speed;
this.dx = 1 * this.speed;
this.dy = 1 * this.speed;
this.text = text;
this.color = color;
}
// creating circle
draw(context) {
context.beginPath();
context.strokeStyle = this.color;
context.fillText(this.text, this.position_x, this.position_y);
context.textAlign = "center";
context.textBaseline = "middle"
context.font = "20px Arial";
context.lineWidth = 5;
context.arc(this.position_x, this.position_y, this.radius, 0, Math.PI * 2);
context.stroke();
context.closePath();
}
update() {
this.text = hit_counter;
context.clearRect(0, 0, window_width, window_height)
this.draw(context);
if ((this.position_x + this.radius) > window_width) {
this.dx = -this.dx;
hit_counter++;
}
if ((this.position_x - this.radius) < 0) {
this.dx = -this.dx;
hit_counter++;
}
if ((this.position_y - this.radius) < 0) {
this.dy = -this.dy;
hit_counter++;
}
if ((this.position_y + this.radius) > window_height) {
this.dy = -this.dy;
hit_counter++;
}
this.position_x += this.dx;
this.position_y += this.dy;
}
}
let my_circle = new Circle(100, 100, 50, 3, 'Black', hit_counter);
let updateCircle = function() {
requestAnimationFrame(updateCircle);
my_circle.update();
}
updateCircle();
//for color
function changeColor(event) {
var coloorr = event.value;
canvas.style.background = coloorr;
}
// I tried it in bllk function but it didn't work for me.
function bllk() {
canvas.style.background = "black";
context.fillStyle = "blue";
// I tried it in bllk function but it didn't work for me.
// setInterval(() => {
// if(context.fillStyle=="blue"){
// context.fillStyle=red;
// context.fill();
// }else if(context.fillStyle=="red"){
// context.fillStyle=blue;
// context.fill();
// }else if(context.fillStyle=="blue"){
// context.fillStyle=red;
// context.fill();
// }
// }, 1000);
}
<!-- On clicking button Hi How to apply two color one by one to the numbers inside the circle ? I tried it in bllk function but it didn't work for me. -->
<button onclick="bllk()">Hi</button>
<canvas id="canvas"></canvas>
The code needed a little upgrade:
decoupling variables from each other & the global space
adding some internal attributes & methods to the circle
Now it's possible to change the background color of the canvas, the outline and text of the circle, and the background of the circle separataley.
const canvas = document.getElementById("canvas");
const context = canvas.getContext("2d");
// for canvas size
const window_width = window.innerWidth;
const window_height = window.innerHeight;
canvas.width = window_width;
canvas.height = window_height;
// object is created using class
class Circle {
constructor(xpos, ypos, radius, speed, color, text) {
this.position_x = xpos;
this.position_y = ypos;
this.radius = radius;
this.speed = speed;
this.dx = 1 * this.speed;
this.dy = 1 * this.speed;
this.text = text;
this.color = color;
this.fillColor = "white" // added as a default value
this.hit_counter = 0
}
// outline & text in circle
drawOutline({
ctx
}) {
ctx.beginPath();
ctx.strokeStyle = this.color;
ctx.fillStyle = this.color
ctx.fillText(this.text, this.position_x, this.position_y);
ctx.textAlign = "center";
ctx.textBaseline = "middle"
ctx.font = "20px Arial";
ctx.lineWidth = 5;
ctx.arc(this.position_x, this.position_y, this.radius, 0, Math.PI * 2);
ctx.stroke();
ctx.closePath();
}
// background of the circle
drawFill({
ctx,
color
}) {
ctx.beginPath();
ctx.fillStyle = this.fillColor
ctx.arc(this.position_x, this.position_y, this.radius, 0, Math.PI * 2);
ctx.fill();
ctx.closePath();
}
// drawing the circle from two pieces
draw(ctx) {
this.drawFill({
ctx
})
this.drawOutline({
ctx
})
}
// color change function
setColor({
outline,
fill
}) {
this.color = outline
this.fillColor = fill
}
update(ctx) {
this.text = this.hit_counter;
ctx.clearRect(0, 0, window_width, window_height)
this.draw(context);
if ((this.position_x + this.radius) > window_width) {
this.dx = -this.dx;
this.hit_counter++;
}
if ((this.position_x - this.radius) < 0) {
this.dx = -this.dx;
this.hit_counter++;
}
if ((this.position_y - this.radius) < 0) {
this.dy = -this.dy;
this.hit_counter++;
}
if ((this.position_y + this.radius) > window_height) {
this.dy = -this.dy;
this.hit_counter++;
}
this.position_x += this.dx;
this.position_y += this.dy;
}
}
const my_circle = new Circle(100, 100, 50, 3, 'Black');
const updateCircle = function(ctx) {
requestAnimationFrame(() => updateCircle(ctx));
my_circle.update(ctx);
}
updateCircle(context);
// I tried it in bllk function but it didn't work for me.
function bllk1() {
canvas.style.background = "black";
my_circle.setColor({
outline: "red",
fill: "yellow"
})
}
function bllk() {
canvas.style.background = "black";
my_circle.setColor({
outline: "black",
fill: "blue"
})
setInterval(() => {
const fill = my_circle.fillColor === "blue" ? "red" : "blue"
my_circle.setColor({
outline: "black",
fill,
})
}, 1000);
}
<!-- On clicking button Hi How to apply two color one by one to the numbers inside the circle ? I tried it in bllk function but it didn't work for me. -->
<button onclick="bllk()">Hi</button>
<canvas id="canvas"></canvas>
I simplified your code to just focus on what you asked on the comments:
changing red to blue and blue to red color continuously
To focus on that specific problem we don't need the Circle moving or the collisions with the borders, in the future when you are asking a question you should do the same, provide a minimal example, remove everything else that is not specifically related to your problem.
To solve your issue we can pass a colors parameter to the draw function, that way we let it know what colors to use for the circle and the text, or anything you might want to add in the future.
See code sample below:
let canvas = document.getElementById("canvas");
let context = canvas.getContext("2d");
canvas.width = canvas.height = 100;
class Circle {
draw(xpos, ypos, radius, colors) {
context.beginPath();
context.arc(xpos, ypos, radius, 0, Math.PI * 2);
context.fillStyle = colors.circle;
context.fill();
context.beginPath();
context.font = "20px Arial";
context.fillStyle = colors.text;
context.fillText("0", xpos, ypos);
}
}
let my_circle = new Circle();
let colors = {text:"red", circle:"blue"};
let updateCircle = function() {
requestAnimationFrame(updateCircle);
context.clearRect(0, 0, canvas.width, canvas.height)
my_circle.draw(50, 50, 20, colors);
}
updateCircle();
setInterval(() => {
if (colors.text == "blue") {
colors = {text:"red", circle:"blue"};
} else {
colors = {text:"blue", circle:"red"};
}
}, 1000);
<canvas id="canvas"></canvas>

How to use: globalCompositeOperation on multiple objects in JavaScript Canvas

I'm attempting to create a circle menu in JavaScript canvas, something that would look similar to this:
Here is the code I'm using:
let canvas = document.querySelector("#canvas");
canvas.width = 500;
canvas.height = 500;
let ctx = canvas.getContext("2d");
ctx.fillStyle = "rgba(0,0,0,.45)"; // color
let circlePath = [];
let centerCircle = new Path2D();
for (let t = 0; t < 8; t++) {
circlePath[t] = new Path2D();
circlePath[t].moveTo(250, 250);
circlePath[t].arc(
250,
250,
190,
Math.PI * 2 * 0.125 * t,
Math.PI * 2 * 0.125 * t + Math.PI * 2 * 0.1175
);
circlePath[t].closePath();
ctx.fill(circlePath[t]);
}
ctx.fillStyle = "#fff";
centerCircle.moveTo(250, 250);
centerCircle.arc(250,250,100,0,2*Math.PI);
ctx.fill(centerCircle);
canvas.addEventListener("mousemove", function (event) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
for (let t = 0; t < 8; t++) {
if (ctx.isPointInPath(circlePath[t], event.offsetX, event.offsetY)) {
ctx.fillStyle = "blue";
} else {
ctx.fillStyle = "rgba(0,0,0,.45)";
}
ctx.fill(circlePath[t]);
}
ctx.fillStyle = "#fff";
centerCircle.moveTo(250, 250);
centerCircle.arc(250,250,100,0,2*Math.PI);
//ctx.globalCompositeOperation = "destination-out";
ctx.fill(centerCircle);
});
#canvas {
border: 1px solid #000;
background: green;
};
<canvas id="canvas"></canvas>
The problem I am having is that when I try to use ctx.globalCompositeOperation = "destination-out"; to "punch out" a hole in the midle of the arcs using the white circle, it makes all of the objects disappear.
Thank you in advance for any input provided.
Figured it out! Had to place ctx.globalCompositeOperation = "destination-out"; in the right places, followed by: ctx.globalCompositeOperation = "source-over";
Here is the updated code:
let canvas = document.querySelector("#canvas");
canvas.width = 500;
canvas.height = 500;
let ctx = canvas.getContext("2d");
ctx.fillStyle = "rgba(0,0,0,.45)"; // color
let circlePath = [];
let centerCircle = new Path2D();
for (let t = 0; t < 8; t++) {
circlePath[t] = new Path2D();
circlePath[t].moveTo(250, 250);
circlePath[t].arc(
250,
250,
190,
Math.PI * 2 * 0.125 * t,
Math.PI * 2 * 0.125 * t + Math.PI * 2 * 0.1175
);
circlePath[t].closePath();
ctx.fill(circlePath[t]);
}
ctx.fillStyle = "#fff";
centerCircle.moveTo(250, 250);
centerCircle.arc(250,250,100,0,2*Math.PI);
ctx.globalCompositeOperation = "destination-out";
ctx.fill(centerCircle);
ctx.globalCompositeOperation = "source-over";
canvas.addEventListener("mousemove", function (event) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
for (let t = 0; t < 8; t++) {
if (ctx.isPointInPath(circlePath[t], event.offsetX, event.offsetY)) {
ctx.fillStyle = "blue";
} else {
ctx.fillStyle = "rgba(0,0,0,.45)";
}
ctx.fill(circlePath[t]);
}
ctx.fillStyle = "#fff";
centerCircle.moveTo(250, 250);
centerCircle.arc(250,250,100,0,2*Math.PI);
ctx.globalCompositeOperation = "destination-out";
ctx.fill(centerCircle);
ctx.globalCompositeOperation = "source-over";
});
#canvas {
border: 1px solid #000;
background: green;
};
<canvas id="canvas"></canvas>

In JavaScript Canvas, How do I keep my drawing inside my canvas after shifting it with a function?

I am trying to move my drawing with "up", "down", "left", "right" and "reset". However, I would like to keep it inside of the canvas at all times, so when I click any of the buttons and move the drawing, it would touch the borders but not go outside of the border. Here is what I have so far...
HTML
<canvas id="myCanvas" width="250" height="250" style="border:1px solid #000000;"></canvas></br>
<button id="up">Up</button><br>
<button id="left">Left</button>
<button id="right">Right</button>
<button id="reset">Reset</button></br>
<button id="down">Down</button>
JavaScript
let c, ctx, pos, centerX, centerY, radius, eyeRadius, eyeXOffset, eyeYOffset
window.onload = function() {
c = document.getElementById("myCanvas");
ctx = c.getContext("2d");
centerX = c.width / 2;
centerY = c.height / 2;
radius = 70;
eyeRadius = 10;
eyeXOffset = 25;
eyeYOffset = 20;
reset();
}
function drawFace(){
//my drawObject() from last assignment - separated into 3 different parts
// Draw the yellow circle
ctx.beginPath();
ctx.arc(centerX + pos.left, centerY + pos.top, radius, 0, 2 * Math.PI, false);
ctx.fillStyle = 'yellow';
ctx.fill();
ctx.lineWidth = 5;
ctx.strokeStyle = 'black';
ctx.stroke();
ctx.closePath();
}
function drawEyes(){
//my drawObject() from last assignment - separated into 3 different parts
// Draw the eyes
let eyeX = centerX + pos.left - eyeXOffset;
let eyeY = centerY + pos.top - eyeYOffset;
ctx.beginPath();
ctx.arc(eyeX, eyeY, eyeRadius, 0, 2 * Math.PI, false);
ctx.fillStyle = 'black';
ctx.fill();
ctx.closePath();
ctx.beginPath();
eyeX = centerX + pos.left + eyeXOffset;
ctx.arc(eyeX, eyeY, eyeRadius, 0, 2 * Math.PI, false);
ctx.fillStyle = 'black';
ctx.fill();
ctx.closePath();
}
function drawMouth(){
//my drawObject() from last assignment - separated into 3 different parts
// Draw the mouth
ctx.beginPath();
ctx.arc(centerX + pos.left, centerY + pos.top, 50, 0, Math.PI, false);
ctx.stroke();
ctx.closePath();
}
function draw() {
clear();
drawFace();
drawEyes();
drawMouth();
}
function clear() {
ctx.clearRect(0, 0, c.width, c.height);
}
function reset() {
pos = {
left: 0,
top: 0
}
draw();
}
function up() {
pos.top -= 20;
draw();
}
function down() {
pos.top += 20;
draw();
}
function left() {
pos.left -= 20;
draw();
}
function right() {
pos.left += 20;
draw();
}
document.getElementById("reset").onclick = reset;
document.getElementById("up").onclick = up;
document.getElementById("down").onclick = down;
document.getElementById("left").onclick = left;
document.getElementById("right").onclick = right;

Using Canvas via JavaScript, how can I draw a picture X number of times and within Y parameters?

I'm trying to draw a smiley face X number of times, and then the smiley face are Y radius from the center of the canvas. I also want to add a function where it allows the drawing to stay within the canvas, not outside as well as two functions to allow maximum number of smiley face in the circle and the maximum radius it can go up to. Eventually, I want my final product to end up looking something like this: https://imgur.com/VvDcFXq. I am new to Canvas and any help is greatly appreciated
<!DOCTYPE>
<html lang="en">
<meta charset="UTF-8">
<head>
<title>CPSC 1045 Assignment 7 - Smiley Rotator</title>
</head>
<body>
<h1>CPSC 1045 Assignment 7 - Simley Rotator</h1>
<p>Enter a number of smiles to draw<input type="number" min="0" max="9" id="NumberofSmiles"></p>
<p>Enter how far from the center of the canvas to draw them<input type="number" min="0" max="151" id="radius"></p>
<button id="draw">Draw</button><br>
<canvas id="myCanvas" height="400" width="400" style="border: 1px solid black">
<script>
let c, ctx, pos, centerX, centerY, radius, eyeRadius, eyeXOffset, eyeYOffset
document.getElementById("draw").onclick = checkNumber;
document.getElementById("draw").onclick = checkRadius;
function placement() {
c = document.getElementById("myCanvas");
ctx = c.getContext("2d");
centerX = c.width / 2;
centerY = c.height / 2;
radius = 70;
eyeRadius = 10;
eyeXOffset = 25;
eyeYOffset = 20;
reset();
}
function drawFace(){
// Draw the yellow circle
ctx.beginPath();
ctx.arc(centerX + pos.left, centerY + pos.top, radius, 0, 2 * Math.PI, false);
ctx.fillStyle = 'yellow';
ctx.fill();
ctx.lineWidth = 5;
ctx.strokeStyle = 'black';
ctx.stroke();
ctx.closePath();
}
function drawEyes(){
// Draw the eyes
let eyeX = centerX + pos.left - eyeXOffset;
let eyeY = centerY + pos.top - eyeYOffset;
ctx.beginPath();
ctx.arc(eyeX, eyeY, eyeRadius, 0, 2 * Math.PI, false);
ctx.fillStyle = 'black';
ctx.fill();
ctx.closePath();
ctx.beginPath();
eyeX = centerX + pos.left + eyeXOffset;
ctx.arc(eyeX, eyeY, eyeRadius, 0, 2 * Math.PI, false);
ctx.fillStyle = 'black';
ctx.fill();
ctx.closePath();
}
function drawMouth(){
// Draw the mouth
ctx.beginPath();
ctx.arc(centerX + pos.left, centerY + pos.top, 50, 0, Math.PI, false);
ctx.stroke();
ctx.closePath();
}
function draw(x,y) {
clear();
drawFace();
drawEyes();
drawMouth();
}
function clear() {
ctx.clearRect(0, 0, c.width, c.height);
}
function checkNumber() {
var input = document.getElementById("NumberofSmiles").value;
if (input > 9) {
alert("You have enter an invalid number");
}
}
function checkRadius() {
var inputs = document.getElementById("radius").value;
if (inputs > 150) {
alert("You have entered an invalid radius");
}
}
function checkmyvalue() {
checkRadius();
checkNumber();
}
</script>
</body>
</html>
I've tried to save as much as I could from your code.
Since you want to rotate the smileys I draw them around the origin of the canvas and then I translate to the position and rotate the context:
ctx.translate(pos.left,pos.top)
ctx.rotate(Angle);
Another change I've made: I've changed the radius of the smiley because I thought it was too big but you can change it back at what you want. Everything else will scale proportionally.
I hope this is what you need.
const c = document.getElementById("myCanvas");
const ctx = c.getContext("2d");
let center = {};
center.x = c.width / 2;
center.y = c.height / 2;
let face_radius = 30;
let eyeRadius = face_radius / 7;
let mouth_radius = face_radius * 0.7;
let eyeXOffset = face_radius * 0.36;
let eyeYOffset = face_radius * 0.28;
function drawFace() {
// Draw the yellow circle
ctx.beginPath();
ctx.arc(0, 0, face_radius, 0, 2 * Math.PI, false);
ctx.fillStyle = "yellow";
ctx.fill();
ctx.lineWidth = 5;
ctx.strokeStyle = "black";
ctx.stroke();
ctx.closePath();
}
function drawEyes() {
// Draw the eyes
let eyeX = - eyeXOffset;
let eyeY = - eyeYOffset;
ctx.beginPath();
ctx.arc(eyeX, eyeY, eyeRadius, 0, 2 * Math.PI, false);
ctx.fillStyle = "black";
ctx.fill();
ctx.closePath();
ctx.beginPath();
eyeX = eyeXOffset;
ctx.arc(eyeX, eyeY, eyeRadius, 0, 2 * Math.PI, false);
ctx.fillStyle = "black";
ctx.fill();
ctx.closePath();
}
function drawMouth() {
// Draw the mouth
ctx.beginPath();
ctx.arc(0, 0, mouth_radius, 0, Math.PI, false);
ctx.stroke();
ctx.closePath();
}
function clear() {
ctx.clearRect(0, 0, c.width, c.height);
}
function drawSmiley(pos,Angle) {
ctx.save();
ctx.translate(pos.left,pos.top)
ctx.rotate(Angle);
drawFace();
drawEyes();
drawMouth();
ctx.restore();
}
function checkNumber() {
let n = parseInt(NumberofSmiles.value);
if (n > 0 && n < 9) {
return n;
} else {
alert("You have enter an invalid number");
clear();
}
}
function checkRadius() {
let R = parseInt(_radius.value);
let maxR = c.width/2 - face_radius
if (R > 0 && R < maxR) {
return R;
} else {
alert("The radius has to be smaller than "+ maxR );
clear();
}
}
function checkmyvalue() {
let R = checkRadius();
let N = checkNumber();
let angle = 2 * Math.PI / N;
clear();
for (let i = 0; i < N; i++) {
let Angle = angle * i;
let pos = {};
pos.left = center.x + R * Math.cos(Angle);
pos.top = center.y + R * Math.sin(Angle);
drawSmiley(pos,Angle);
}
}
draw.addEventListener("click", checkmyvalue);
canvas{border:1px solid}
<h1>CPSC 1045 Assignment 7 - Simley Rotator</h1>
<p>Enter a number of smiles to draw<input type="number" min="0" max="9" id="NumberofSmiles"></p>
<p>Enter how far from the center of the canvas to draw them<input type="number" min="0" max="151" id="_radius"></p>
<button id="draw">Draw</button><br>
<canvas id="myCanvas" height="400" width="400" style="border: 1px solid black">

In Canvas via JavaScript, How Can I move an object to a different coordinate?

I have here A simple "game" with controls, and the reset button to reset the image drawn (smiley face) back to the center. I have tried this code with this an empty circle and I was able to move it around via the buttons without any problems. I proceeded to decorate the circle and now I am not able to move my drawn image. Any feedback or solution would be appreciated.
<!DOCTYPE>
<html lang="en">
<meta charset="UTF-8">
<body>
<button id="reset">Reset</button></br>
<canvas id="myCanvas" width="250" height="250" style="border:1px solid#000000;"></canvas></br>
<button id="left">Left</button>
<button id="up">Up</button>
<button id="down">Down</button>
<button id="right">Right</button>
<script>
let c, ctx, pos, centre = { x: 95, y: 50 }
window.onload = function drawSmile(){
let c = document.getElementById("myCanvas");
let ctx = c.getContext("2d");
let centerX = c.width / 2;
let centerY = c.height / 2;
let radius = 70;
let eyeRadius = 10;
let eyeXOffset = 25;
let eyeYOffset = 20;
// draw the yellow circle
ctx.beginPath();
ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
ctx.fillStyle = 'yellow';
ctx.fill();
ctx.lineWidth = 5;
ctx.strokeStyle = 'black';
ctx.stroke();
// draw the eyes
ctx.beginPath();
var eyeX = centerX - eyeXOffset;
var eyeY = centerY - eyeXOffset;
ctx.arc(eyeX, eyeY, eyeRadius, 0, 2 * Math.PI, false);
var eyeX = centerX + eyeXOffset;
ctx.arc(eyeX, eyeY, eyeRadius, 0, 2 * Math.PI, false);
ctx.fillStyle = 'black';
ctx.fill();
// draw the mouth
ctx.beginPath();
ctx.arc(centerX, centerY, 50, 0, Math.PI, false);
ctx.stroke();
reset();
}
function draw(){
clear();
ctx.beginPath();
ctx.arc(centre.x + pos.left, centre.y + pos.top, 40, 0, 2*Math.PI);
ctx.stroke();
}
function clear(){
ctx.clearRect(0, 0, 2000, 1000);
}
function reset() {
pos = { left: 0, top: 0 }
draw();
}
function up() {
ctx.clearRect(0, 0, 2000, 1000);
pos.top-= 20;
draw();
}
function down() {
pos.top+= 20;
draw();
}
function left() {
pos.left-= 20;
draw();
}
function right() {
pos.left+= 20;
draw();
}
document.getElementById("reset").onclick = reset;
document.getElementById("up").onclick = up;
document.getElementById("down").onclick = down;
document.getElementById("left").onclick = left;
document.getElementById("right").onclick = right;
</script>
</body>
</html>
Do check the below code. It is similar to the last drawing of empty circle, I have just included the correct position calculations, and included closePath() method at appropriate places.
let c
, ctx
, pos
, centerX
, centerY
, radius
, eyeRadius
, eyeXOffset
, eyeYOffset
window.onload = function() {
c = document.getElementById("myCanvas");
ctx = c.getContext("2d");
centerX = c.width / 2;
centerY = c.height / 2;
radius = 70;
eyeRadius = 10;
eyeXOffset = 25;
eyeYOffset = 20;
reset();
}
function drawFace(){
// Draw the yellow circle
ctx.beginPath();
ctx.arc(centerX + pos.left, centerY + pos.top, radius, 0, 2 * Math.PI, false);
ctx.fillStyle = 'yellow';
ctx.fill();
ctx.lineWidth = 5;
ctx.strokeStyle = 'black';
ctx.stroke();
ctx.closePath();
}
function drawEyes(){
// Draw the eyes
var eyeX = centerX + pos.left - eyeXOffset;
var eyeY = centerY + pos.top - eyeYOffset;
ctx.beginPath();
ctx.arc(eyeX, eyeY, eyeRadius, 0, 2 * Math.PI, false);
ctx.fillStyle = 'black';
ctx.fill();
ctx.closePath();
ctx.beginPath();
eyeX = centerX + pos.left + eyeXOffset;
ctx.arc(eyeX, eyeY, eyeRadius, 0, 2 * Math.PI, false);
ctx.fillStyle = 'black';
ctx.fill();
ctx.closePath();
}
function drawMouth(){
// Draw the mouth
ctx.beginPath();
ctx.arc(centerX + pos.left, centerY + pos.top, 50, 0, Math.PI, false);
ctx.stroke();
ctx.closePath();
}
function draw() {
clear();
drawFace();
drawEyes();
drawMouth();
}
function clear() {
ctx.clearRect(0, 0, c.width, c.height);
}
function reset() {
pos = {
left: 0,
top: 0
}
draw();
}
function up() {
pos.top -= 20;
draw();
}
function down() {
pos.top += 20;
draw();
}
function left() {
pos.left -= 20;
draw();
}
function right() {
pos.left += 20;
draw();
}
document.getElementById("reset").onclick = reset;
document.getElementById("up").onclick = up;
document.getElementById("down").onclick = down;
document.getElementById("left").onclick = left;
document.getElementById("right").onclick = right;
<!DOCTYPE>
<html lang="en">
<meta charset="UTF-8">
<body>
<button id="reset">Reset</button><br>
<canvas id="myCanvas" width="250" height="250" style="border:1px solid#000000;"></canvas><br>
<button id="left">Left</button>
<button id="up">Up</button>
<button id="down">Down</button>
<button id="right">Right</button>
</body>
</html>

Categories

Resources