discord/js and angle of arc function - javascript

Example:
Try to get a handle on Arc and I'm running into a wall trying to figure out the end angle. I need something simple so can feed it a percentage and it make an arc that that's percent of a circle.
I got the arc to start at the top and I know math.pi*2 will get me all the way around but when I try to modify that with the old *0.p trick of a converted percentage I get this.
white is 0.1/10%
red is 0.95/95%
green is 0.5/50%
blue is 0.7/70%
but none of them look like that and I just can't figure out the way it's figuring the arc.
var radius = 250 / 2 - 5;
var centerx = 250 / 2;
var centery = 250 / 2;
const startagle = Math.PI * 1.5;
var endagle = (Math.PI * 2)*0.1;
context.beginPath();
context.fillStyle = 'white';
context.arc(centerx, centery, radius, startagle, endagle, false);
context.lineTo(centerx, centery);
context.fill();
context.closePath();
var endagle = (Math.PI * 2)*0.95;
context.beginPath();
context.fillStyle = 'red';
context.arc(centerx, centery, radius-5, startagle, endagle, false);
context.lineTo(centerx, centery);
context.fill();
context.closePath();
var endagle = (Math.PI * 2)*0.5;
context.beginPath();
context.fillStyle = 'green';
context.arc(centerx, centery, radius-10, startagle, endagle, false);
context.lineTo(centerx, centery);
context.fill();
context.closePath();
var endagle = (Math.PI * 2)*0.7;
context.beginPath();
context.fillStyle = 'blue';
context.arc(centerx, centery, radius-15, startagle, endagle, false);
context.lineTo(centerx, centery);
context.fill();
context.closePath();
context.beginPath();
context.arc(centerx, centery, radius-20, 0, 360, false);
context.closePath();
context.clip();
const avatar = await Canvas.loadImage('https://i.imgur.com/lleYAsg.png');
context.drawImage(avatar, 10, 10, 250, 250);
Finalized/Fixed code
const Canvas = require('canvas');
var canvas = Canvas.createCanvas(700, 250);
var context = canvas.getContext('2d');
const background = await Canvas.loadImage('./images/photo-1538370965046-79c0d6907d47.jpg');
context.drawImage(background, 0, 0, canvas.width, canvas.height);
context.strokeStyle = '#0099ff';
context.strokeRect(0, 0, canvas.width, canvas.height);
var answers = [
"Red Ranger",
"Blue Ranger",
"Yellow Ranger",
"Pink Ranger",
"Green Ranger",
"Black Ranger",
"Orange Ranger",
"Violet Ranger",
"White Ranger",
"Silver Ranger",
"Gold Ranger",
"Bronze Ranger",
"Brown Ranger",
"Extra Hero",
"Meta Hero",
"Rider",
"Ultra",
"Kaiju"
];
var stats = [
Math.floor(Math.random() * 99),
Math.floor(Math.random() * 99),
Math.floor(Math.random() * 99),
Math.floor(Math.random() * 99),
Math.floor(Math.random() * 99),
Math.floor(Math.random() * 99),
Math.floor(Math.random() * 99),
Math.floor(Math.random() * 99),
Math.floor(Math.random() * 99)
];
var toonnamelist = [
"Evelyn Leon",
"Salvador Knight",
"Alyson Hensley",
"Tobias Harvey",
"Selah Frazier",
"Morgan Ward",
"Ronald Shepherd",
"Miriam Moody",
"Maren Gallagher",
"Alexia Crawford",
"Aliya Weiss",
"Jan Garrison"
];
var toonavatars = [
"https://i.imgur.com/lleYAsg.png",
"https://i.imgur.com/0x008b.png",
"https://i.imgur.com/ESPP3b.png",
"https://i.imgur.com/qv7cvb.png",
"https://i.imgur.com/VuYRAb.png",
"https://i.imgur.com/RB6lSb.png",
"https://i.imgur.com/hMlrIb.png",
"https://i.imgur.com/mLuRIb.png",
"https://i.imgur.com/QVQ7mb.png",
"https://i.imgur.com/IXEuqb.png",
"https://i.imgur.com/CgMlpb.png",
"https://i.imgur.com/vO008b.png"
];
var randomrank = answers[Math.floor(Math.random() * answers.length)];
var randomavy = toonavatars[Math.floor(Math.random() * toonavatars.length)];
var toonname = `${msg.member.displayName}`;
toonname = toonnamelist[Math.floor(Math.random() * toonnamelist.length)];;
var toonlevel = Math.floor(Math.random() * 99);
var toonrank = randomrank;
var curentexp = Math.floor(Math.random() * 9999);
var maxexp = Math.floor(Math.random() * 9999);
if (curentexp > maxexp){curentexp = maxexp;}
const cFont = context.font;
var fontArgs = context.font.split(' ');
var newSize = '30px';
context.font = newSize + ' ' + fontArgs[fontArgs.length - 1];
context.fillText(toonname, 250, 50);
fontArgs = context.font.split(' ');
newSize = '20px';
context.font = newSize + ' ' + fontArgs[fontArgs.length - 1];
context.fillText(`Level: `+toonlevel, 250, 80);
context.fillText(`Rank: `+toonrank, 350, 80);
context.font = '30px monospace';
context.fillText(`S:`+stats[0], 250, 170);
context.fillText(`P:`+stats[1], 355, 170);
context.fillText(`E:`+stats[2], 450, 170);
context.fillText(`W:`+stats[3], 250, 200);
context.fillText(`I:`+stats[4], 355, 200);
context.fillText(`L:`+stats[5], 450, 200);
context.fillText(`A:`+stats[6], 250, 230);
context.fillText(`F:`+stats[7], 355, 230);
context.fillText(`R:`+stats[8], 450, 230);
var recx = 250;
var recy = 90;
var recw = 300;
var rech = 40;
context.fillStyle = 'grey';
context.strokeStyle = 'silver';
context.lineWidth = '3';
context.beginPath();
context.fillRect(recx, recy, recw*(curentexp/maxexp), rech);
context.strokeRect(recx, recy, recw, rech);
context.fillStyle = 'white';
context.font = '20px sans-serif';
context.fillText('XP: '+curentexp+'/'+maxexp, 260, recy+28);
context.closePath();
let strokeWidth = 5;
var radius = 250 / 2 - strokeWidth;
let center = {
x: 250 / 2,
y: 250 / 2,
};
//var centerX = 250 / 2;
//var centerY = 250 / 2;
//const fullCircle = Math.PI * 2;
//const startAngle = Math.PI * 1.5;
//let endAngle;
let sectors = [
{ color: 'white', size: 0.1 },
{ color: 'crimson', size: 0.95 },
{ color: 'springgreen', size: 0.5 },
{ color: 'dodgerblue', size: 0.7 },
];
function drawSector({ context, color, center, radius, size }) {
let startAngle = Math.PI * 1.5;
let endAngle = startAngle + Math.PI * 2 * size;
context.beginPath();
context.fillStyle = color;
context.arc(center.x, center.y, radius, startAngle, endAngle);
context.lineTo(center.x, center.y);
context.fill();
context.closePath();
}
sectors.forEach(({ color, size }, i) => drawSector({
context, color, center, radius: radius - i * strokeWidth, size
}));
const conditionx = 575;
const conditiony = 5;
const conditionw = 125;
const conditionh = 250;
var conditionpic1 = await Canvas.loadImage('https://maskedriders.info/Mee6RP/PaperDoll/White_Base/NekollxComm_BaseV2ArmS1_White.png');
var conditionpic2 = await Canvas.loadImage('https://maskedriders.info/Mee6RP/PaperDoll/White_Base/NekollxComm_BaseV2ArmS2_White.png');
var conditionpic3 = await Canvas.loadImage('https://maskedriders.info/Mee6RP/PaperDoll/White_Base/NekollxComm_BaseV2Head_White.png');
var conditionpic4 = await Canvas.loadImage('https://maskedriders.info/Mee6RP/PaperDoll/White_Base/NekollxComm_BaseV2Torso_White.png');
var conditionpic5 = await Canvas.loadImage('https://maskedriders.info/Mee6RP/PaperDoll/White_Base/NekollxComm_BaseV2LegS1_White.png');
var conditionpic6 = await Canvas.loadImage('https://maskedriders.info/Mee6RP/PaperDoll/White_Base/NekollxComm_BaseV2LegS2_White.png');
var conditionpic3 = await Canvas.loadImage('https://maskedriders.info/Mee6RP/PaperDoll/White_Adjustments/CatPeople/NekollxComm2_CatHead_F_White.png');
var conditionpic7 = await Canvas.loadImage('https://maskedriders.info/Mee6RP/PaperDoll/White_Adjustments/CatPeople/NekollxComm2_CatTail_F_White.png');
context.drawImage(conditionpic1, conditionx, conditiony, conditionw, conditionh);
context.drawImage(conditionpic2, conditionx, conditiony, conditionw, conditionh);
context.drawImage(conditionpic3, conditionx, conditiony, conditionw, conditionh);
context.drawImage(conditionpic4, conditionx, conditiony, conditionw, conditionh);
context.drawImage(conditionpic5, conditionx, conditiony, conditionw, conditionh);
context.drawImage(conditionpic6, conditionx, conditiony, conditionw, conditionh);
context.drawImage(conditionpic7, conditionx, conditiony, conditionw, conditionh);
context.beginPath();
context.arc(center.x, center.y, radius - sectors.length * strokeWidth, 0, 360, false);
context.closePath();
context.clip();
const avatar = await Canvas.loadImage(randomavy);
context.drawImage(avatar, 10, 10, 250, 250);

It's because you forgot that you changed the starting angle. You need to make the angle, at which the arc ends, to be relative to the starting angle. So if you increase the value by the starting value it will work as expected:
// ** For this demo only ** //
const canvas = document.querySelector('canvas');
const context = canvas.getContext('2d');
canvas.height = 250;
canvas.width = 250;
context.fillStyle = 'dimgray';
context.fillRect(0, 0, canvas.width, canvas.height);
// ** End ** //
const radius = canvas.width / 2 - 5;
const centerX = canvas.width / 2;
const centerY = canvas.height / 2;
const fullCircle = Math.PI * 2;
const startAngle = Math.PI * 1.5;
let endAngle;
endAngle = startAngle + fullCircle * 0.1;
context.beginPath();
context.fillStyle = 'white';
context.arc(centerX, centerY, radius, startAngle, endAngle, false);
context.lineTo(centerX, centerY);
context.fill();
context.closePath();
endAngle = startAngle + fullCircle * 0.95;
context.beginPath();
context.fillStyle = 'crimson';
context.arc(centerX, centerY, radius - 5, startAngle, endAngle, false);
context.lineTo(centerX, centerY);
context.fill();
context.closePath();
endAngle = startAngle + fullCircle * 0.5;
context.beginPath();
context.fillStyle = 'springgreen';
context.arc(centerX, centerY, radius - 10, startAngle, endAngle, false);
context.lineTo(centerX, centerY);
context.fill();
context.closePath();
endAngle = startAngle + fullCircle * 0.7;
context.beginPath();
context.fillStyle = 'dodgerblue';
context.arc(centerX, centerY, radius - 15, startAngle, endAngle, false);
context.lineTo(centerX, centerY);
context.fill();
context.closePath();
context.beginPath();
context.arc(centerX, centerY, radius - 20, 0, 360, false);
context.closePath();
context.clip();
// ** For this demo only ** //
let url = 'https://i.imgur.com/lleYAsg.png';
let img = new Image();
new Promise((resolve) => (img.onload = resolve), (img.src = url)).then(() =>
context.drawImage(img, 10, 10, 250, 250),
);
body {
align-items: center;
background-color: dimgray;
display: flex;
justify-content: center;
margin: 0;
min-height: 100vh;
}
<canvas></canvas>
It works as expected; however, you could also simplify the way you create the sectors. I would write a function to draw these (drawSector) and store the colours and sizes in an array (sectors).
// ** For this demo only ** //
let canvas = document.querySelector('canvas');
let context = canvas.getContext('2d');
canvas.height = 250;
canvas.width = 250;
context.fillStyle = '#232425';
context.fillRect(0, 0, canvas.width, canvas.height);
// ** End ** //
let center = {
x: canvas.width / 2,
y: canvas.height / 2,
};
let strokeWidth = 5;
let radius = canvas.width / 2 - strokeWidth;
let sectors = [
{ color: 'white', size: 0.1 },
{ color: 'crimson', size: 0.95 },
{ color: 'springgreen', size: 0.5 },
{ color: 'dodgerblue', size: 0.7 },
];
function drawSector({ context, color, center, radius, size }) {
let startAngle = Math.PI * 1.5;
let endAngle = startAngle + Math.PI * 2 * size;
context.beginPath();
context.fillStyle = color;
context.arc(center.x, center.y, radius, startAngle, endAngle);
context.lineTo(center.x, center.y);
context.fill();
context.closePath();
}
sectors.forEach(({ color, size }, i) => drawSector({
context, color, center, radius: radius - i * strokeWidth, size
}));
context.beginPath();
context.arc(center.x, center.y, radius - sectors.length * strokeWidth, 0, 360);
context.closePath();
context.clip();
// ** For this demo only ** //
let url = 'https://i.imgur.com/lleYAsg.png';
let img = new Image();
new Promise((resolve) => (img.onload = resolve), (img.src = url)).then(() =>
context.drawImage(img, 10, 10, 250, 250),
);
body {
align-items: center;
background-color: #232425;
display: flex;
justify-content: center;
margin: 0;
min-height: 100vh;
}
<canvas></canvas>

Related

How i can create a curved text in qml canvas element?

i want to create a curved text in qml it's possible? Is there a javascript library that i can import to do it?
My idea is that it's possible maybe with canvas element but i don't know how i can do it... it's a good idea??
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
Canvas{
anchors.fill: parent
onPaint: {
var ctx = getContext("2d");
ctx.fillStyle = Qt.rgba(1, 0, 0, 1);
ctx.fillRect(0, 0, width, height);
//how i can create curved text???
}
}
}
Hello I tried the code into the link posted by #folibis , work perfectly!!!
This is the code :
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
Canvas{
property string nameFont: webFont.name
function drawTextAlongArc(context, str, centerX, centerY, radius, angle)
{
context.save();
context.translate(centerX, centerY);
context.rotate(-1 * angle / 2);
context.rotate(-1 * (angle / str.length) / 2);
for (var n = 0; n < str.length; n++) {
context.rotate(angle / str.length);
context.save();
context.translate(0, -1 * radius);
var char1 = str[n];
context.fillText(char1, 0, 0);
context.restore();
}
context.restore();
}
anchors.fill: parent
onPaint: {
var ctx = getContext("2d");
ctx.fillStyle = Qt.rgba(1, 1, 1, 1);
ctx.fillRect(0, 0, width, height);
ctx.font='50px Verdana'
//ctx.font = '30px Courier New'
ctx.textAlign = "center";
var centerX = width / 2;
var centerY = height/2; //height - 30;
var angle = Math.PI * 0.8; // radians
var radius = 180;
ctx.fillStyle="#000000"
drawTextAlongArc(ctx, "Hello World", centerX, centerY, radius, angle);
}
}
}

Javascript unwanted lines connecting moving arcs

So i have this basic script which makes 4 circles move around a centre, and I have put in two circles which are the route which the circles follow.. The problem is that there's odd unwanted lines joining the circles to the stationary one's. I think it may be because the line for the circles ctx.arc(cx, cy, 200, 200, 0, 2 * Math.PI); is within the draw function. Does anyone know how to solve this? (Placing the stationary circles outside the draw function causes them to disappear when the canvas is cleared.
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var w = canvas.width;
var h = canvas.height;
var dd = 3;
var dd2 = 3;
var dd3 = 3;
var dd4 = 3;
var angle = 0;
var angle2 = 0;
var angle3 = 0;
var angle4 = 0;
var cx = 1000;
var cy = 1000;
var radius = 200;
var radius2 = 300;
var radius3 = 400;
var radius4 = 500;
var fps = 100;
ctx.fillStyle = "yellow";
ctx.strokeStyle = "skyblue";
(function () {
"use strict";
function draw(x, y) {
ctx.save();
ctx.clearRect(0, 0, w, h);
ctx.beginPath();
ctx.arc(cx, cy, 75, 75, 0, 2 * Math.PI);
ctx.fillStyle = "lightgray";
ctx.arc((x - 50 / 2) + 25, (y - 30 / 2) + 15, 25, 25, 0, 2 * Math.PI);
ctx.arc(cx, cy, 200, 200, 0, 2 * Math.PI);
ctx.stroke();
ctx.closePath();
ctx.restore();
}
function draw1(x1, y1) {
ctx.save();
ctx.beginPath();
ctx.fillStyle = "orange";
ctx.arc((x1 - 50 / 2) + 25, (y1 - 30 / 2) + 15, 25, 25, 0, 2 * Math.PI);
ctx.arc(cx, cy, 300, 300, 0, 2 * Math.PI);
ctx.stroke();
ctx.closePath();
ctx.restore();
}
function draw2(x2, y2) {
ctx.save();
ctx.beginPath();
ctx.fillStyle = "blue";
ctx.arc((x2 - 50 / 2) + 25, (y2 - 30 / 2) + 15, 25, 25, 0, 2 * Math.PI);
ctx.arc(cx, cy, 400, 400, 0, 2 * Math.PI);
ctx.stroke();
ctx.closePath();
ctx.restore();
}
function draw3(x3, y3) {
ctx.save();
ctx.beginPath();
ctx.fillStyle = "red";
ctx.arc((x3 - 50 / 2) + 25, (y3 - 30 / 2) + 15, 25, 25, 0, 2 * Math.PI);
ctx.arc(cx, cy, 500, 500, 0, 2 * Math.PI);
ctx.stroke();
ctx.closePath();
ctx.restore();
}
window.requestAnimFrame = (function (callback) {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function (callback) {
window.setTimeout(callback, 1000 / fps);
};
}());
function animate() {
setTimeout(function () {
requestAnimFrame(animate);
ctx.beginPath();
angle += Math.acos(1 - Math.pow(dd / radius, 2) / 2);
var newX = cx + radius * Math.cos(angle),
newY = cy + radius * Math.sin(angle),
newX1 = cx + radius2 * Math.cos(angle2),
newY1 = cy + radius2 * Math.sin(angle2),
newX2 = cx + radius3 * Math.cos(angle3),
newY2 = cy + radius3 * Math.sin(angle3),
newX3 = cx + radius4 * Math.cos(angle4),
newY3 = cy + radius4 * Math.sin(angle4);
draw(newX, newY);
ctx.arc(cx, cy, radius, 0, Math.PI * 2);
ctx.closePath();
ctx.beginPath();
angle2 += Math.acos(1 - Math.pow(dd2 / radius2, 2) / 2);
draw1(newX1, newY1);
ctx.arc(cx, cy, radius2, 0, 2 * Math.PI);
ctx.closePath();
ctx.beginPath();
angle3 += Math.acos(1 - Math.pow(dd3 / radius3, 2) / 2);
draw2(newX2, newY2);
ctx.arc(cx, cy, radius3, 0, 2 * Math.PI);
ctx.closePath();
ctx.beginPath();
angle4 += Math.acos(1 - Math.pow(dd4 / radius4, 2) / 2);
draw3(newX3, newY3);
ctx.arc(cx, cy, radius4, 0, 2 * Math.PI);
ctx.closePath();
}, 1000 / fps);
}
animate();
}());
You have to use ctx.beginPath(), ctx.closePath() and ctx.stroke() for EVERY arc you create, else it will connect them with lines (as you yourself also would have to, if you were drawing and were not allowed to take the pencil off the paper):
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var w = canvas.width;
var h = canvas.height;
var dd = 3;
var dd2 = 3;
var dd3 = 3;
var dd4 = 3;
var angle = 0;
var angle2 = 0;
var angle3 = 0;
var angle4 = 0;
var cx = 1000;
var cy = 1000;
var radius = 200;
var radius2 = 300;
var radius3 = 400;
var radius4 = 500;
var fps = 100;
ctx.fillStyle = "yellow";
ctx.strokeStyle = "skyblue";
(function () {
"use strict";
function draw(x, y) {
ctx.save();
ctx.clearRect(0, 0, w, h);
ctx.beginPath();
ctx.arc(cx, cy, 75, 75, 0, 2 * Math.PI);
ctx.closePath();
ctx.stroke();
ctx.fillStyle = "lightgray";
ctx.beginPath();
ctx.arc((x - 50 / 2) + 25, (y - 30 / 2) + 15, 25, 25, 0, 2 * Math.PI);
ctx.closePath();
ctx.stroke();
ctx.beginPath();
ctx.arc(cx, cy, 200, 200, 0, 2 * Math.PI);
ctx.closePath();
ctx.stroke();
ctx.restore();
}
function draw1(x1, y1) {
ctx.save();
ctx.fillStyle = "orange";
ctx.beginPath();
ctx.arc((x1 - 50 / 2) + 25, (y1 - 30 / 2) + 15, 25, 25, 0, 2 * Math.PI);
ctx.closePath();
ctx.stroke();
ctx.beginPath();
ctx.arc(cx, cy, 300, 300, 0, 2 * Math.PI);
ctx.closePath();
ctx.stroke();
ctx.restore();
}
function draw2(x2, y2) {
ctx.save();
ctx.fillStyle = "blue";
ctx.beginPath();
ctx.arc((x2 - 50 / 2) + 25, (y2 - 30 / 2) + 15, 25, 25, 0, 2 * Math.PI);
ctx.closePath();
ctx.stroke();
ctx.beginPath();
ctx.arc(cx, cy, 400, 400, 0, 2 * Math.PI);
ctx.closePath();
ctx.stroke();
ctx.restore();
}
function draw3(x3, y3) {
ctx.save();
ctx.fillStyle = "red";
ctx.beginPath();
ctx.arc((x3 - 50 / 2) + 25, (y3 - 30 / 2) + 15, 25, 25, 0, 2 * Math.PI);
ctx.closePath();
ctx.stroke();
ctx.beginPath();
ctx.arc(cx, cy, 500, 500, 0, 2 * Math.PI);
ctx.closePath();
ctx.stroke();
ctx.restore();
}
window.requestAnimFrame = (function (callback) {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function (callback) {
window.setTimeout(callback, 1000 / fps);
};
}());
function animate() {
setTimeout(function () {
requestAnimFrame(animate);
angle += Math.acos(1 - Math.pow(dd / radius, 2) / 2);
var newX = cx + radius * Math.cos(angle),
newY = cy + radius * Math.sin(angle),
newX1 = cx + radius2 * Math.cos(angle2),
newY1 = cy + radius2 * Math.sin(angle2),
newX2 = cx + radius3 * Math.cos(angle3),
newY2 = cy + radius3 * Math.sin(angle3),
newX3 = cx + radius4 * Math.cos(angle4),
newY3 = cy + radius4 * Math.sin(angle4);
draw(newX, newY);
ctx.arc(cx, cy, radius, 0, Math.PI * 2);
angle2 += Math.acos(1 - Math.pow(dd2 / radius2, 2) / 2);
draw1(newX1, newY1);
ctx.arc(cx, cy, radius2, 0, 2 * Math.PI);
angle3 += Math.acos(1 - Math.pow(dd3 / radius3, 2) / 2);
draw2(newX2, newY2);
ctx.arc(cx, cy, radius3, 0, 2 * Math.PI);
angle4 += Math.acos(1 - Math.pow(dd4 / radius4, 2) / 2);
draw3(newX3, newY3);
ctx.arc(cx, cy, radius4, 0, 2 * Math.PI);
}, 1000 / fps);
}
animate();
}());
<canvas id="canvas" width="2000" height="2000"></canvas>
E.g. I changed the following:
ctx.beginPath();
ctx.arc(cx, cy, 75, 75, 0, 2 * Math.PI);
ctx.fillStyle = "lightgray";
ctx.arc((x - 50 / 2) + 25, (y - 30 / 2) + 15, 25, 25, 0, 2 * Math.PI);
ctx.arc(cx, cy, 200, 200, 0, 2 * Math.PI);
ctx.stroke();
ctx.closePath();
Into this:
ctx.beginPath();
ctx.arc(cx, cy, 75, 75, 0, 2 * Math.PI);
ctx.closePath(); //Added
ctx.stroke(); //Added
ctx.fillStyle = "lightgray";
ctx.beginPath(); //Added
ctx.arc((x - 50 / 2) + 25, (y - 30 / 2) + 15, 25, 25, 0, 2 * Math.PI);
ctx.closePath(); //Added
ctx.stroke(); //Added
ctx.beginPath(); //Added
ctx.arc(cx, cy, 200, 200, 0, 2 * Math.PI);
ctx.closePath(); //Reversed order (doesn't really matter, but looks better IMO)
ctx.stroke(); //Reversed order (doesn't really matter, but looks better IMO)

Distorted canvas border In chrome and Firefox

I have this very simple canvas script , FIDDLE HERE.
JS code:
$(function() {
var canvas = $('<canvas></canvas>').attr({
width: 200,
height: 200
}).appendTo('.circle').get(0);
var context = canvas.getContext('2d');
context.clearRect(0, 0, 100, 100);
context.beginPath();
context.arc(100, 100, (200 / 2.5), Math.PI * 2, 0, false);
context.lineWidth = 10;
context.strokeStyle = "#eeeeee";
context.stroke();
context.fillStyle = "#FF0033";
context.fill();
var curPerc = 0;
function drawArc(current) {
console.log(current + ' ' + curPerc);
context.beginPath();
context.arc(100, 100, (200 / 2.5), 0, ((Math.PI * 2) * current), false);
context.strokeStyle = '#9BCB3C';
context.stroke();
//console.log(curPerc)
if (curPerc < 75) {
curPerc += 1;
requestAnimationFrame(function() {
drawArc(curPerc / 100);
});
};
}
drawArc();
});
Now the problem is the circle does't quite look perfect, the border is a bit distorted , i am on the latest version of chrome(same situation in latest FF) and below is how it looks:
.
Is this a known issue and is there an easy fix to this , that's what i want to know. Any help or advice would be appreciated.
Thank you.
Your problem is that you are always drawing the same arcs over the last ones.
The anti-aliasing artifacts are accumulating at each draw and become bigger and nastier.
The solution is to clearRect() your canvas at each call.
$(function() {
var canvas = $('<canvas></canvas>').attr({
width: 200,
height: 200
}).appendTo('.circle').get(0);
var context = canvas.getContext('2d');
// you wil then need to redraw the full circle at every frame too
var drawFull = function() {
context.clearRect(0, 0, 200, 200);
context.beginPath();
context.arc(100, 100, (200 / 2.5), Math.PI * 2, 0, false);
context.lineWidth = 10;
context.strokeStyle = "#eeeeee";
context.stroke();
context.fillStyle = "#FF0033";
context.fill();
};
var curPerc = 0;
function drawArc(current) {
drawFull();
context.beginPath();
context.arc(100, 100, (200 / 2.5), 0, ((Math.PI * 2) * current), false);
context.strokeStyle = '#9BCB3C';
context.stroke();
if (curPerc < 75) {
curPerc += 1;
requestAnimationFrame(function() {
drawArc(curPerc / 100);
});
};
}
drawArc();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="circle">
</div>
With this drawing, you could also try to upscale your canvas' width/height attributes and downscale it after with css :
$(function() {
var canvas = $('<canvas></canvas>').attr({
width: 400,
height: 400
}).css({width:200,height:200}).appendTo('.circle').get(0);
var context = canvas.getContext('2d');
// we need to change the context's scale
context.scale(2,2);
var drawFull = function() {
context.clearRect(0, 0, 200, 200);
context.beginPath();
context.arc(100, 100, (200 / 2.5), Math.PI * 2, 0, false);
context.lineWidth = 10;
context.strokeStyle = "#eeeeee";
context.stroke();
context.fillStyle = "#FF0033";
context.fill();
};
var curPerc = 0;
function drawArc(current) {
drawFull();
context.beginPath();
context.arc(100, 100, (200 / 2.5), 0, ((Math.PI * 2) * current), false);
context.strokeStyle = '#9BCB3C';
context.stroke();
if (curPerc < 75) {
curPerc += 1;
requestAnimationFrame(function() {
drawArc(curPerc / 100);
});
};
}
drawArc();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="circle">
</div>

Add another stroke to the existing canvas element

How to add another stroke with a different color and length into the same circle?
This script use Mootools lib. Can it be converted in pure JavaScript or jQuery?
fiddle: http://jsfiddle.net/xc4xnzcq/1/
Thanks :)
// SVG stuff
var ctx = document.id('counter').getContext('2d');
var circ = Math.PI * 2;
var quart = Math.PI / 2;
ctx.beginPath();
ctx.strokeStyle = '#ff00ab';
ctx.lineCap = 'square';
ctx.closePath();
ctx.fill();
ctx.lineWidth = 10;
var imd = ctx.getImageData(0, 0, 160, 160);
var draw = function(current) {
ctx.putImageData(imd, 0, 0);
ctx.beginPath();
ctx.arc(119, 70, 60, -(quart), ((circ) * current) - quart, false);
ctx.stroke();
}
var myFx = new Fx({
duration: 5500,
transition: 'bounce:out',
onStep: function(step){
draw(step / 100);
}
});
myFx.set = function(now){
var ret = Fx.prototype.set.call(this, now);
this.fireEvent('step', now);
return ret;
};
myFx.start(0, 80);
Drawing a second path seems to work fine for me.
// SVG stuff
var ctx = document.id('counter').getContext('2d');
var circ = Math.PI * 2;
var quart = Math.PI / 2;
var imd = ctx.getImageData(0, 0, 160, 160);
var draw = function(current) {
ctx.putImageData(imd, 0, 0);
ctx.beginPath();
ctx.strokeStyle = '#ff00ab';
ctx.lineCap = 'square';
ctx.lineWidth = 10;
ctx.arc(119, 70, 60, -(quart), ((circ) * current) - quart, false);
ctx.stroke();
ctx.beginPath();
ctx.strokeStyle = '#bb00bc';
ctx.lineCap = 'square';
ctx.lineWidth = 5;
ctx.arc(119, 70, 60, -(quart), ((circ) * current) - quart, false);
ctx.stroke();
}
var myFx = new Fx({
duration: 5500,
transition: 'bounce:out',
onStep: function(step){
draw(step / 100);
}
});
myFx.set = function(now){
var ret = Fx.prototype.set.call(this, now);
this.fireEvent('step', now);
return ret;
};
myFx.start(0, 80);

How to smooth out edges of circles drawn in canvas with arc?

I am drawing circles in a html5 canvas using arc but the edges are rough and not smooth. I am looking to smooth them out. Stacked overflow requires me to write more so my code to text ratio is better
Code
(function() {
var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
window.requestAnimationFrame = requestAnimationFrame;
}());
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
createCircle(100, 150, '85', '675');
createCircle(300, 150, '70', '479');
createCircle(500, 150, '91', '715');
createCircle(700, 150, '58', '334');
function createCircle(x, y, temp, hash, callback) {
var radius = 75;
var endPercent = parseInt(temp, 10);
var curPerc = 0;
var counterClockwise = false;
var circ = Math.PI * 2;
var quart = Math.PI / 2;
context.strokeStyle ='#006600';
context.lineWidth = 10;
context.lineCap = "round";
var offset = quart;
function doText(context, x, y, temp, hash) {
context.lineWidth = 10;
if(parseInt(temp, 10) > 90)
context.fillStyle = '#ad2323';
else if(parseInt(temp, 10) > 82)
context.fillStyle = '#ffcc33';
else
context.fillStyle = '#006600';
context.font = "28px sans-serif";
context.fillText(temp + 'ยบ', x - 20, y + 10);
context.fillText(hash + 'KH/s', x - 50, y - 90);
}
function animate(current) {
context.lineWidth = 10;
if(curPerc > 89)
context.strokeStyle = '#ad2323';
else if(curPerc > 81)
context.strokeStyle = '#ffcc33';
context.beginPath();
context.arc(x, y, radius, offset, ((circ) * current) + offset , false);
context.stroke();
context.closePath();
curPerc++;
if (curPerc < endPercent) {
requestAnimationFrame(function () {
animate(curPerc / 100);
});
}
else {
doText(context, x, y, temp, hash);
if (callback) callback.call();
}
}
animate();
}
JSFiddle = http://jsfiddle.net/uhVj6/712/
You are drawing strokes multiple times so they are drawing over one another. You need to clear the area where the old arc stroke was and then draw the new one
context.clearRect(x - radius - context.lineWidth,
y - radius - context.lineWidth,
radius * 2 + (context.lineWidth*2),
radius * 2 + (context.lineWidth*2));
context.beginPath();
context.arc(x, y, radius, offset, ((circ) * current) + offset , false);
context.stroke();
context.closePath();
JSFiddle

Categories