Rotation wheel with 12 fields like a chart - html

I have to create a rotation wheel with 12 fields like in the image below link :http://www.resilienciacomunitaria.org/
How i create through which approach?
I used canvas for this but not successful i used d3.js svg but not successful .
<!DOCTYPE html>
<html>
<body>
<canvas id="canvas" width="600" height="600"
style="background-color:#ffff">
</canvas>
<script type="text/javascript">
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var radius = canvas.height /2; //400
//alert(radius);
//draw a circle again and agian
ctx.translate(radius, radius);
radius =radius*0.85;
setInterval(drawCircle, 50);
function drawCircle() {
var pos = .01;
var length = 100;
var width = 40;
drawFace(ctx, radius);
drawHand(ctx, pos, length, width);
}
function drawFace(ctx,radius){
ctx.beginPath();
ctx.arc(0, 0, 50, 0, 2 * Math.PI, false);
ctx.fillStyle = '#ffff';
ctx.strokeStyle = 'blue';
ctx.fill();
ctx.stroke();
ctx.beginPath();
ctx.arc(0, 0, radius, 0, 2 * Math.PI, false);
ctx.strokeStyle = 'yellow';
ctx.fillStyle = 'blue';
ctx.lineWidth = 50;
ctx.fill();
ctx.stroke();
}
function drawHand(ctx, pos, length, width) {
ctx.beginPath();
ctx.lineWidth = 30;
ctx.moveTo(-radius,0);
ctx.lineTo(radius, 0);
ctx.moveTo(-radius,150);
ctx.lineTo(radius, -150);
ctx.moveTo(-radius,-150);
ctx.lineTo(radius, 150);
ctx.moveTo(-radius,380);
ctx.lineTo(radius, -380);
ctx.moveTo(-radius,-380);
ctx.lineTo(radius, 380);
ctx.moveTo(0, -radius);
ctx.lineTo(0, radius);
ctx.stroke();
/*
ctx.globalCompositeOperation='destination-over';
ctx.font="20px Verdana";
ctx.fillStyle = 'white';
ctx.fillText("Explore Zero",180,180);
ctx.stroke();
ctx.globalCompositeOperation='source-over';*/
ctx.rotate(-pos);
}
</script>
</body>
</html>
Thanks in advance

Here's code to get you started:
You can style it to your specific needs
Create an in-memory canvas containing your wheel.
Create an in-memory canvas containing your spike-indicator.
Rotate the canvas and draw the wheel on the main canvas.
Draw the indicator on the main canvas.
Change the rotation angle for the next loop.
Repeat, repeat, repeat using requestAnimationFrame.
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
var PI2=Math.PI*2;
var myData = [1,2,3,4,5,6,7,8,9,10,11,12];
var cx=150;
var cy=150;
var radius=150;
var wheel=document.createElement('canvas');
var wheelCtx=wheel.getContext('2d');
var indicator=document.createElement('canvas');
var indicatorCtx=indicator.getContext('2d');
var angle=PI2-PI2/4;
var myColor = [];
for(var i=0;i<myData.length;i++){ myColor.push(randomColor()); }
makeWheel();
makeIndicator();
requestAnimationFrame(animate);
function makeWheel(){
wheel.width=wheel.height=radius*2+2;
wheelCtx.lineWidth=1;
wheelCtx.font='24px verdana';
wheelCtx.textAlign='center';
wheelCtx.textBaseline='middle';
var cx=wheel.width/2;
var cy=wheel.height/2;
var sweepAngle=PI2/myData.length;
var startAngle=0;
for(var i=0;i<myData.length;i++){
// calc ending angle based on starting angle
var endAngle=startAngle+sweepAngle;
// draw the wedge
wheelCtx.beginPath();
wheelCtx.moveTo(cx,cy);
wheelCtx.arc(cx,cy,radius,startAngle,endAngle,false);
wheelCtx.closePath();
wheelCtx.fillStyle=myColor[i];
wheelCtx.strokeStyle='black';
wheelCtx.fill();
wheelCtx.stroke();
// draw the label
var midAngle=startAngle+(endAngle-startAngle)/2;
var labelRadius=radius*.85;
var x=cx+(labelRadius)*Math.cos(midAngle);
var y=cy+(labelRadius)*Math.sin(midAngle);
wheelCtx.fillStyle='gold';
wheelCtx.fillText(myData[i],x,y);
wheelCtx.strokeText(myData[i],x,y);
// increment angle
startAngle+=sweepAngle;
}
}
function makeIndicator(){
indicator.width=indicator.height=radius+radius/10;
indicatorCtx.font='18px verdana';
indicatorCtx.textAlign='center';
indicatorCtx.textBaseline='middle';
indicatorCtx.fillStyle='skyblue';
indicatorCtx.strokeStyle='blue';
indicatorCtx.lineWidth=1;
var cx=indicator.width/2;
var cy=indicator.height/2;
indicatorCtx.beginPath();
indicatorCtx.moveTo(cx-radius/8,cy);
indicatorCtx.lineTo(cx,cy-indicator.height/2);
indicatorCtx.lineTo(cx+radius/8,cy);
indicatorCtx.closePath();
indicatorCtx.fillStyle='skyblue'
indicatorCtx.fill();
indicatorCtx.stroke();
indicatorCtx.beginPath();
indicatorCtx.arc(cx,cy,radius/3,0,PI2);
indicatorCtx.closePath();
indicatorCtx.fill();
indicatorCtx.stroke();
indicatorCtx.fillStyle='blue';
indicatorCtx.fillText('Prizes',cx,cy);
}
function animate(time){
ctx.clearRect(0,0,cw,ch);
ctx.translate(cw/2,ch/2);
ctx.rotate(angle);
ctx.drawImage(wheel,-wheel.width/2,-wheel.height/2);
ctx.rotate(-angle);
ctx.translate(-cw/2,-ch/2);
ctx.drawImage(indicator,cw/2-indicator.width/2,ch/2-indicator.height/2)
angle+=PI2/360;
requestAnimationFrame(animate);
}
function randomColor(){
return('#'+Math.floor(Math.random()*16777215).toString(16));
}
body{ background-color: ivory; padding:10px; }
canvas{border:1px solid red;}
<canvas id="canvas" width=400 height=300></canvas>

You can just put the "wheel" image on the website and just rotate it.
document.getElementById("TheImage").style.transform = "rotate("+YourAngle+"deg)";
Also you will need to put the "pointer" image on top of "wheel" image. (you will not rotate this one)

This is a fiddle written in 20 minutes, hope it helps.
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
canvas.width = 500;
canvas.height = 500;
var lines = new Array();
lines[0] = new Array();
lines[0] = ["Prize 1","#000000"];
lines[1] = new Array();
lines[1] = ["Prize 2","#ffff00"];
lines[2] = new Array();
lines[2] = ["Prize 3","#ff00ff"];
lines[3] = new Array();
lines[3] = ["Prize 4","#00ffff"];
lines[4] = new Array();
lines[4] = ["Prize 5","#00ff00"];
var TO_RADIANS = Math.PI / 180;
var angle = 360 / lines.length; //to see how far apart the lines need to be
var angle_offset = 0; //this will determine the spinning
var angle_speed = 1; //degrees per cycle
var center_offset = 20; //the radius of your spinner in the middle
function animate() {
ctx.clearRect(0,0,canvas.width,canvas.height);
angle_offset+=angle_speed;
ctx.font="20px Verdana";
ctx.fillStyle="#000000";
for (i=0; i<lines.length; i++) {
ctx.fillStyle=lines[i][1];
ctx.save();
ctx.translate(canvas.width/2, canvas.height/2);
ctx.rotate((angle * i + angle_offset) * TO_RADIANS);
//Here you can also decorate with boxes and stuff
ctx.fillText(lines[i][0],center_offset,0);
ctx.restore();
}
requestAnimationFrame(animate);
}
animate();
<canvas id="canvas"></canvas>

Related

Lissajous in canvas

i need lissajous curves in Canvas. In curves should swim dot.I use this in school, but i can t this do, because i am new in this.
Curves should look like https://www.intmath.com/trigonometric-graphs/svg/svgphp-lissajous-figures-7-s2.svg
Thanks in advance.
function draw_lissajous(omega, sigma, cycles) {
var canvas = $('#scena').get(0);
var ctx = canvas.getContext('2d');
var c_h = 500;
var c_w = 500;
var step = 0.01;
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.strokeStyle = "red";
ctx.beginPath();
for(var i=0; i<(cycles * Math.PI*2) + step; i+=step) {
var x = Math.sin(omega*i + sigma);
var y = Math.sin(i);
var scale=200;
ctx.lineTo(c_w/2 + (x*scale), c_h/2 + (y*scale));
}
ctx.stroke();
}
function update() {
var omega = parseFloat($('input#omega').val());
var sigma = parseFloat($('input#sigma').val());
var cycles = parseFloat($('input#cycles').val());
if (isNaN(omega)) omega = 0;
if (isNaN(sigma)) sigma = 0;
if (isNaN(cycles)) cycles = 10;
draw_lissajous(omega, sigma, cycles);
}
$('input').keyup(function() {
update();
});
update();
<html>
<head>
<title>Lissajous Curves</title>
</head>
<body>
<canvas id='scena' width=500 height=500>
</canvas>
</body>
</html>

Canvas, animate line to move up and down

I have created a horizontal line in HTML5 Canvas. I want to animate the line to move infinity up and down. Is it possible?
function horizontal_line() {
context.beginPath();
context.moveTo(100, 100);
context.lineTo(5000, 100);
context.strokeStyle = "Green";
context.stroke();
}
For an animation you will need to have a way to draw different frames, and in each frame you have to delete the previous one, calculate the new position of the line, and then draw the line again:
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
ctx.strokeStyle = "Green";
var posY = 0;
var lineLength = 10;
var speed = 2;
function drawLine() {
ctx.beginPath();
ctx.moveTo(10, posY);
ctx.lineTo(10, posY+lineLength);
ctx.stroke();
}
function moveLine () {
posY += speed;
if (posY < 0 || posY > canvas.height) {
speed = speed * -1;
}
}
function loop() {
// clear old frame;
ctx.clearRect(0,0,canvas.width, canvas.height);
moveLine();
drawLine();
requestAnimationFrame(loop);
}
requestAnimationFrame(loop);
<canvas id="canvas"></canvas>
In this example requestAnimationFrame is what provides you the frames you need, so the function loop() gets called over and over again. In there we clear the old frame with clearRect(), calculate the new position, and then we draw the new Line with drawLine().

calling function twice in canvas

actually I'm new in html5 and tring to do something using canvas , the function that i create is drawing a short ray length start from point and end in point , the problem is when I duplicate the function to run twice in the same time it doesn't work correctly , where is the problem in my code ?
first I create the canvas
<canvas id="mycanvas" width="1120" height="700" style="margin:auto;border:1px solid #000000;position:relative;z-index: 10;">
</canvas>
Then i create call a function twice
var path1Number=0;
window.addEventListener('load', function () {
var x = 185, y = 185;
direction1(x,y , path1Number);
direction1(x+91,y+91 , path1Number);
}, false);
then i create a function that draw a path start from point to point
function direction1(x,y , path1Number){
//draw canvas line
var canvas1 = document.getElementById('mycanvas');
var context = canvas1.getContext('2d');
var x2 = x;
var y2 = y;
var ini_x = x;
var ini_y = y;
var done = false;
var interval = setInterval(function() {
context.clearRect(0, 0, canvas1.width, canvas1.height);
context.beginPath();
context.moveTo(x, y);
if(x2<x+20 && !done){
context.lineTo(x2, y2);
context.closePath();
context.strokeStyle = 'red';
context.stroke();
x2+=1;
y2+=1;
}else{
done = true;
x+=1;
y+=1;
if(x2 >= ini_x + 91){
if(x2 == x){
clearInterval(interval);
context.closePath();
context.clearRect(0, 0, canvas1.width, canvas1.height);
path1Number+=1;
path1(x,y,path1Number);
}
}else{
x2+=1;
y2+=1;
}
context.lineTo(x2, y2);
context.closePath();
context.strokeStyle = 'red';
context.stroke();
}
},10);
}
the problem happened when i call this function twice it doesn't work correctly so what is the reason ? Thanks .

Canvas, animated text rotation

I want to have a animated canvas rotation of a word, while another word on the canvas does not move. But somehow both stand still. What do I have to change?
[link]http://jsfiddle.net/2dszD/8/
var canvas;
var ctx;
var canvasWidth;
var canvasHeight;
var interval = 10;
function init(){
canvas = document.getElementById("canvas");
ctx = canvas.getContext('2d');
canvasWidth = canvas.width;
canvasHeight = canvas.height;
setInterval(redraw, interval);
}
init();
function redraw() {
ctx.clearRect(0, 0, canvasWidth, canvasHeight);
ctx.translate( (200 ), (150 ) );
ctx.rotate( 1*Math.PI/180 );
ctx.fillStyle = '#f00';
ctx.font = '40px san-serif';
ctx.textBaseline = 'top';
ctx.fillText("Hello rotated", 0, 0);
ctx.rotate(-( 1*Math.PI/180 ));
ctx.translate( -(200), -(150) );
ctx.fillStyle = '#f00';
ctx.font = '40px san-serif';
ctx.textBaseline = 'top';
ctx.fillText("Hello still", 0, 0);
}
Actually, your text is rotated by a tiny 1.0 degree.
1*Math.PI/180 represents 1 tiny degree of rotation
So this would be a more noticeable 5 degrees:
ctx.rotate( 5.0 * Math.PI/180 );
A few coding glitches:
You need to increment the rotation angle so your text actually animates
angleInDegrees+=5;
ctx.rotate( angleInDegrees * Math.PI/180 );
setInterval requires a full function as an argument, not just a function name, like this:
setInterval( function(){redraw();}, interval);
And here’s easier way to handle translate/rotate
Instead of un-translating and un-rotating like this:
ctx.translate( (200 ), (150 ) );
ctx.rotate( 1*Math.PI/180 );
// draw stuff here
ctx.rotate(-( 1*Math.PI/180 ));
ctx.translate( -(200), -(150) );
You can instead context.save() and context.restore() which is cleaner and doesn’t require un-doing:
// save the canvas context—including its un-translated and un-rotated setting
ctx.save();
ctx.translate(200,150);
ctx.rotate( angleInDegrees * Math.PI/180 );
// draw stuff here
// after restore() the canvas is back to its starting position before save()
ctx.restore();
Here’s code and a Fiddle: http://jsfiddle.net/m1erickson/5XTcn/
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: ivory; }
canvas{border:1px solid red;}
</style>
<script>
$(function(){
var canvasWidth;
var canvasHeight;
var interval = 350;
var angleInDegrees=0;
function init(){
canvas = document.getElementById("canvas");
ctx = canvas.getContext('2d');
canvasWidth = canvas.width;
canvasHeight = canvas.height;
setInterval( function(){redraw();}, interval);
}
init();
function redraw() {
angleInDegrees+=5;
ctx.clearRect(0, 0, canvasWidth, canvasHeight);
ctx.beginPath();
ctx.rect(200,150,5,5);
ctx.fill();
ctx.save();
ctx.translate(200,150);
ctx.rotate( angleInDegrees * Math.PI/180 );
ctx.fillStyle = '#f00';
ctx.font = '40px san-serif';
ctx.textBaseline = 'top';
ctx.fillText("Hello rotated", 0, 0);
ctx.restore();
ctx.fillStyle = '#f00';
ctx.font = '40px san-serif';
ctx.textBaseline = 'top';
ctx.fillText("Hello still", 0, 0);
}
}); // end $(function(){});
</script>
</head>
<body>
<canvas id="canvas" width=500 height=300></canvas>
</body>
</html>

moving an image across a html canvas

I am trying to move an image from the right to the center and I am not sure if this is the best way.
var imgTag = null;
var x = 0;
var y = 0;
var id;
function doCanvas()
{
var canvas = document.getElementById('icanvas');
var ctx = canvas.getContext("2d");
var imgBkg = document.getElementById('imgBkg');
imgTag = document.getElementById('imgTag');
ctx.drawImage(imgBkg, 0, 0);
x = canvas.width;
y = 40;
id = setInterval(moveImg, 0.25);
}
function moveImg()
{
if(x <= 250)
clearInterval(id);
var canvas = document.getElementById('icanvas');
var ctx = canvas.getContext("2d");
ctx.clearRect(0, 0, canvas.width, canvas.height);
var imgBkg = document.getElementById('imgBkg');
ctx.drawImage(imgBkg, 0, 0);
ctx.drawImage(imgTag, x, y);
x = x - 1;
}
Any advice?
This question is 5 years old, but since we now have requestAnimationFrame() method, here's an approach for that using vanilla JavaScript:
var imgTag = new Image(),
canvas = document.getElementById('icanvas'),
ctx = canvas.getContext("2d"),
x = canvas.width,
y = 0;
imgTag.onload = animate;
imgTag.src = "http://i.stack.imgur.com/Rk0DW.png"; // load image
function animate() {
ctx.clearRect(0, 0, canvas.width, canvas.height); // clear canvas
ctx.drawImage(imgTag, x, y); // draw image at current position
x -= 4;
if (x > 250) requestAnimationFrame(animate) // loop
}
<canvas id="icanvas" width=640 height=180></canvas>
drawImage() enables to define which part of the source image to draw on target canvas. I would suggest for each moveImg() calculate the previous image position, overwrite the previous image with that part of imgBkg, then draw the new image. Supposedly this will save some computing power.
Here's my answer.
var canvas = document.getElementById("canvas");
ctx = canvas.getContext("2d");
var myImg = new Image();
var myImgPos = {
x: 250,
y: 125,
width: 50,
height: 25
}
function draw() {
myImg.onload = function() {
ctx.drawImage(myImg, myImgPos.x, myImgPos.y, myImgPos.width, myImgPos.height);
}
myImg.src = "https://mario.wiki.gallery/images/thumb/c/cc/NSMBUD_Mariojump.png/1200px-NSMBUD_Mariojump.png";
}
function moveMyImg() {
ctx.clearRect(myImgPos.x, myImgPos.y, myImgPos.x + myImgPos.width, myImgPos.y +
myImgPos.height);
myImgPos.x -= 5;
}
setInterval(draw, 50);
setInterval(moveMyImg, 50);
<canvas id="canvas" class="canvas" width="250" height="150"></canvas>
For lag free animations,i generally use kinetic.js.
var stage = new Kinetic.Stage({
container: 'container',
width: 578,
height: 200
});
var layer = new Kinetic.Layer();
var hexagon = new Kinetic.RegularPolygon({
x: stage.width()/2,
y: stage.height()/2,
sides: 6,
radius: 70,
fill: 'red',
stroke: 'black',
strokeWidth: 4
});
layer.add(hexagon);
stage.add(layer);
var amplitude = 150;
var period = 2000;
// in ms
var centerX = stage.width()/2;
var anim = new Kinetic.Animation(function(frame) {
hexagon.setX(amplitude * Math.sin(frame.time * 2 * Math.PI / period) + centerX);
}, layer);
anim.start();
Here's the example,if you wanna take a look.
http://www.html5canvastutorials.com/kineticjs/html5-canvas-kineticjs-animate-position-tutorial/
Why i suggest this is because,setInterval or setTimeout a particular function causes issues when large amount of simultaneous animations take place,but kinetic.Animation deals with framerates more intelligently.
Explaining window.requestAnimationFrame() with an example
In the following snippet I'm using an image for the piece that is going to be animated.
I'll be honest... window.requestAnimationFrame() wasn't easy for me to understand, that is why I coded it as clear and intuitive as possible. So that you may struggle less than I did to get my head around it.
const
canvas = document.getElementById('root'),
btn = document.getElementById('btn'),
ctx = canvas.getContext('2d'),
brickImage = new Image(),
piece = {image: brickImage, x:400, y:70, width:70};
brickImage.src = "https://i.stack.imgur.com/YreH6.png";
// When btn is clicked execute start()
btn.addEventListener('click', start)
function start(){
btn.value = 'animation started'
// Start gameLoop()
brickImage.onload = window.requestAnimationFrame(gameLoop)
}
function gameLoop(){
// Clear canvas
ctx.clearRect(0, 0, canvas.width, canvas.height)
// Draw at coordinates x and y
ctx.drawImage(piece.image, piece.x, piece.y)
let pieceLeftSidePos = piece.x;
let middlePos = canvas.width/2 - piece.width/2;
// Brick stops when it gets to the middle of the canvas
if(pieceLeftSidePos > middlePos) piece.x -= 2;
window.requestAnimationFrame(gameLoop) // Needed to keep looping
}
<input id="btn" type="button" value="start" />
<p>
<canvas id="root" width="400" style="border:1px solid grey">
A key point
Inside the start() function we have:
brickImage.onload = window.requestAnimationFrame(gameLoop);
This could also be written like: window.requestAnimationFrame(gameLoop);
and it would probably work, but I'm adding the brickImage.onload to make sure that the image has loaded first. If not it could cause some issues.
Note: window.requestAnimationFrame() usually loops at 60 times per second.