How to solve this canvas fillStyle problem? - javascript

class Entity {
constructor(name, type = 'player') {
this.name = name,
this.type = type
}
newObject(name, ...pvals) {
this[name] = {}
if (pvals) {
for (var i = 0; i < pvals.length; i += 2) {
this[name][pvals[i]] = pvals[i + 1]
}
}
}
}
const canvas = document.querySelector('canvas')
const ctx = canvas.getContext('2d')
canvas.height = window.innerHeight - 20
canvas.width = window.innerWidth
var frame = new Entity('frame', 'game-object')
var button = new Entity('button', 'player-component')
const radius = 70
var speed = 3
frame.newObject('$', 'r', radius)
button.newObject('$', 'r', radius / 3)
function updateFrame() {
ctx.fillStyle = 'black'
ctx.arc((canvas.width / 2), (canvas.height / 2), frame.$.r, 0, Math.PI * 2)
ctx.fill()
ctx.fillStyle = 'red'
ctx.arc((canvas.width / 2), (canvas.height / 2), button.$.r, 0, Math.PI * 2)
ctx.fill()
}
updateFrame()
<canvas></canvas>
As far as I know it should print big black circle in the middle of the canvas and on top of that a red small circle. But it just prints a big red circle. I just can't figure it out.

Just like #Teemu points out in the comment "Begin the paths" you must use the ctx.beginPath() between your arcs when you are changing colors
https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/beginPath#examples
I simplified a lot of your code to show just the problem, you should do the same when you are troubleshooting class Entity was just a distraction and we can reproduce without it
const canvas = document.querySelector('canvas')
const ctx = canvas.getContext('2d')
ctx.beginPath()
ctx.fillStyle = 'black'
ctx.arc(50, 50, 20, 0, Math.PI * 2)
ctx.fill()
ctx.beginPath()
ctx.fillStyle = 'red'
ctx.arc(50, 50, 10, 0, Math.PI * 2)
ctx.fill()
<canvas></canvas>

You should add these 2 lines:
ctx.beginPath();
ctx.closePath();
function updateFrame() {
ctx.beginPath();
ctx.fillStyle = 'black'
ctx.arc((canvas.width / 2), (canvas.height / 2), frame.$.r, 0, Math.PI * 2)
ctx.closePath();
ctx.fill();
ctx.beginPath();
ctx.fillStyle = 'red'
ctx.arc((canvas.width / 2), (canvas.height / 2), button.$.r, 0, Math.PI * 2)
ctx.closePath();
ctx.fill()
}

Related

HTML Canvas Separating Strokes

I made a simple canvas program that draws a spiral starting from the canvas's center, using a line that constantly has new points drawn. It works until another shape or line is added, and I can't think of any way to fix it. Is there any way to separate these two strokes without using a beginPath() before the lineTo()?
const canvas = document.querySelector("canvas");
canvas.width = innerWidth;
canvas.height = innerHeight;
const c = canvas.getContext("2d");
let x, y;
let i = 0;
const animate = function() {
requestAnimationFrame(animate);
c.clearRect(0, 0, canvas.width, canvas.height);
c.lineTo(x, y);
c.stroke();
// c.beginPath();
// c.beginPath();
// c.arc(canvas.width / 2, canvas.height / 2, 20, 0, Math.PI * 2, false);
// c.strokeStyle = "red";
// c.stroke();
// c.closePath();
x = canvas.width / 2 + Math.cos(i * Math.PI / 180) * i;
y = canvas.height / 2 + Math.sin(i * Math.PI / 180) * i;
i += 5;
}
animate();
The drawing of your spiral is possible because the lineTo() method draws a straight line from the current path's last position to the position given as a parameter. As you realized, this breaks as soon as you add a new path somewhere in-between.
One possible solution is keeping track of the positions that make up the spiral instead of trying to draw it right away. To do this we can fill a simply array with object's holding the x and y values for the spiral's segments.
For example:
const canvas = document.querySelector("canvas");
canvas.width = innerWidth;
canvas.height = innerHeight;
const c = canvas.getContext("2d");
let x, y;
let i = 0;
let points = [];
const animate = function() {
requestAnimationFrame(animate);
c.clearRect(0, 0, canvas.width, canvas.height);
c.beginPath();
c.arc(canvas.width / 2, canvas.height / 2, 20, 0, Math.PI * 2, false);
c.strokeStyle = "red";
c.stroke();
c.closePath();
points.push({
x: canvas.width / 2 + Math.cos(i * Math.PI / 180) * i,
y: canvas.height / 2 + Math.sin(i * Math.PI / 180) * i
});
c.beginPath();
c.strokeStyle = "black";
c.moveTo(points[0].x, points[0].y);
if (points.length > 1) {
for (let a = 0; a < points.length; a++) {
c.lineTo(points[a].x, points[a].y);
}
}
c.stroke();
c.closePath();
i += 5;
}
animate();
<canvas></canvas>

How do I remove the line connection between the ellipse? JS Canvas

So I am trying to draw a face with Javascript in a canvas and the smile is using ellipse(x, y, rX, rY, rot, start, end. I closed the path (closePath();) and that follow that with a stroke command (stroke();). This draws the ellipse, which looks like a half-circle. But this also draws a stroke which connects the two ends of the half-circle, which I don't want. It looks like this:
var c = document.createElement('canvas');
var ctx = c.getContext('2d');
var w = 500;
var h = 300;
window.onload = function() {
c.style.backgroundColor = '#aaa';
c.width = w;
c.height = h;
c.tabIndex = '1';
c.style.outline = 'none';
c.style.display = 'block';
c.style.margin = '0 auto';
c.style.position = 'relative';
c.style.top = '50px';
document.body.style.margin = '0';
document.body.appendChild(c);
}
setInterval(function() {
ctx.clearRect(0, 0, w, h);
ctx.beginPath();
ctx.ellipse(w / 2, h / 2, 30, 35, 0, 0, 2 * Math.PI);
ctx.closePath();
ctx.fillStyle = '#cf9454';
ctx.fill();
ctx.stroke();
ctx.beginPath();
ctx.ellipse(w / 2 - 10, h / 2 - 10, 2, 2, 0, 0, 2 * Math.PI);
ctx.moveTo(w / 2 + 10, h / 2 - 10);
ctx.ellipse(w / 2 + 10, h / 2 - 10, 2, 2, 0, 0, 2 * Math.PI);
ctx.closePath();
ctx.stroke();
ctx.fillStyle = '#000';
ctx.fill();
ctx.beginPath();
ctx.ellipse(w / 2, h / 2 + 10, 16, 12, 0, 0, 1 * Math.PI);
ctx.closePath();
ctx.stroke();
}, 30);
You should simply omit the last closePath() call. Its intention is described in MDN's documentation:
The CanvasRenderingContext2D.closePath() method of the Canvas 2D API attempts to add a straight line from the current point to the start of the current sub-path.
It effectively adds that straight line to the "mouth" shape. So just leave that out:
var c = document.createElement('canvas');
var ctx = c.getContext('2d');
var w = 500;
var h = 140; // reduced to make the smiley appear within the snippet area
window.onload = function() {
c.width = w;
c.height = h;
c.tabIndex = '1';
c.style.backgroundColor = '#aaa';
c.style.outline = 'none';
c.style.display = 'block';
c.style.margin = '0 auto';
c.style.position = 'relative';
c.style.top = '50px';
document.body.style.margin = '0';
document.body.appendChild(c);
}
setInterval(function() {
ctx.clearRect(0, 0, w, h);
ctx.beginPath();
ctx.ellipse(w / 2, h / 2, 30, 35, 0, 0, 2 * Math.PI);
ctx.closePath();
ctx.fillStyle = '#cf9454';
ctx.fill();
ctx.stroke();
ctx.beginPath();
ctx.ellipse(w / 2 - 10, h / 2 - 10, 2, 2, 0, 0, 2 * Math.PI);
ctx.moveTo(w / 2 + 10, h / 2 - 10);
ctx.ellipse(w / 2 + 10, h / 2 - 10, 2, 2, 0, 0, 2 * Math.PI);
ctx.closePath();
ctx.stroke();
ctx.fillStyle = '#000';
ctx.fill();
ctx.beginPath();
ctx.ellipse(w / 2, h / 2 + 10, 16, 12, 0, 0, 1 * Math.PI);
//ctx.closePath(); //<----- remove this
ctx.stroke();
}, 30);
Note that Unicode has characters for smileys. Maybe they are useful for your project? I would also move some of the styling to CSS definitions. The setInterval is currently useless; but I suppose you have it for future purposes.
For example:
var c = document.createElement('canvas');
var ctx = c.getContext('2d');
var w = 500;
var h = 140; // reduced to make the smiley appear within the snippet area
window.onload = function() {
c.width = w;
c.height = h;
c.tabIndex = 1;
document.body.appendChild(c);
ctx.font = "70px Verdana";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
setInterval(function() {
ctx.clearRect(0, 0, w, h);
ctx.fillText("🙂", w/2, h/2);
}, 30);
}
canvas {
background-color: #aaa;
outline: none;
display: block;
margin: 0 auto;
position: relative;
top: 50px;
}
body { margin: 0; }

Rotate HTML canvas circle scale

I am experiencing trouble in rotating a circle with HTML5 canvas.
the function is about control a circle,
but the scale is out of control...
anyone know how to adjust(or set rotate) the scale to fit the canvas circle?
The starting angle(0.7 pi) and endAngle(0.3 pi).
Do I need to reset the rotate?
--> ctx.rotate(Math.PI * 3 / 16);
-->(math.pi*15/10*1/8)
var degrees = 0;
var color = "lightblue";
var bgcolor = "#222";
var canvas, ctx, W, Htext;
function init_rpm(name, val) {
canvas = document.getElementById(name);
ctx = canvas.getContext("2d");
//dimensions
W = canvas.width;
H = canvas.height;
//Clear the canvas everytime a chart is drawn
ctx.clearRect(0, 0, W, H);
//Background 360 degree arc
ctx.beginPath();
ctx.lineWidth = 25;
ctx.strokeStyle = bgcolor;
ctx.arc(W / 2, H / 2, Math.floor(W / 3), 0.7 * Math.PI, 0.3 * Math.PI, false); //you can see thr src now
ctx.stroke();
//center circle
ctx.save();
ctx.beginPath();
ctx.strokeStyle = 'rgba(255, 255, 255, .2)';
ctx.lineWidth = 10;
ctx.arc(W / 2, H / 2, Math.floor(W / 3) - 40, 0.7 * Math.PI, 0.3 * Math.PI, false);
ctx.stroke();
ctx.restore();
// scale
ctx.save();
ctx.translate(300, 300);
for (var i = 0; i < 9; i++) {
ctx.beginPath();
ctx.lineWidth = 2;
ctx.strokeStyle = 'rgba(255, 255, 255, .3)';
ctx.moveTo(130, 0);
ctx.lineTo(140, 0);
ctx.stroke();
ctx.rotate(Math.PI * 3 / 16);
}
ctx.restore();
//angle in radians =angle in drgrees*pi/180 make color
var percent = val / 8000 * 100;
ctx.beginPath();
ctx.lineWidth = 30;
// ctx.strokeStyle= color;
var my_gradient = ctx.createLinearGradient(0, 150, 250, 300);
my_gradient.addColorStop(0, "#B31918");
my_gradient.addColorStop(1, "#FFA000");
ctx.strokeStyle = my_gradient;
//the arc start from the rightmost end. if we deduct 90 degrees from the angles
//the arc will start from the top most end
ctx.arc(W / 2, H / 2, Math.floor(W / 3), 0.7 * Math.PI, 0.7 * Math.PI + 1.6 * Math.PI / 100 * percent, false); //you can see thr src now
ctx.stroke();
//add text
ctx.fillStyle = color;
ctx.font = "7vh play";
// text=Math.floor(degrees/360*8)+' RPM';
text = degrees / 360 * 8;
text_width = ctx.measureText(text).width;
ctx.fillText(text, W / 2 - text_width / 2, H / 2 + 15);
ctx.font = "3vh play";
text2 = 'RPM';
ctx.fillText(text2, W / 2 - text_width / 2, H / 2 + 70);
}
function draw(val, name, type) {
// console.log(val);
if (name != "" || name != null) {
if (type == "rpm") {
if (val != "" || val != null) {
degrees = val / 1000 / 8 * 360;
} else {
degrees = 180;
}
init_rpm(name, val);
} else if (type == "kmh") {
if (val != "" || val != null) {
degrees = val;
} else {
degrees = 180;
}
init_kmh(name);
}
} else {
console.log('can not find canvas id');
}
}
$(document).ready(function () {
//canvas init
draw(0, "canvas3", "rpm");
var rpmControl2 = document.querySelector('input[id=get_rpm]');
rpmControl2.addEventListener('input', function () {
draw(this.value, "canvas3", "rpm");
});
});
#canvas2{
display:inline;
}
body{
background:#333;
font-family: 'Play', sans-serif;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.1/jquery.min.js"></script>
<div class="container-fluid">
<input id="get_rpm" type="number" value="0" min="0" max="8000" step="100" />
<span style="color:white">RPM</span>
<canvas id="canvas3" width="600" height="600"></canvas>
Your scale is drawn by drawing its lines in a single direction and then controlling the context's rotation to make all these lines point at a different angle.
Just like if you held a ruler always in the same direction and simply rotated the leaf of paper underneath.
So to control the rotation of your scale, you have to set the context's rotation (or leaf of paper) before you draw the first line.
var ctx = c.getContext('2d');
angle.oninput = function(e) {
ctx.clearRect(0, 0, c.width, c.height);
var rad = angle.value * (Math.PI / 180);
// move the context so its center be at 0,0
ctx.setTransform(1, 0, 0, 1, c.width/2, c.height/2);
// rotate it so we face the required angle
ctx.rotate(rad);
var stepAngle = Math.PI*2 / 14,
innerRad = c.width / 2.8,
outerRad = c.width / 2.5;
ctx.beginPath();
for(var i = 0; i < 12; i++) {
ctx.moveTo(0, innerRad); // move vertically
ctx.lineTo(0, outerRad); // draw line vertically
ctx.rotate(stepAngle); // rotate by fixed increment
}
ctx.stroke(); // all drawn, we can stroke
ctx.setTransform(1, 0, 0, 1, 0, 0); // reset context's position
};
angle.oninput();
<input type="range" min="0" max="360" id="angle"><br>
<canvas id="c" width="200" height="200"></canvas>
And with your code:
var degrees = 0;
var color = "lightblue";
var bgcolor = "#222";
var canvas, ctx, W, Htext;
function init_rpm(name, val) {
canvas = document.getElementById(name);
ctx = canvas.getContext("2d");
//dimensions
W = canvas.width;
H = canvas.height;
//Clear the canvas everytime a chart is drawn
ctx.clearRect(0, 0, W, H);
//Background 360 degree arc
ctx.beginPath();
ctx.lineWidth = 25;
ctx.strokeStyle = bgcolor;
ctx.arc(W / 2, H / 2, Math.floor(W / 3), 0.7 * Math.PI, 0.3 * Math.PI, false); //you can see thr src now
ctx.stroke();
//center circle
ctx.beginPath();
ctx.strokeStyle = 'rgba(255, 255, 255, .2)';
ctx.lineWidth = 10;
ctx.arc(W / 2, H / 2, Math.floor(W / 3) - 40, 0.7 * Math.PI, 0.3 * Math.PI, false);
ctx.stroke();
//EDITS BEGIN HERE
// scale
ctx.setTransform(1, 0, 0, 1, 300, 300);
ctx.beginPath();
ctx.lineWidth = 2;
ctx.strokeStyle = 'rgba(255, 255, 255, .3)';
// there should be 10 lines
var stepAngle = (Math.PI * 2) / 10;
// begin angle
ctx.rotate(0.7 * Math.PI);
// draw only 9 of the 10 lines
for (var i = 0; i < 9; i++) {
ctx.moveTo(130, 0);
ctx.lineTo(140, 0);
ctx.rotate(stepAngle);
}
ctx.stroke();
ctx.setTransform(1, 0, 0, 1, 0, 0);
//EDITS END HERE
var percent = val / 8000 * 100;
ctx.beginPath();
ctx.lineWidth = 30;
var my_gradient = ctx.createLinearGradient(0, 150, 250, 300);
my_gradient.addColorStop(0, "#B31918");
my_gradient.addColorStop(1, "#FFA000");
ctx.strokeStyle = my_gradient;
//the arc start from the rightmost end. if we deduct 90 degrees from the angles
//the arc will start from the top most end
ctx.arc(W / 2, H / 2, Math.floor(W / 3), 0.7 * Math.PI, 0.7 * Math.PI + 1.6 * Math.PI / 100 * percent, false); //you can see thr src now
ctx.stroke();
//add text
ctx.fillStyle = color;
ctx.font = "7vh play";
// text=Math.floor(degrees/360*8)+' RPM';
text = degrees / 360 * 8;
text_width = ctx.measureText(text).width;
ctx.fillText(text, W / 2 - text_width / 2, H / 2 + 15);
ctx.font = "3vh play";
text2 = 'RPM';
ctx.fillText(text2, W / 2 - text_width / 2, H / 2 + 70);
}
function draw(val, name, type) {
// console.log(val);
if (name != "" || name != null) {
if (type == "rpm") {
if (val != "" || val != null) {
degrees = val / 1000 / 8 * 360;
} else {
degrees = 180;
}
init_rpm(name, val);
} else if (type == "kmh") {
if (val != "" || val != null) {
degrees = val;
} else {
degrees = 180;
}
init_kmh(name);
}
} else {
console.log('can not find canvas id');
}
}
$(document).ready(function () {
//canvas init
draw(0, "canvas3", "rpm");
var rpmControl2 = document.querySelector('input[id=get_rpm]');
rpmControl2.addEventListener('input', function () {
draw(this.value, "canvas3", "rpm");
});
});
#canvas2{
display:inline;
}
body{
background:#333;
font-family: 'Play', sans-serif;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.1/jquery.min.js"></script>
<div class="container-fluid">
<input id="get_rpm" type="number" value="0" min="0" max="8000" step="100" />
<span style="color:white">RPM</span>
<canvas id="canvas3" width="600" height="600"></canvas>

How do you set up multiple orbiting canvas drawings (pure js)

I am making a solar system with pre-made planets and want to know how to get more than one to rotate around the sun. I ran into the issue of not being able to rotate 2 at once. Any solutions?Here is current code:
Orbiting page:
var canvasP = document.getElementById("planetsOrbit");
var ctx2 = canvasP.getContext("2d");
var angle = 6 * Math.PI / 180;
var cx = window.innerWidth / 2;
var cy = window.innerHeight / 2.12;
var radiusNew = (window.innerHeight + window.innerWidth) * 0.15;
function resizeCanvasPOrbit() {
ctx2.clearRect(0, 0, canvasP.width, canvasP.height);
if (canvasP.width < window.innerWidth) {
canvasP.width = window.innerWidth * 0.99;
}'
if (canvasP.height < window.innerHeight)
{
canvasP.height = window.innerHeight * 0.98;
}
w = canvasP.width
h = canvasP.height
}
function draw(x, y) {
ctx2.clearRect(0, 0, w, h);
ctx2.save();
ctx2.beginPath();
ctx2.beginPath();
roa(x, y, window.innerHeight * window.innerWidth * 0.00008);
ctx2.stroke();
ctx2.restore();
};
function keepDrawing() {
ctx2.clearRect(0, 0, w, h);
draw(newX, newY);
setTimeout(keepDrawing, 250);
}
window.requestAnimFrame = (function (callback) {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function (callback) {
window.setTimeout(callback, 5000 / 60);
};
})();
var fps = 60;
function animate() {
setTimeout(function () {
requestAnimationFrame(animate);
// increase the angle of rotation A.K.A SPEED!
angle += 1 * Math.PI / 3600;
//calculate the new ball.x / ball.y
var newX = cx - radiusNew * Math.cos(angle);
var newY = cy + radiusNew * Math.sin(angle);
//draw
ctx2.clearRect(0, 0, w, h);
draw(newX, newY);
//draw the centerpoint
ctx2.beginPath();
ctx2.arc(cx, cy, radiusNew, 0, Math.PI * 2, false);
ctx2.closePath();
}, 1000 / fps);
}
animate();
and the Premade Planets:
//sun
solus = function(xAxis, yAxis, radius) {
ctx.shadowBlur=400
ctx.shadowColor="red"
ctx.fillStyle ="#ff9900";
ctx.beginPath();
ctx.arc(xAxis, yAxis, radius, 0, Math.PI * 2, false)
ctx.fill();
ctx.shadowBlur = 0;
}
//Fighting Pits
pits = function(xAxis, yAxis, radius) {
ctx.beginPath();
ctx.fillStyle ="#990000"
ctx.arc(xAxis, yAxis, radius, 0, Math.PI , false)
ctx.moveTo(xSpot1,ySpot1)
ctx.lineTo(xSpot1,ySpot2)
ctx.lineTo(xSpot2,ySpot2)
ctx.lineTo(xSpot2,ySpot3)
ctx.lineTo(xSpot3,ySpot4)
ctx.lineTo(xSpot4,ySpot3)
ctx.lineTo(xSpot4,ySpot2)
ctx.lineTo(xSpot5,ySpot2)
ctx.lineTo(xSpot5,ySpot1)
ctx.lineTo(xSpot1,ySpot1)
ctx.fill();
}
//Water Planet
roa = function(xAxis, yAxis, radius) {
ctx2.shadowBlur = 0;
ctx2.beginPath();
ctx2.fillStyle ="#00ffff"
ctx2.arc(xAxis, yAxis, radius, 0, Math.PI * 2, false)
ctx2.fill();
}
//Forest planet atmoshpere
eldridA = function(xAxis, yAxis, radius) {
ctx.beginPath();
ctx.fillStyle ="rgba(230, 230, 230, 0.3)";
ctx.arc(xAxis, yAxis, radius, 0, Math.PI * 2, false)
ctx.fill();
}
//forest core
eldrid = function(xAxis, yAxis, radius) {
ctx.shadowColor = "rgba(230, 230, 230, 0.2)";
ctx.shadowBlur = 200;
ctx.beginPath();
ctx.fillStyle ="#ff9900"
ctx.arc(xAxis, yAxis, radius / 2, 0, Math.PI * 2, false)
ctx.fill();
xAxis2 = xAxis - window.innerWidth * 0.009
yAxis2 = yAxis + window.innerHeight * 0.007
ctx.arc(xAxis2, yAxis2, radius / 4, 0, Math.PI * 2, false)
ctx.fill();
ctx.beginPath();
xAxis3 = xAxis + window.innerWidth * 0.011
ctx.arc(xAxis3 , yAxis2, radius / 3, 0, Math.PI * 2, false)
ctx.fill();
ctx.beginPath();
yAxis3 = yAxis - window.innerHeight * 0.03
ctx.arc(xAxis, yAxis3, radius / 3, 0, Math.PI * 2, false)
ctx.fill();
ctx.shadowBlur = 0;
ctx.shadowColor = null;
}
So how can I get more than one planet to orbit the Sun? any Help is appreciated.
I did a simple demo of a solar system with multiple planets using canvas: http://codepen.io/giladaya/pen/PWWKLP
I believe that you can easily adapt it to your needs and I'll explain the main parts of the code:
Each planet has it's own properties like radius, distance from center, radial velocity and a reference to a draw function.
var planets = [
{
name: 'sun', // for reference
rad: 30, // Planet radius
distance: 0, // Planet distance from center
rv: 0, // radial velocity (deg/sec)
drawFunc: drawSun // draw function
},
{
name: 'foo',
rad: 10,
distance: 70,
rv: 1,
drawFunc: drawBlue
},
{
name: 'bar',
rad: 15,
distance: 100,
rv: 2,
drawFunc: drawRed
}
];
The main loop iterates over all the planets, updates their current angle according to the radial velocity and draws each one in it's new, updated location.
function draw() {
ctx.fillRect(-cW/2, -cH/2, cW, cH);
var now = Date.now(),
dts = (now - lastFrameTime) / 1000;
planets.forEach(function(planet, idx){
var theta = 0;
planetsAngle[idx] += planet.rv/Math.PI * dts;
theta = planetsAngle[idx];
var x = planet.distance * Math.cos(theta);
var y = planet.distance * Math.sin(theta);
planet.drawFunc(ctx, x, y, planet.rad);
});
lastFrameTime = now;
requestAnimationFrame(draw);
}
Note that if using requestAnimationFrame, you don't need to set timers.
The draw function for each planet can be as complicated as you want in order to have more elements on the planet. For example:
function drawRed(ctx, x, y, rad) {
ctx.save();
ctx.fillStyle = 'red';
ctx.translate(x, y);
ctx.beginPath();
ctx.arc(0, 0, rad, 0, 2*Math.PI , false);
ctx.fill();
ctx.fillStyle = '#A00';
ctx.fillRect(-4, -4, 8, 8);
ctx.restore();
}

Circle won't be drawn on canvas

Hi I try to make an animation. A circle should run from right to left. Now the problem is that no circle become drawed in the canvas. I check in chromes developer tool the console log but there was no error. Have anyone a idea what the mistake is?
window.onload = window.onresize = function() {
var C = 1; // canvas width to viewport width ratio
var el = document.getElementById("myCanvas");
var viewportWidth = window.innerWidth;
var viewportHeight = window.innerHeight;
var canvasWidth = viewportWidth * C;
var canvasHeight = viewportHeight;
el.style.position = "fixed";
el.setAttribute("width", canvasWidth);
el.setAttribute("height", canvasHeight);
var x = canvasWidth / 100;
var y = canvasHeight / 100;
var ballx = canvasWidth / 100;
var n;
window.ctx = el.getContext("2d");
ctx.clearRect(0, 0, canvasWidth, canvasHeight);
// draw triangles
function init() {
ballx;
return setInterval(main_loop, 1000);
}
function drawcircles() {
function getRandomElement(array) {
if (array.length == 0) {
return undefined;
}
return array[Math.floor(Math.random() * array.length)];
}
var circles = [
'#FFFF00',
'#FF0000',
'#0000FF'
];
ctx.beginPath();
ctx.arc(ballx * 108, canvasHeight / 2, x * 5, 0, 2 * Math.PI, false);
ctx.fillStyle = JSON.stringify(getRandomElement(circles));
ctx.fill();
ctx.closePath;
}
function draw() {
var counterClockwise = false;
ctx.clearRect(0, 0, canvasWidth, canvasHeight);
//first halfarc
ctx.beginPath();
ctx.arc(x * 80, y * 80, y * 10, 0 * Math.PI, 1 * Math.PI, counterClockwise);
ctx.lineWidth = y * 1;
ctx.strokeStyle = 'black';
ctx.stroke();
ctx.closePath;
//second halfarc
ctx.beginPath();
ctx.arc(x * 50, y * 80, y * 10, 0 * Math.PI, 1 * Math.PI, counterClockwise);
ctx.lineWidth = y * 1;
ctx.strokeStyle = 'black';
ctx.stroke();
ctx.closePath;
//third halfarc
ctx.beginPath();
ctx.arc(x * 20, y * 80, y * 10, 0 * Math.PI, 1 * Math.PI, counterClockwise);
ctx.lineWidth = y * 1;
ctx.strokeStyle = 'black';
ctx.stroke();
ctx.closePath;
// draw stop button
ctx.beginPath();
ctx.moveTo(x * 87, y * 2);
ctx.lineTo(x * 87, y * 10);
ctx.lineWidth = x;
ctx.stroke();
ctx.beginPath();
ctx.moveTo(x * 95, y * 2);
ctx.lineTo(x * 95, y * 10);
ctx.lineWidth = x;
ctx.stroke();
ctx.closePath;
//circle
}
function update() {
ballx -= 0.1;
if (ballx < 0) {
ballx = -radius;
}
}
function main_loop() {
drawcircles();
draw();
update();
}
init();
function initi() {
console.log('init');
// Get a reference to our touch-sensitive element
var touchzone = document.getElementById("myCanvas");
// Add an event handler for the touchstart event
touchzone.addEventListener("mousedown", touchHandler, false);
}
function touchHandler(event) {
// Get a reference to our coordinates div
var can = document.getElementById("myCanvas");
// Write the coordinates of the touch to the div
if (event.pageX < x * 50 && event.pageY > y * 10) {
ballx += 1;
} else if (event.pageX > x * 50 && event.pageY > y * 10) {
ballx -= 1;
}
console.log(event, x, ballx);
draw();
}
initi();
draw();
}
<div id="gameArea">
<canvas id="myCanvas"></canvas>
</div>
Your call to draw() after calling drawcircles() has a ctx.clearRect - this clears the canvas (including the just drawn circles).
Moving drawcircles(); to after draw(); in main_loop will make the circle appear. Note that you have to wait for a bit for the circle to be drawn within the visible area.

Categories

Resources