requestAnimationFrame too fast - javascript

I am creating simple animation in canvas. I use requestanimationframe to control animation. There is 3 circle. But i can only see 3 circle and animation is too fast. My question is how can i slow my animation and how can show each frame. here is my live link.
const swing = (time) => {
for(var i = 0; i < 3; i++) {
circle[i] = new ball();
circle[i].draw(i, circle[i].color);
}
requestAnimationFrame(swing);
}
requestAnimationFrame(swing);
//swing();
function ball(i){
this.x = random(100, 150);
this.y = random(40, 60);
this.radius = 45;
this.color = getRandomColor(random(1, 30));
this.strokeText = "m"
ctx.clearRect(0, 0, el.width, el.height);
this.draw = function(i, color){
ctx.beginPath();
ctx.font="30px Verdana";
ctx.arc(i*this.x, this.y, this.radius, 0, 2*Math.PI, false);
ctx.fillStyle = color;
ctx.globalAlpha = 0.5;
ctx.strokeText(i,i*this.x,this.y);
ctx.fill();
ctx.closePath();
}
}
Thanks in advance.
Edited:- I am creating something similar like this:- http://codepen.io/jscottsmith/pen/oWyxjp?editors=1010

Just a simple example, let three balls doing some circular motion:
// refer below
// http://codepen.io/jscottsmith/pen/oWyxjp?editors=1010
const el = document.getElementById('canvas'),
ctx = el.getContext('2d');
let circle = [];
el.width = document.body.clientWidth;
el.height = document.body.clientHeight;
const getRandomColor = (i) => {
let count = 30,
color = 1,
hue = (i / count * color) * 360;
return `hsla(${hue}, 100%, 50%, 1)`
}
for (var i = 0; i < 3; i++) {
circle[i] = new ball();
}
let angle = 0;
let speed = 0.02;
const swing = (time) => {
ctx.clearRect(0, 0, el.width, el.height);
for (var i = 0; i < 3; i++) {
circle[i].x = circle[i].x + Math.cos(angle) * 1;
circle[i].y = circle[i].y + Math.sin(angle) * 2;
}
for (var i = 0; i < 3; i++) {
circle[i].draw(i, circle[i].color);
}
angle += speed;
requestAnimationFrame(swing);
}
requestAnimationFrame(swing);
//swing();
function ball(i){
this.x = random(100, 150);
this.y = random(40, 60);
this.radius = 45;
this.color = getRandomColor(random(1, 30));
this.strokeText = "m"
this.draw = function(i, color){
ctx.beginPath();
ctx.font="30px Verdana";
ctx.arc(i*this.x, this.y, this.radius, 0, 2*Math.PI, false);
ctx.fillStyle = color;
ctx.globalAlpha = 0.5;
ctx.strokeText(i,i*this.x,this.y);
ctx.fill();
ctx.closePath();
}
}
function random (num1, num2) {
var max = Math.max(num1, num2);
var min = Math.min(num1, num2);
return Math.floor(Math.random() * (max - min + 1)) + min;
}
#canvas {
width: 600px;
height: 600px;
}
<canvas id="canvas"></canvas>

Related

canvas is flickering constantly

I've looked at a few different posts on StackOverflow, but didn't really find the one that solved my issue. The code below works, but it's flickering constantly.
Essentially, I'm just creating a starry background where random stars will fade in and out
var canvas = document.querySelector("canvas");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
var c = canvas.getContext("2d");
function Star(x, y, a, z, size, b) {
this.x = x;
this.y = y;
this.z = z;
this.a = a;
this.size = size;
this.b = b;
this.draw = function () {
c.fillStyle = "rgba(155, 241, 052, 1)";
c.beginPath();
c.arc(this.x, this.y, this.z, 0, Math.PI * 2, false);
c.fill();
};
this.update = function () {
if (this.z > this.size) {
this.a = 0;
}
if (this.z < 0) {
this.a = 1;
}
if (this.a == 1) {
this.z += this.b;
} else {
this.z -= this.b;
}
this.draw();
};
}
var starArray = [];
for (var i = 0; i < 100; i++) {
var size = Math.random() * 3 + 2; //size range
var x = Math.random() * innerWidth; //x coordinate
var y = Math.random() * innerHeight; //y coordinate
var z = Math.random() * size; //star size
var a = 1; //on-off switch for the star to fade in or fade out
var b = Math.random() / 20; //fade-in/fade-out rate (random for each star)
starArray.push(new Star(x, y, a, z, size, b));
}
function animate() {
requestAnimationFrame(animate);
c.clearRect(0, 0, innerWidth, innerHeight);
for (var i = 0; i < starArray.length; i++) {
starArray[i].update();
}
}
animate();
You are providing a negative radius to CanvasRenderingContext2D.arc(). You may need to rethink your logic or use Math.abs to make sure the radius provided is always non-negative.
c.arc(this.x, this.y, Math.abs(this.z), 0, Math.PI * 2, false);
var canvas = document.querySelector("canvas");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
var c = canvas.getContext("2d");
function Star(x, y, a, z, size, b) {
this.x = x;
this.y = y;
this.z = z;
this.a = a;
this.size = size;
this.b = b;
this.draw = function () {
c.fillStyle = "rgba(155, 241, 052, 1)";
c.beginPath();
c.arc(this.x, this.y, Math.abs(this.z), 0, Math.PI * 2, false);
c.fill();
};
this.update = function () {
if (this.z > this.size) {
this.a = 0;
}
if (this.z < 0) {
this.a = 1;
}
if (this.a == 1) {
this.z += this.b;
} else {
this.z -= this.b;
}
this.draw();
};
}
var starArray = [];
for (var i = 0; i < 100; i++) {
var size = Math.random() * 3 + 2; //size range
var x = Math.random() * innerWidth; //x coordinate
var y = Math.random() * innerHeight; //y coordinate
var z = Math.random() * size; //star size
var a = 1; //on-off switch for the star to fade in or fade out
var b = Math.random() / 20; //fade-in/fade-out rate (random for each star)
starArray.push(new Star(x, y, a, z, size, b));
}
function animate() {
requestAnimationFrame(animate);
c.clearRect(0, 0, innerWidth, innerHeight);
for (var i = 0; i < starArray.length; i++) {
starArray[i].update();
}
}
animate();
<canvas></canvas>
You are getting negative radius on the arc call, just do:
c.arc(this.x, this.y, Math.max(this.z, 0), 0, Math.PI * 2, false);

Clickable Canvas Button with Link

I have the following canvas. I want it so that when the user clicks the canvas, I will go to google.com, and I want to keep the button element. This is my code:
//set the variables
var a = document.getElementById('canvas'),
c = a.getContext('2d'),
a.style.width = '200px';
a.style.height = '50px';
area = w * h,
particleNum = 300,
ANIMATION;
var particles = [];
//create the particles
function Particle(i) {
this.id = i;
this.hue = rand(50, 0, 1);
this.active = false;
}
Particle.prototype.build = function() {
this.x = w / 2;
this.y = h / 2;
this.r = rand(7, 2, 1);
this.vx = Math.random() * 10 - 5;
this.vy = Math.random() * 10 - 5;
this.gravity = .01;
this.opacity = Math.random() + .5;
this.active = true;
c.beginPath();
c.arc(this.x, this.y, this.r, 0, 2 * Math.PI, false);
c.fillStyle = "hsla(" + this.hue + ",100%,50%,1)";
c.fill();
};
Particle.prototype.draw = function() {
this.active = true;
this.x += this.vx;
this.y += this.vy;
this.vy += this.gravity;
this.hue -= 0.5;
this.r = Math.abs(this.r - .05);
c.beginPath();
c.arc(this.x, this.y, this.r, 0, 2 * Math.PI, false);
c.fillStyle = "hsla(" + this.hue + ",100%,50%,1)";
c.fill();
// reset particle
if(this.r <= .05) {
this.active = false;
}
};
//functionality
function drawScene() {
c.fillStyle = "black";
c.fillRect(0,0,w,h);
for(var i = 0; i < particles.length; i++) {
if(particles[i].active === true) {
particles[i].draw();
} else {
particles[i].build();
}
}
ANIMATION = requestAnimationFrame(drawScene);
}
function initCanvas() {
var s = getComputedStyle(a);
if(particles.length) {
particles = [];
cancelAnimationFrame(ANIMATION);
ANIMATION;
console.log(ANIMATION);
}
w = a.width = window.innerWidth;
h = a.height = window.innerHeight;
for(var i = 0; i < particleNum; i++) {
particles.push(new Particle(i));
}
drawScene();
console.log(ANIMATION);
}
//init
(function() {
initCanvas();
addEventListener('resize', initCanvas, false);
})();
//helper functions
function rand(max, min, _int) {
var max = (max === 0 || max)?max:1,
min = min || 0,
gen = min + (max - min) * Math.random();
return (_int) ? Math.round(gen) : gen;
};
#canvas{
width: 200;
height: 50;
}
<div class="wrapper">
<a href="index.html">
<button align=center onclick="handleClick()">
<canvas width="200" height="50" id="canvas" align=center></canvas>
<span class="text">SUBMIT</span>
</button>
</a>
</div>
Although, I only see the button, and no the canvas. How can I fix this?
You got a lot of errors actually buddy (variable declaration is the biggest problem) but by following the errors will give you a way to fix it, I don't know if this is the fix you want.
//set the variables
var a = document.getElementById('canvas'),
c = a.getContext('2d');
a.style.width = '200px';
a.style.height = '50px';
var w, h;
var area = w * h,
particleNum = 300,
ANIMATION;
var particles = [];
//create the particles
function Particle(i) {
this.id = i;
this.hue = rand(50, 0, 1);
this.active = false;
}
Particle.prototype.build = function() {
this.x = w / 2;
this.y = h / 2;
this.r = rand(7, 2, 1);
this.vx = Math.random() * 10 - 5;
this.vy = Math.random() * 10 - 5;
this.gravity = 0.01;
this.opacity = Math.random() + .5;
this.active = true;
c.beginPath();
c.arc(this.x, this.y, this.r, 0, 2 * Math.PI, false);
c.fillStyle = "hsla(" + this.hue + ",100%,50%,1)";
c.fill();
};
Particle.prototype.draw = function() {
this.active = true;
this.x += this.vx;
this.y += this.vy;
this.vy += this.gravity;
this.hue -= 0.5;
this.r = Math.abs(this.r - 0.05);
c.beginPath();
c.arc(this.x, this.y, this.r, 0, 2 * Math.PI, false);
c.fillStyle = "hsla(" + this.hue + ",100%,50%,1)";
c.fill();
// reset particle
if (this.r <= 0.05) {
this.active = false;
}
};
//functionality
function drawScene() {
c.fillStyle = "black";
c.fillRect(0, 0, w, h);
for (var i = 0; i < particles.length; i++) {
if (particles[i].active === true) {
particles[i].draw();
} else {
particles[i].build();
}
}
ANIMATION = requestAnimationFrame(drawScene);
}
function initCanvas() {
var s = getComputedStyle(a);
if (particles.length) {
particles = [];
cancelAnimationFrame(ANIMATION);
ANIMATION;
console.log(ANIMATION);
}
w = a.width = window.innerWidth;
h = a.height = window.innerHeight;
for (var i = 0; i < particleNum; i++) {
particles.push(new Particle(i));
}
drawScene();
console.log(ANIMATION);
}
//init
(function() {
initCanvas();
addEventListener('resize', initCanvas, false);
})();
//helper functions
function rand(max, min, _int) {
var max = (max === 0 || max) ? max : 1,
min = min || 0,
gen = min + (max - min) * Math.random();
return (_int) ? Math.round(gen) : gen;
};
#canvas {
width: 200px;
height: 50px;
}
<div class="wrapper">
<a href="index.html">
<button align=center onclick="handleClick()">
<canvas width="200" height="50" id="canvas" align=center> </canvas>
<span class="text">SUBMIT</span>
</button>
</a>
</div>

How to add random shapes on click using canvas animation

For this animation On click I need a different shapes to be made I need 5 different shapes in total. Also Ive had a hard time doing these things,
add a random motion vector to every circle
add an interval timer that redraws the background and each circle in its new position every 30 milliseconds
Check if any circle is outside the canvas width and height, and if so reverse its direction back onto the screen
also maybe If I can have some random text to fade in and fade out every couple of seconds too
The code...
var canvas;
var context;
var circles = [];
var timer;
function Circle(x, y, color) {
this.x = x;
this.y = y;
this.dx = Math.random() * 4 - 2;
this.dy = Math.random() * 4 - 2;
this.color = color;
}
function init() {
canvas = document.getElementById('canvas');
context = canvas.getContext("2d");
window.addEventListener('resize', resizeCanvas, false);
window.addEventListener('orientationchange', resizeCanvas, false);
resizeCanvas();
canvas.onclick = function (event) {
handleClick(event.clientX, event.clientY);
};
timer = setInterval(resizeCanvas, 20);
}
function handleClick(x, y) {
var found = false;
for (var i = 0; i < circles.length; i++) {
d = Math.sqrt((circles[i].x - x) * (circles[i].x - x) + (circles[i].y - y) * (circles[i].y - y));
if (d <= 30) {
circles.splice(i, 1);
found = true;
}
}
fillBackgroundColor();
if (!found) {
var colors = ["red", "green", "blue", "orange", "purple", "yellow"];
var color = colors[Math.floor(Math.random() * colors.length)];
circles.push(new Circle(x, y, color));
}
for (var i = 0; i < circles.length; i++) {
drawCircle(circles[i]);
}
}
function drawCircle(circle) {
context.beginPath();
context.arc(circle.x, circle.y, 30, 0, degreesToRadians(360), true);
context.fillStyle = circle.color;
context.fill();
if (circle.x + circle.dx > canvas.width || circle.x + circle.dx < 0)
circle.dx = -circle.dx;
if (circle.y + circle.dy > canvas.height || circle.y + circle.dy < 0)
circle.dy = -circle.dy;
circle.x += circle.dx;
circle.y += circle.dy;
}
function resizeCanvas() {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
fillBackgroundColor();
for (var i = 0; i < circles.length; i++) {
drawCircle(circles[i]);
}
}
function fillBackgroundColor() {
//var colors = ["white", "yellow", "blue", "red"];
//var bgColor = colors[Math.floor(Math.random() * colors.length)];
context.fillStyle = 'black';
context.fillRect(0, 0, canvas.width, canvas.height);
}
function degreesToRadians(degrees) {
//converts from degrees to radians and returns
return (degrees * Math.PI) / 180;
}
window.onload = init;
<canvas id='canvas' width=500 height=500></canvas>

How to make canvas particles follow mouse with JS?

I want to make the particles follow the mouse and I am not sure on how to do that.
I figured I can replace the x and y with the mouses position but I can figure that out either.
I would appreciate an almost exact answer and not examples please.
window.onload = function() {
var canvas = document.createElement("canvas"),
c = canvas.getContext("2d"),
particles = {}
particleIndex = 0,
particleNum = Math.random() * 2;
canvas.width = 400;
canvas.height = 400;
document.body.appendChild(canvas);
c.fillStyle = "black";
c.fillRect(0, 0, canvas.width, canvas.height);
function Particle() {
this.x = canvas.width / 10;
this.y = canvas.height / 2;
this.vx = Math.random() * 10 - 5;
this.vy = Math.random() * 10 - 5;
this.gravity = .2;
particleIndex++;
particles[particleIndex] = this;
this.id = particleIndex;
this.life = 0;
this.maxLife = Math.random() * 30 + 10;
this.color = "rgb(" + parseInt(Math.random() * 255, 10) + ",0,0)";
this.color2 = "hsl(" + parseInt(Math.random() * 255, 10) + ",50%,50%)";
}
Particle.prototype.draw = function() {
this.x += this.vx;
this.y += this.vy;
if (Math.random() < 0.1) {
this.vx = Math.random() * 10 - 5;
this.vy = Math.random() * 10 - 5;
}
this.vy += this.gravity;
this.life++;
if (this.Life >= this.maxLife) {
delete particles[this.id];
}
c.fillStyle = this.color2;
c.fillRect(this.x, this.y, 10, 10);
};
//var p = new Particle();
setInterval(function() {
c.fillStyle = "rgba(0,0,0,0.5)";
c.fillRect(0, 0, canvas.width, canvas.height);
for (var i in particles) {
particles[i].draw();
}
for (var i = 0; i < particleNum; i++) {
new Particle();
}
}, 30);
};

Drawing triangles on each piece of a canvas pie graph to make arrows

Using canvas, I have to take some data that is used to create a pie graph, and turn that pie graph into a circle of arrows.
So far the pie graph is simple, and cutting out the middle is easy. But can't figure out how to
get the x, y points of each end point of the pie peices.
use that to somehow draw a triangle, and
continue onto the next pie piece.
What I do have is the x, y of the center point of the circle, and the radius.
I can draw 1 triangle -
var friends=alumni=hopefuls=athletes=0,
data = ['Ahtlete', 'Athlete', 'Friend', 'Friend', 'Athlete'];
test = data.length;
for (var i = 0; i < test; i++){
if ( data[i] == "Athelete" ) {
athletes++;
} else if ( data[i] == "Friend"){
friends++;
} else if (data[i] == "Hopeful" ){
hopefuls++;
} else if (data[i] == "Alumni"){
alumni++
}
}
var mychart = new AwesomeChart('segmented-circle');
//friends, alumni, hopefuls, athletes;
mychart.colors = ['#d20007','#02f2fb', '#d2ebf6', '#0554ff']
mychart.title = "";
mychart.data = [friends, alumni, hopefuls, athletes];
mychart.labels = [];
mychart.chartType = 'ring';
mychart.draw();
function AwesomeChart(canvasElementId){
var canvas = document.getElementById(canvasElementId);
this.ctx = canvas.getContext('2d');
this.width = this.ctx.canvas.width;
this.height = this.ctx.canvas.height;
this.numberOfDecimals = 0;
this.proportionalSizes = true;
this.widthSizeFactor = this.width/400;
this.heightSizeFactor = this.height/400;
this.chartType = 'bar';
this.randomColors = false;
this.marginTop = 10;
this.marginBottom = 10;
this.marginLeft = 20;
this.marginRight = 50;
this.labelMargin = 10;
this.dataValueMargin = 20;
this.titleMargin = 10;
this.yAxisLabelMargin = 5;
this.data = new Array();
this.labels = new Array();
this.colors = new Array();
this.title = null;
this.backgroundFillStyle = 'rgba(255,255,255,0)';
this.borderStrokeStyle = 'rgba(255,255,255,0)';
this.borderWidth = 0;
this.labelFillStyle = 'rgb(220, 36, 0)';
this.labelFont = 'sans-serif';
this.labelFontHeight = 12;
this.labelFontStyle = '';
this.dataValueFillStyle = '#333';
this.dataValueFont = 'sans-serif';
this.dataValueFontHeight = 15;
this.dataValueFontStyle = '';
this.titleFillStyle = '#333';
this.titleFont = 'sans-serif';
this.titleFontHeight = 16;
this.titleFontStyle = 'bold';
this.yAxisLabelFillStyle = '#333';
this.yAxisLabelFont = 'sans-serif';
this.yAxisLabelFontHeight = 10;
this.yAxisLabelFontStyle = '';
var lingrad = this.ctx.createLinearGradient(0,0,0,this.height);
lingrad.addColorStop(0.2, '#fdfdfd');
lingrad.addColorStop(0.8, '#ededed');
this.chartBackgroundFillStyle = lingrad;
this.chartBorderStrokeStyle = '#999';
this.chartBorderLineWidth = 1;
this.chartHorizontalLineStrokeStyle = '#999';
this.chartHorizontalLineWidth = 1;
this.chartVerticalLineStrokeStyle = '#999';
this.chartVerticalLineWidth = 1;
this.chartMarkerSize = 5;
this.chartPointRadius = 4;
this.chartPointFillStyle = 'rgb(150, 36, 0)';
this.chartLineStrokeStyle = 'rgba(150, 36, 0, 0.5)';
this.chartLineWidth = 2;
this.barFillStyle = 'rgb(220, 36, 0)';
this.barStrokeStyle = '#fff';
this.barBorderWidth = 2.0;
this.barShadowColor = 'rgba(0, 0, 0, 0.5)';
this.barShadowBlur = 5;
this.barShadowOffsetX = 3.0;
this.barShadowOffsetY = 0.0;
this.barHGap = 20;
this.barVGap = 20;
this.explosionOffset = 20;
this.pieFillStyle = 'rgb(220, 36, 0)';
this.pieStrokeStyle = '#fff';
this.pieBorderWidth = 2.0;
this.pieShadowColor = 'rgba(255, 255, 255, 0.8)';
this.pieShadowBlur = 15;
this.pieShadowOffsetX = 0.0;
this.pieShadowOffsetY = 0.0;
this.pieStart = 0;
this.pieTotal = null;
this.generateRandomColor = function(){
var rgb = new Array();
for(var i=0; i<3; i++){
rgb.push(Math.ceil(Math.random()*150 + 50));
}
return 'rgb('+rgb.join(",")+')';
}
this.draw = function(){
var context = this.ctx;
context.lineCap = 'round';
var minFactor = Math.min(this.widthSizeFactor, this.heightSizeFactor);
if(this.proportionalSizes){
this.labelMargin = this.labelMargin * this.heightSizeFactor;
this.dataValueMargin = this.dataValueMargin * this.heightSizeFactor;
this.titleMargin = this.titleMargin * this.heightSizeFactor;
this.yAxisLabelMargin = this.yAxisLabelMargin * this.heightSizeFactor;
this.labelFontHeight = this.labelFontHeight * minFactor;
this.dataValueFontHeight = this.dataValueFontHeight * minFactor;
this.titleFontHeight = this.titleFontHeight * minFactor;
this.yAxisLabelFontHeight = this.yAxisLabelFontHeight * minFactor;
this.barHGap = this.barHGap * this.widthSizeFactor;
this.barVGap = this.barHGap * this.heightSizeFactor;
this.explosionOffset = this.explosionOffset * minFactor;
}
if(this.randomColors){
for(var i=0; i<this.data.length; i++){
if(!this.colors[i]){
this.colors[i] = this.generateRandomColor();
}
}
}
this.drawPieChart(true);
//Draw the outer border:
context.lineWidth = this.borderWidth;
context.strokeStyle = this.borderStrokeStyle;
context.strokeRect(0, 0, this.width, this.height);
context.globalCompositeOperation = 'destination-over';
//Fill the background:
context.fillStyle = this.backgroundFillStyle;
context.fillRect(0, 0, this.width, this.height);
context.globalCompositeOperation = 'source-over';
}
this.drawPieChart = function(ring){
var context = this.ctx;
context.lineWidth = this.pieBorderWidth;
var dataSum = 0;
if(this.pieTotal == null){
var len = this.data.length;
for (var i = 0; i < len; i++){
dataSum += this.data[i];
if(this.data[i]<0){
return;
}
}
}else{
dataSum = this.pieTotal;
}
var pieAreaWidth = this.width - this.marginLeft - this.marginRight;
var pieAreaHeight = this.height - this.marginTop - this.marginBottom;
var centerX = this.width / 2;
var centerY = this.marginTop + (pieAreaHeight / 2);
var doublePI = 2 * Math.PI;
var radius = (Math.min( pieAreaWidth, pieAreaHeight) / 2);
var maxLabelWidth = 0;
var labelWidth = 0;
context.font = this.labelFontStyle + ' ' + this.labelFontHeight + 'px '+ this.labelFont;
for (var i = 0; i < this.labels.length; i++){
labelWidth = context.measureText(this.labels[i]).width;
if(labelWidth > maxLabelWidth){
maxLabelWidth = labelWidth;
}
}
radius = radius - maxLabelWidth - this.labelMargin;
var startAngle = this.pieStart * doublePI / dataSum;
var currentAngle = startAngle;
var endAngle = 0;
var incAngleBy = 0;
for (var i = 0; i < this.data.length; i++){
context.beginPath();
incAngleBy = this.data[i] * doublePI / dataSum;
endAngle = currentAngle + incAngleBy;
// Draw pie graph then using same calculations
// draw an isoceles triangle at end points before the center
// is cut out to make the arrows
context.moveTo(centerX, centerY);
context.arc(centerX, centerY, radius, currentAngle, endAngle, false);
context.lineTo(centerX, centerY);
var twidth = 15; // Triangle Width
var theight = 20; // Triangle Height
context.moveTo(centerX+radius/2, centerY+radius/2);
context.lineTo(centerX+radius, centerY+radius);
context.lineTo(centerX+radius-10, centerY+radius/3);
context.lineTo(centerX, centerY);
/*
var width = 15; // Triangle Width
var height = 20; // Triangle Height
var padding = endAngle;
context.save();
context.moveTo(centerX, dataSum);
context.arc(centerX *2, dataSum, 5, 0, doublePI, false);
context.moveTo(padding + width / 2, padding); // Top Corner
context.lineTo(padding + width, height + padding); // Bottom Right
context.lineTo(centerX , height + padding); // Bottom Left
*/
currentAngle = endAngle;
if (this.colors[i]){
context.fillStyle = this.colors[i];
}else{
context.fillStyle = this.pieFillStyle;
}
context.fill();
context.strokeStyle = this.pieStrokeStyle;
context.stroke();
}
//Draw the outer shadow:
context.save();
context.shadowOffsetX = this.pieShadowOffsetX;
context.shadowOffsetY = this.pieShadowOffsetY;
context.translate(centerX, centerY);
//context.rotate(this.pieStart* doublePI / dataSum);
context.beginPath();
context.moveTo(0, 0);
context.arc(0, 0, radius, startAngle, endAngle, false);
context.shadowBlur = this.pieShadowBlur;
context.shadowColor = this.pieShadowColor;
context.globalCompositeOperation = 'destination-over';
context.fillStyle = 'rgba(0,0,0,1.0)';
context.fill();
context.restore();
//Ring-charts:
if(ring){
// "cut" the central part:
context.save();
var ringCenterRadius = radius / 1.15;
context.beginPath();
context.moveTo(centerX + ringCenterRadius, centerY);
context.arc(centerX, centerY, ringCenterRadius, 0, doublePI, false);
// context.globalCompositeOperation = 'destination-out';
context.fillStyle = '#000';
context.fill();
context.restore();
// draw the ring's inner shadow below the ring:
context.save();
context.shadowOffsetX = this.pieShadowOffsetX;
context.shadowOffsetY = this.pieShadowOffsetY;
context.translate(centerX, centerY);
context.beginPath();
// added -1 to make inner border same width as outer
context.arc(0, 0, ringCenterRadius -1, startAngle, endAngle, false);
context.shadowBlur = this.pieShadowBlur;
context.shadowColor = this.pieShadowColor;
context.globalCompositeOperation = 'destination-over';
context.strokeStyle = this.pieStrokeStyle;
context.stroke();
context.restore();
}
// draw the labels:
var currentAngle = this.pieStart* doublePI / dataSum;
var endAngle = 0;
var incAngleBy = 0;
context.beginPath();
for(var i=0; i<this.data.length; i++){
context.save();
incAngleBy = this.data[i] * doublePI / dataSum;
endAngle = currentAngle + incAngleBy;
var mAngle = currentAngle + incAngleBy/2;
context.translate(centerX, centerY);
context.rotate(mAngle);
context.font = this.labelFontStyle + ' ' + this.labelFontHeight + 'px '+ this.labelFont;
if(this.colors[i]){
context.fillStyle = this.colors[i];
}else{
context.fillStyle = this.labelFillStyle;
}
context.textAlign = 'start';
if(this.labels[i]){
if( (currentAngle>Math.PI/2) && (currentAngle<=3*(Math.PI/2)) ){
var translateXBy = radius + this.labelMargin + context.measureText(this.labels[i]).width / 2;
context.translate(translateXBy, 0);
context.rotate(Math.PI);
context.translate(-translateXBy, 0);
}
context.textBaseline = 'middle';
context.fillText(this.labels[i], radius+this.labelMargin, 0);
}
context.restore();
currentAngle = endAngle;
}
}
}
canvas {
background: #000033;
}
<canvas id='segmented-circle' width='200' height='200'></canvas>
I have tried several different things and feel like this would be a great thing to ask here.
The last one here is how it should look in the end.

Categories

Resources