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>
Related
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()
}
After adding the animation, the canvas gets pixelated. I've tried to fix this with adding context.clearRect(0, 0, canvas.width, canvas.height); but it hides the previous segments
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var x = canvas.width / 2;
var y = canvas.height / 2;
var radius = x - 40;
var endPercent = 45;
var curPerc = 0,
mybeg;
var counterClockwise = false;
var circ = Math.PI * 2;
var quart = Math.PI / 2;
var col = ['#000', '#ff0000', '#002bff'];
function animate(current, colr, mybeg) {
context.beginPath();
context.moveTo(x, y);
context.arc(x, y, radius, mybeg, ((circ) * current));
context.fillStyle = colr;
context.fill();
//console.log(x, y, radius, mybeg, ((circ) * current));
curPerc++;
if (curPerc <= endPercent) {
mybeg = 0;
requestAnimationFrame(function() {
animate(curPerc / 100, col[0], mybeg)
});
} else if (curPerc > 44 && curPerc <= 65) {
const mybeg1 = ((circ) * 45 / 100);
requestAnimationFrame(function() {
animate(curPerc / 100, col[1], mybeg1)
});
} else if (curPerc > 64 && curPerc <= 100) {
const mybeg2 = ((circ) * 65 / 100);
requestAnimationFrame(function() {
animate(curPerc / 100, col[2], mybeg2)
});
}
}
animate();
<canvas id="myCanvas" height="300" width="300"></canvas>
You are redrawing the same arc over itself a lot of times.
To render a smooth arc, we need semi-transparent pixels (antialiasing), and drawing semi-transparent pixels over other semi-transparent pixels will make them more an more opaque.
So the solution here is to clear everything and redraw everything at every frame.
There are several ways to do it, but one of the simplest might be to render your complete pie every-time and only animate a mask over it, using compositing:
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var x = canvas.width / 2;
var y = canvas.height / 2;
var radius = x - 40;
var stops = [
//[ begin, end , color ]
[ 0, 45, '#000' ],
[ 45, 65, '#ff0000' ],
[ 65, 100, '#002bff' ]
];
var current = 0;
animate();
function drawFullPie() {
stops.forEach( function( stop , i) {
var begin = (stop[0] / 100 ) * Math.PI * 2;
var end = (stop[1] / 100 ) * Math.PI * 2;
context.beginPath();
context.moveTo( x, y );
context.arc( x, y, radius, begin, end );
context.fillStyle = stop[2];
context.fill();
} );
}
function drawMask() {
var begin = 0;
var end = (current / 100) * Math.PI * 2;
// Keep whatever is currently painted to the canvas
// only where our next drawings will appear
context.globalCompositeOperation = 'destination-in';
context.beginPath();
context.moveTo( x, y );
context.arc( x, y, radius, begin, end );
context.fill();
// disable masking
context.globalCompositeOperation = 'source-over';
}
function animate() {
// clear at every frame
context.clearRect( 0, 0, canvas.width, canvas.height );
// draw the full pie
drawFullPie();
// mask it as needed
drawMask();
// until complete
if( current ++ < 100 ) {
// do it again
requestAnimationFrame( animate );
}
}
<canvas id="myCanvas" height="300" width="300"></canvas>
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">
I have 2 canvasses that visualize values from 2 different labels.
I wrote 2 almost the same javascripts and when I run my application. It skips the first visualitation and only shows the second one. Where is my mistake?
Here is my html code:-
<div><canvas id="canvas" width="300" height="300"></canvas></div>
<asp:Label ID="LblGauge" runat="server"></asp:Label>
<div><canvas id="canvas2" width="300" height="300"></canvas></div>
<asp:Label ID="LblGauge1" runat="server"></asp:Label>
And here are my 2 javascripts. The only difference now is the canvas/canvas2 and the lblgauge and lblgauge1. Even if I change all the variables in the second script it will still only show the second visualition.
<script>
window.onload = function () {
//canvas initialization
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
//dimensions
var W = canvas.width;
var H = canvas.height;
//Variables
var degrees = document.getElementById("LblGauge").textContent;
var new_degrees = 0;
var difference = 0;
var color = "lightgreen";
var bgcolor = "#222";
var text;
var animation_loop, redraw_loop;
function init() {
//Clear the canvas everytime a chart is drawn
ctx.clearRect(0, 0, W, H);
//Background 360 degree arc
ctx.beginPath();
ctx.strokeStyle = bgcolor;
ctx.lineWidth = 30;
ctx.arc(W / 2, H / 2, 100, 0, Math.PI * 2, false);
ctx.stroke();
//Angle in radians = angle in degrees * PI / 180
var radians = degrees * Math.PI / 180;
ctx.beginPath();
ctx.strokeStyle = color;
ctx.lineWidth = 30;
//the arc will start from the topmost end
ctx.arc(W / 2, H / 2, 100, 0 - 90 * Math.PI / 180, radians - 90 * Math.PI / 180, false);
ctx.stroke();
//Lets add the text
ctx.fillStyle = color;
ctx.font = "50px bebas";
text = Math.floor(degrees / 360 * 100) + "%";
text_width = ctx.measureText(text).width;
ctx.fillText(text, W / 2 - text_width / 2, H / 2 + 15);
}
function draw() {
//Cancel any movement animation if a new chart is requested
if (typeof animation_loop != undefined) clearInterval(animation_loop);
////time for each frame is 1sec / difference in degrees
animation_loop = setInterval(animate_to, 1000 / difference);
}
//function to make the chart move to new degrees
function animate_to() {
if (degrees == new_degrees)
if (degrees < new_degrees)
degrees++;
else
degrees--;
init();
}
draw();
}
</script>
<script>
window.onload = function () {
//canvas initialization
var canvas = document.getElementById("canvas2");
var ctx = canvas.getContext("2d");
//dimensions
var W = canvas.width;
var H = canvas.height;
//Variables
var degrees = document.getElementById("LblGauge1").textContent;
var new_degrees = 0;
var difference = 0;
var color = "lightgreen";
var bgcolor = "#222";
var text;
var animation_loop, redraw_loop;
function init() {
//Clear the canvas everytime a chart is drawn
ctx.clearRect(0, 0, W, H);
//Background 360 degree arc
ctx.beginPath();
ctx.strokeStyle = bgcolor;
ctx.lineWidth = 30;
ctx.arc(W / 2, H / 2, 100, 0, Math.PI * 2, false);
ctx.stroke();
//Angle in radians = angle in degrees * PI / 180
var radians = degrees * Math.PI / 180;
ctx.beginPath();
ctx.strokeStyle = color;
ctx.lineWidth = 30;
//the arc will start from the topmost end
ctx.arc(W / 2, H / 2, 100, 0 - 90 * Math.PI / 180, radians - 90 * Math.PI / 180, false);
ctx.stroke();
//Lets add the text
ctx.fillStyle = color;
ctx.font = "50px bebas";
text = Math.floor(degrees / 360 * 100) + "%";
text_width = ctx.measureText(text).width;
ctx.fillText(text, W / 2 - text_width / 2, H / 2 + 15);
}
function draw() {
//Cancel any movement animation if a new chart is requested
if (typeof animation_loop != undefined) clearInterval(animation_loop);
////time for each frame is 1sec / difference in degrees
animation_loop = setInterval(animate_to, 1000 / difference);
}
//function to make the chart move to new degrees
function animate_to() {
if (degrees == new_degrees)
if (degrees < new_degrees)
degrees++;
else
degrees--;
init();
}
draw();
}
</script>
Can somebody tell me how to change my code.
This is what the javascript shows me when it works.
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.