I've been learning some javascript/canvas animation, I'm having trouble getting this animation to work correctly.
My goal is that the animation will start drawing at the top, then as it gets back to the top it will stop progressing and the start position will progress around the arc making it look as though it is erasing itself and once at the top (1.5 * PI) will starting drawing again.
Here is a fiddle: https://jsfiddle.net/kg1fmsjj/
Here is my code:
function f(element, colour, thickness, elapsedTime) {
// Create Element
element.innerHTML = '';
var canvas = document.createElement('canvas');
var context = canvas.getContext("2d");
element.appendChild(canvas);
// Circle Params
context.lineWidth = thickness;
context.strokeStyle = colour;
var width = canvas.width;
var height = canvas.height;
var mathPi = Math.PI;
var x = canvas.width / 2;
var y = canvas.height / 2;
var radius = 40;
var startAngle = 1.5 * mathPi;
var endAngle = 1.5 * mathPi;
context.lineWidth = thickness;
context.strokeStyle = colour;
var erasing = false;
function animate() {
if(erasing) {
startAngle = startAngle + 0.01 * mathPi;
} else {
endAngle = endAngle + 0.01 * mathPi;
}
if (endAngle > (1.5 * mathPi)) {
erasing = true;
}
if (startAngle > (1.5 * mathPi)) {
erasing = false;
}
context.beginPath();
context.arc(x, y, radius, startAngle, endAngle, false);
context.stroke();
context.closePath();
}
setInterval(animate, 10);
}
f(document.getElementById('out'), '#800080', 4, 60);
context.arc lets you optionally draw your arc counterclockwise.
This ability lets you create your desired effect:
To "draw" the arc, draw an increasing arc clockwise.
To "erase" the arc, draw a decreasing arc counterclockwise.
Here's example code and a Demo:
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
ctx.lineWidth=2;
ctx.strokeStyle='#800080';
var PI=Math.PI;
var cx=cw/2;
var cy=ch/2;
var radius=cw/2-30;
var angle=0;
var direction=1;
requestAnimationFrame(animate);
function animate(time){
ctx.clearRect(0,0,cw,ch);
angle+=PI/120;
if(angle<0 || angle>PI*2){
angle=0;
direction*=-1;
}
draw();
requestAnimationFrame(animate);
}
function draw(){
var counterclockwise=(direction>0)?false:true;
var s=-Math.PI/2;
var e=angle-Math.PI/2;
ctx.beginPath();
ctx.arc(cx,cy,radius,s,e,counterclockwise);
ctx.stroke();
}
body{ background-color: ivory; }
#canvas{border:1px solid red; margin:0 auto; }
<canvas id="canvas" width=300 height=300></canvas>
You need to clear the canvas on each repaint using the clearRect() method.
You need to change the conditions when erasing variable is toggled. If erasing and startAngle >= endAngle then toggle erasing variable. If not erasing and endAngle >= startAngle + 2 * PI then toggle erasing variable.
The animate() method then become...
function animate() {
if(erasing) {
startAngle = startAngle + 0.01 * mathPi;
if (startAngle >= endAngle) {
erasing = false;
}
} else {
endAngle = endAngle + 0.01 * mathPi;
if (endAngle >= startAngle + 2.0 * mathPi) {
erasing = true;
}
}
context.clearRect(0, 0, canvas.width, canvas.height);
context.beginPath();
context.arc(x, y, radius, startAngle, endAngle, false);
context.stroke();
}
Related
I know that this question may have already been answered, but I am having a hard time figuring out how to do it with my code.
What I would like is for the arc of the circle to do a draw animation from 0deg to 360deg whenever the mouse is clicked.
I know that I should put this in a loop that increases the angle, but I keep running into issues with (I think) translate.
Here is my code so far:
https://jsfiddle.net/s7aufv0g/2/
This is where I draw the ball:
// Draw the ball
ctx.clearRect(0,0,width,height);
ctx.save();
ctx.translate(ball.position.x, ball.position.y);
ctx.beginPath();
ctx.arc(0, 0, ball.radius, 0, Math.PI*2, true);
ctx.stroke();
ctx.closePath();
ctx.restore();
Any help would be great, thank you very much.
Don't bother with context.translate because you can set the arc's centerX & centerY directly in the context.arc command.
You can control how much of the 360 degree arc angle is shown in the animation by setting the startAngle & endAngle in context.arc(centerX,centerY,radius,startAngle,endAngle).
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
function reOffset(){
var BB=canvas.getBoundingClientRect();
offsetX=BB.left;
offsetY=BB.top;
}
var offsetX,offsetY;
reOffset();
window.onscroll=function(e){ reOffset(); }
window.onresize=function(e){ reOffset(); }
var cx=cw/2;
var cy=ch/2;
var radius=Math.min(cw,ch)*.75/2;
var startAngle=-Math.PI/2;
var accumAngle=0;
var increment=Math.PI*2/120;
ctx.lineWidth=13;
ctx.strokeStyle='skyblue';
requestAnimationFrame(animate);
$("#canvas").mousedown(function(e){handleMouseDown(e);});
function handleMouseDown(e){
if(accumAngle>=Math.PI*2){
accumAngle=0;
requestAnimationFrame(animate);
}
}
function animate(time){
accumAngle+=increment;
ctx.clearRect(0,0,cw,ch);
ctx.beginPath();
ctx.arc(cx,cy,radius,startAngle,startAngle+accumAngle);
ctx.stroke();
if(accumAngle<=Math.PI*2){ requestAnimationFrame(animate); }
}
body{ background-color: ivory; }
#canvas{border:1px solid red; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<h4>Click in red canvas to begin arc animation<br>You must wait for any current circle to finish drawing.</h4>
<canvas id="canvas" width=300 height=300></canvas>
Here is someone else's fiddle animating the drawing of arc(). Perhaps it will get you pointed in the right direction. Add a click handler to start the draw() method and you should be good to go.
HTML
<html>
<head>
</head>
<body>
<canvas id="canvas1" width="500" height="500"></canvas>
</body>
</html>
JS
var currentEndAngle = 0
var currentStartAngle = 0;
var currentColor = 'black';
var lineRadius = 75;
var lineWidth = 15;
setInterval(draw, 50);
function draw() { /***************/
var can = document.getElementById('canvas1'); // GET LE CANVAS
var canvas = document.getElementById("canvas1");
var context = canvas.getContext("2d");
var x = canvas.width / 2;
var y = canvas.height / 2;
var radius;
var width;
var startAngle = currentStartAngle * Math.PI;
var endAngle = (currentEndAngle) * Math.PI;
currentStartAngle = currentEndAngle - 0.01;
currentEndAngle = currentEndAngle + 0.01;
if (Math.floor(currentStartAngle / 2) % 2) {
currentColor = "white";
radius = lineRadius - 1;
width = lineWidth + 3;
} else {
currentColor = "black";
radius = lineRadius;
width = lineWidth;
}
var counterClockwise = false;
context.beginPath();
context.arc(x, y, radius, startAngle, endAngle, counterClockwise);
context.lineWidth = width;
context.lineCap = "round";
// line color
context.strokeStyle = currentColor;
context.stroke();
http://jsfiddle.net/umaar/fnMvf/
Hi I try to make a animation. One of the 3 circles which become drawed when the function is called should move from right to left at first one random (yellow, blue or orange) circle should become drawed on the canvas then after 3 seconds the next random circle and then after 2,8 seconds and so far.
How can I do that? Now the circles become drawed every time again when the mainloop starts run again.
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 drawcircle1()
{
var radius = x * 5;
ctx.beginPath();
ctx.arc(ballx * 108, canvasHeight / 2, radius, 0, 2 * Math.PI, false);
ctx.fillStyle = 'yellow';
ctx.fill();
}
function drawcircle2()
{
var radius = x * 5;
ctx.beginPath();
ctx.arc(ballx * 108, canvasHeight / 2, radius, 0, 2 * Math.PI, false);
ctx.fillStyle = 'blue';
ctx.fill();
}
function drawcircle3()
{
var radius = x * 5;
ctx.beginPath();
ctx.arc(ballx * 105, canvasHeight / 2, radius, 0, 2 * Math.PI, false);
ctx.fillStyle = 'orange';
ctx.fill();
}
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();
//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();
//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();
// 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();
function drawRandom(drawFunctions){
//generate a random index
var randomIndex = Math.floor(Math.random() * drawFunctions.length);
//call the function
drawFunctions[randomIndex]();
}
drawRandom([drawcircle1, drawcircle2, drawcircle3]);
}
function update() {
ballx -= 0.1;
if (ballx < 0) {
ballx = -radius;
}
}
function main_loop() {
draw();
update();
collisiondetection();
}
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();
}
I'm a bit confused by your code, but I think I understand that you want to know how to delay when each circle will start animating to the left.
Here's how to animate your yellow, blue & orange circles with different delays:
Define the 3 circles using javascript objects and store all definintions in an array.
Inside an animation loop:
Calculate how much time has elapsed since the animation began
Loop through each circle in the array
If a circle's delay time as elapsed, animate it leftward
When all 3 circles have moved offscreen-left, stop the animation loop.
Here's annotated code and a Demo:
// canvas related variables
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var canvasWidth=canvas.width;
var canvasHeight=canvas.height;
// predifine PI*2 because it's used often
var PI2=Math.PI*2;
// startTime is used to calculate elapsed time
var startTime;
// define 3 circles in javascript objects and put
// them in the arcs[] array
var arcs=[];
addArc(canvasWidth,canvasHeight/2,20,0,PI2,0,-1,'yellow');
addArc(canvasWidth,canvasHeight/2+40,20,0,PI2,3000,-1,'blue');
addArc(canvasWidth,canvasHeight/2+80,20,0,PI2,8000,-1,'orange');
// begin animating
requestAnimationFrame(animate);
function animate(time){
// set startTime if it isn't already set
if(!startTime){startTime=time;}
// calc elapsedTime
var elapsedTime=time-startTime;
// clear the canvas
ctx.clearRect(0,0,canvasWidth,canvasHeight);
// assume no further animating is necessary
// The for-loop may change the assumption
var continueAnimating=false;
for(var i=0;i<arcs.length;i++){
var arc=arcs[i];
// update this circle & report if it wasMoved
var wasMoved=update(arc,elapsedTime);
// if it wasMoved, then change assumption to continueAnimating
if(wasMoved){continueAnimating=true;}
// draw this arc at its current position
drawArc(arc);
}
// if update() reported that it moved something
// then request another animation loop
if(continueAnimating){
requestAnimationFrame(animate);
}else{
// otherwise report the animation is complete
alert('Animation is complete');
}
}
function update(arc,elapsedTime){
// has this arc's animation delay been reached by elapsedTime
if(elapsedTime>=arc.delay){
// is this arc still visible on the canvas
if(arc.cx>-arc.radius){
// if yes+yes, move this arc by the specified moveX
arc.cx+=arc.moveX;
// report that we moved this arc
return(true);
}
}
// report that we didn't move this arc
return(false);
}
// create a javascript object defining this arc
function addArc(cx,cy,radius,startAngle,endAngle,
animationDelay,moveByX,color){
arcs.push({
cx:cx,
cy:cy,
radius:radius,
start:startAngle,
end:endAngle,
// this "delay" property is what causes this
// circle to delay before it starts to animate
delay:animationDelay,
moveX:moveByX,
color:color,
});
}
// draw a given arc
function drawArc(a){
ctx.beginPath();
ctx.arc(a.cx,a.cy,a.radius,a.start,a.end);
ctx.fillStyle=a.color;
ctx.fill();
}
body{ background-color: ivory; }
#canvas{border:1px solid red; margin:0 auto; }
<canvas id="canvas" width=400 height=300></canvas>
I have three arcs, the first one loads on page-load, the second one loads on mouse-over and the third one on mouse-out. I want the mouse-over-out effect to happen each time rather than just one time (as it is now).
here's the fiddle: http://jsfiddle.net/krish7878/7bX7n/
Here's the JS code:
var currentEndAngle = 0;
var currentStartAngle = 0;
var currentEndAngle2 = 0;
var currentStartAngle2 = 0;
var currentEndAngle3 = -0.5;
var currentStartAngle3 = -0.5;
var something = setInterval(draw, 5);
$("#canvas1").hover(
function(){
var something2 = setInterval(draw2, 5);
},
function(){
var something3 = setInterval(draw3, 5);
}
);
function draw() { /***************/
var can = document.getElementById('canvas1'); // GET LE CANVAS
var canvas = document.getElementById("canvas1");
var context = canvas.getContext("2d");
var x = canvas.width / 2;
var y = canvas.height / 2;
var radius;
var width;
var currentColor = "#00b5ff";
var radius = 100;
var width = 8;
var startAngle = currentStartAngle * Math.PI;
var endAngle = (currentEndAngle) * Math.PI;
if(currentEndAngle < 0.1){
currentEndAngle = currentEndAngle - 0.01;
}
if (currentEndAngle < -0.5){
clearInterval(something);
}
context.beginPath();
context.arc(x, y, radius, startAngle, endAngle, true);
context.lineWidth = width;
// line color
context.strokeStyle = currentColor;
context.stroke();
/************************************************/
}
function draw2() { /***************/
var can = document.getElementById('canvas1'); // GET LE CANVAS
var canvas = document.getElementById("canvas1");
var context = canvas.getContext("2d");
var x = canvas.width / 2;
var y = canvas.height / 2;
var radius;
var width;
var currentColor = "#000";
var radius = 100;
var width = 7;
var startAngle = currentStartAngle2 * Math.PI;
var endAngle = (currentEndAngle2) * Math.PI;
if(currentEndAngle2 < 0.1){
currentEndAngle2 = currentEndAngle2 - 0.01;
}
if (currentEndAngle2 < -0.55){
clearInterval(something2);
}
context.beginPath();
context.arc(x, y, radius, startAngle, endAngle, true);
context.lineWidth = width;
// line color
context.strokeStyle = currentColor;
context.stroke();
/*
context.beginPath();
context.clearRect ( 0 , 0 , 400 , 400 );
context.stroke():
/************************************************/
}
function draw3() { /***************/
var can = document.getElementById('canvas1'); // GET LE CANVAS
var canvas = document.getElementById("canvas1");
var context = canvas.getContext("2d");
var x = canvas.width / 2;
var y = canvas.height / 2;
var radius;
var width;
var currentColor = "#00b5ff";
var radius = 100;
var width = 8;
var startAngle = currentStartAngle3 * Math.PI;
var endAngle = (currentEndAngle3) * Math.PI;
if(currentEndAngle3 < 0){
currentEndAngle3 = currentEndAngle3 + 0.01;
}
if (currentEndAngle3 > 0){
clearInterval(something3);
}
context.beginPath();
context.arc(x, y, radius, startAngle, endAngle, false);
context.lineWidth = width;
// line color
context.strokeStyle = currentColor;
context.stroke();
/************************************************/
}
Code Explanation: there are three functions draw(), draw2(), draw3() - draw is run when the page loads, it draws a blue arc, draw2() is executed when mouse-over happens and draws a black line, draw3 is run when mouse-out happens.
Show I draw them on individual canvases and clear them individually or is there a method to get this done?
Here's one way to do it:
A Demo: http://jsfiddle.net/m1erickson/wMy4G/
Define an arc object
var arc={
cx:canvas.width/2,
cy:canvas.height/2,
radius:100,
startRadians:0,
endRadians:-Math.PI/2,
linewidth:8,
animationPercent:0,
animationRate:10,
animationDirection:0,
};
Draw a portion of the arc based on an animation point
function drawArc(arc,color){
var rStart=arc.startRadians;
var rEnd=arc.endRadians;
if(!arc.animationDirection==0){
if(arc.animationDirection>0){
rEnd=arc.animationPercent/100*(rEnd-rStart);
}else{
rEnd=(100-arc.animationPercent)/100*(rEnd-rStart);
}
}
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.beginPath();
ctx.arc(arc.cx,arc.cy,arc.radius,rStart,rEnd,true);
ctx.strokeStyle=color;
ctx.stroke();
}
Animate portions of the arc
function animate(time){
if(continueAnimation){RAF=requestAnimationFrame(animate);}
drawArc(arc,"blue");
arc.animationPercent+=arc.animationRate;
if(arc.animationPercent>=100){
continueAnimation=false;
}
}
React to hover events by drawing or undrawing the arc
$("#canvas").hover(
function(){
cancelAnimationFrame(RAF);
arc.animationPercent=0;
arc.animationDirection=1;
continueAnimation=true;
requestAnimationFrame(animate);
},
function(){
cancelAnimationFrame(RAF);
arc.animationPercent=0;
arc.animationDirection=-1;
continueAnimation=true;
requestAnimationFrame(animate);
}
);
Alright guys, I'm sure this has been asked before, but I couldn't find anything that directly related to what I was doing. So I have these 4 self drawing circles (or gauges.) Each one has it's own value, and I've been looking through just nit picking through codes and books to build this. My question I need to figure out is how I would go about putting in a count up? Basically I want a counter to go from 1 - x (x being the degree of the circle it's in). I've included my js and HTML 5 for you guys to look at.
HTML
<canvas id="a" width="300" height="300"></canvas>
<script>
var canvas = document.getElementById('a');
var context = canvas.getContext('2d');
var x = canvas.width / 2;
var y = canvas.height / 2;
var radius = 75;
var startAngle = 1.5 * Math.PI;
var endAngle = 3.2 * Math.PI;
var counterClockwise = false;
context.beginPath();
context.arc(x, y, radius, startAngle, endAngle, counterClockwise);
context.lineWidth = 15;
// line color
context.strokeStyle = 'black';
context.stroke();
</script>
Canvas.JS
$(document).ready(function(){
function animate(elementId, endPercent) {
var canvas = document.getElementById(elementId);
var context = canvas.getContext('2d');
var x = canvas.width / 2;
var y = canvas.height / 2;
var radius = 75;
var curPerc = 0;
var counterClockwise = false;
var circ = Math.PI * 2;
var quart = Math.PI / 2;
context.lineWidth = 15;
context.strokeStyle = '#85c3b8';
context.shadowOffsetX = 0;
context.shadowOffsetY = 0;
context.shadowBlur = 10;
function render(current) {
context.clearRect(0, 0, canvas.width, canvas.height);
context.beginPath();
context.arc(x, y, radius, -(quart), ((circ) * current) - quart, false);
context.stroke();
curPerc++;
if (curPerc < endPercent) {
requestAnimationFrame(function () {
render(curPerc / 100);
});
}
}
render();
}
$(window).scroll(function(){
if($(this).scrollTop()<1600){
animate('a', 85);
animate('b', 95);
animate('c', 80);
animate('d', 75);
}
});
});
Keep in mind that I am very new to canvas, I appreciate all the help guys!
Demo: http://jsfiddle.net/m1erickson/mYKp5/
You can save your gauges as objects in an array:
var guages=[];
guages.push({ x:50, y:100, radius:40, start:0, end:70, color:"blue" });
guages.push({ x:200, y:100, radius:40, start:0, end:90, color:"green" });
guages.push({ x:50, y:225, radius:40, start:0, end:35, color:"gold" });
guages.push({ x:200, y:225, radius:40, start:0, end:55, color:"purple" });
The render function takes a guage object draws its progress
function render(guage,percent) {
var pct=percent/100;
var extent=parseInt((guage.end-guage.start)*pct);
var current=(guage.end-guage.start)/100*PI2*pct-quart;
ctx.beginPath();
ctx.arc(guage.x,guage.y,guage.radius,-quart,current);
ctx.strokeStyle=guage.color;
ctx.stroke();
ctx.fillStyle=guage.color;
ctx.fillText(extent,guage.x-15,guage.y+5);
}
And the animation loop asks render to draw all gauges from 0-100 percent of their full values
function animate() {
// if the animation is not 100% then request another frame
if(percent<100){
requestAnimationFrame(animate);
}
// redraw all guages with the current percent
drawAll(percent);
// increase percent for the next frame
percent+=1;
}
function drawAll(percent){
// clear the canvas
ctx.clearRect(0, 0, canvas.width, canvas.height);
// draw all the guages
for(var i=0;i<guages.length;i++){
render(guages[i],percent);
}
}
I am just learning some details about html5 canvas, and in the progress, I am trying to build a simple color wheel by wedges (build a 1 degree wedge at a time and add it up to 360 degree). However, I am getting some weird marks on the gradient as shown in the following image:
.
Here is the fiddle that produced the colorwheel: http://jsfiddle.net/53JBM/
In particular, this is the JS code:
var canvas = document.getElementById("picker");
var context = canvas.getContext("2d");
var x = canvas.width / 2;
var y = canvas.height / 2;
var radius = 100;
var counterClockwise = false;
for(var angle=0; angle<=360; angle+=1){
var startAngle = (angle-1)*Math.PI/180;
var endAngle = angle * Math.PI/180;
context.beginPath();
context.moveTo(x, y);
context.arc(x, y, radius, startAngle, endAngle, counterClockwise);
context.closePath();
context.fillStyle = 'hsl('+angle+', 100%, 50%)';
context.fill();
}
If anyone can point out what I am doing wrong or if there is a better way to accomplish what I am attempting to do it would be much appreciated :)
Is this enough to you, please check
var startAngle = (angle-2)*Math.PI/180;
Try this it looks great.
Thanks by the way this is exactly what I was trying to make.
var canvas = document.getElementById("picker");
var context = canvas.getContext("2d");
var x = canvas.width / 2;
var y = canvas.height / 2;
var radius = 100;
var counterClockwise = false;
for(var angle=0; angle<=360; angle+=1){
var startAngle = (angle-2)*Math.PI/180;
var endAngle = angle * Math.PI/180;
context.beginPath();
context.moveTo(x, y);
context.arc(x, y, radius, startAngle, endAngle, counterClockwise);
context.closePath();
var gradient = context.createRadialGradient(x, y, 0, x, y, radius);
gradient.addColorStop(0,'hsl('+angle+', 10%, 100%)');
gradient.addColorStop(1,'hsl('+angle+', 100%, 50%)');
context.fillStyle = gradient;
context.fill();
}
<body>
<canvas id="picker"></canvas>
</body>
Similar approach, just for the color
var canvas = document.getElementById("picker");
var context = canvas.getContext("2d");
var x = canvas.width / 2;
var y = canvas.height / 2;
var radius = 50;
var thickness = 0.6;
for(var angle=0; angle<=360; angle+=1){
var startAngle = (angle-2)*Math.PI/180;
var endAngle = angle * Math.PI/180;
context.beginPath();
context.arc(x, y, (1-thickness/2)*radius, startAngle, endAngle, false);
context.lineWidth = thickness*radius;
context.strokeStyle = 'hsl('+angle+', 100%, 50%)';
context.stroke();
}
<body>
<canvas id="picker"></canvas>
</body>
Edit: full project here: https://github.com/dersimn/jquery-colorwheel