Javascript line around a circle - javascript

I want to programm this cool visualization with javascrip:
http://imgur.com/ZCUW7js
I have this: http://test.wikunia.de/pi/ but unfortunately I have no idea how to draw the lines that there is a black circle in the middle. Any idea?
I am using quadraticCurveTo now, but maybe bezier curve is a better option...
My full code:
var canvas = document.getElementById('myCanvas');
var color_arr = new Array("yellow","orange","OrangeRed","red","violetred","MediumSlateBlue","blue","aquamarine","green","greenyellow");
var sA = (Math.PI / 180) * 270;
var pA = (Math.PI / 180) * 36;
if (canvas && canvas.getContext) {
var ctx = canvas.getContext("2d");
if (ctx) {
ctx.fillStyle = "black";
ctx.fillRect(0,0,ctx.canvas.width, ctx.canvas.height);
for (var i=0; i <= 9; i++) {
ctx.strokeStyle = color_arr[i];
ctx.lineWidth = 5;
ctx.beginPath();
ctx.arc (350, 350, 250, sA+(i)*pA, sA+(i+1)*pA, false);
ctx.stroke();
ctx.closePath();
ctx.fillStyle = "white";
ctx.strokeStyle = "white";
ctx.font = "italic 30pt Arial";
if (i > 4 && i < 8) {
ctx.fillText(i.toString(), 350+290*Math.cos(sA+(i+0.5)*pA),350+290*Math.sin(sA+(i+0.5)*pA));
} else {
if (i == 3 || i == 4 || i == 8) {
ctx.fillText(i.toString(), 350+275*Math.cos(sA+(i+0.5)*pA),350+275*Math.sin(sA+(i+0.5)*pA));
} else {
ctx.fillText(i.toString(), 350+260*Math.cos(sA+(i+0.5)*pA),350+260*Math.sin(sA+(i+0.5)*pA));
}
}
}
var pi = '31415...';
for (i = 0; i <= 250; i++) {
line(parseInt(pi.substr(i,1)),parseInt(pi.substr(i+1,1)));
}
}
}
function line(no_1,no_2) {
var rand_1 = Math.random();
var rand_2 = Math.random();
var grad= ctx.createLinearGradient(350+250*Math.cos(sA+(no_1+rand_1)*pA), 350+250*Math.sin(sA+(no_1+rand_1)*pA), 350+250*Math.cos(sA+(no_2+rand_2)*pA), 350+250*Math.sin(sA+(no_2+rand_2)*pA));
grad.addColorStop(0, color_arr[no_1]);
grad.addColorStop(1, color_arr[no_2]);
ctx.lineWidth = 1;
ctx.strokeStyle = grad;
ctx.beginPath();
ctx.moveTo(350+250*Math.cos(sA+(no_1+rand_1)*pA), 350+250*Math.sin(sA+(no_1+rand_1)*pA));
ctx.quadraticCurveTo(350,350,350+250*Math.cos(sA+(no_2+rand_2)*pA),350+250*Math.sin(sA+(no_2+rand_2)*pA));
ctx.stroke();
}

Interesting!
The black circle in the middle is just an absence of curves.
The "lines" are cubic Bezier curves.
The beziers appear to be anchored on both ends to the circle circumference at intervals.
Here's my try at a simplified version of that PI: http://jsfiddle.net/m1erickson/Ju6E8/
This could be addictive so I'm leaving my attempt simple!
<!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; padding:50px; }
#canvas{border:1px solid red;}
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var PI2=Math.PI*2;
var cx=150;
var cy=150;
var r=100;
ctx.arc(cx,cy,r,0,Math.PI*2);
ctx.closePath();
ctx.stroke();
for(var a=0;a<PI2;a+=PI2/20){
ctx.strokeStyle="blue";
curve(a,PI2/2.5,25);
ctx.strokeStyle="green";
curve(a,PI2/5,50);
ctx.strokeStyle="red";
curve(a,PI2/10,75);
}
function curve(rotation,offset,innerRadius){
var x1=cx+r*Math.cos(rotation);
var y1=cy+r*Math.sin(rotation);
var x2=cx+innerRadius*Math.cos(rotation+offset/3.5);
var y2=cy+innerRadius*Math.sin(rotation+offset/3.5);
var x3=cx+innerRadius*Math.cos(rotation+offset/1.5);
var y3=cy+innerRadius*Math.sin(rotation+offset/1.5);
var x4=cx+r*Math.cos(rotation+offset);
var y4=cy+r*Math.sin(rotation+offset);
ctx.beginPath();
ctx.moveTo(x1,y1);
ctx.bezierCurveTo(x2,y2,x3,y3,x4,y4);
ctx.stroke();
}
$("#stop").click(function(){});
}); // end $(function(){});
</script>
</head>
<body>
<button id="stop">Stop</button><br>
<canvas id="canvas" width=300 height=300></canvas>
</body>
</html>

Related

Scroll to element not working? Javascript / jQuery [duplicate]

Ive tried solving the problem, and i cant seem to find its solution. A few hours of fiddling around later, ive found out that the problem is within the button tag or the onclick attribute (Correct me if im wrong).
My aim is to make the white dot move via buttons
<!DOCTYPE html>
<html>
<head>
<title></title>
<script type="text/javascript">
window.onload = function()
{
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
canvas.width = 345;
canvas.height = 410;
canvas.style.border = "1px solid white";
var left = document.getElementById("left");
left.onclick = "playerLeft()";
var x = Math.round(canvas.width/2);
var y = Math.round(canvas.width/2);
var rectWidth = 5, rectHeight = 5;
var fps = 30, frames = 1000/fps;
var colour = "white";
var trailColour = "blue";
ctx.fillStyle = colour;
ctx.fillRect(x,y,rectWidth,rectHeight);
function playerLeft() {
ctx.fillStyle = trailColour;
ctx.fillRect(x,y,rectWidth,rectHeight);
x -= 6;
ctx.fillStyle = colour;;
ctx.fillRect(x,y,rectWidth,rectHeight);
}
function playerRight() {
ctx.fillStyle = trailColour;
ctx.fillRect(x,y,rectWidth,rectHeight);
x += 6;
ctx.fillStyle = colour;
ctx.fillRect(x,y,rectWidth,rectHeight);
}
function playerUp() {
ctx.fillStyle = trailColour;
ctx.fillRect(x,y,rectWidth,rectHeight);
y -= 6;
ctx.fillStyle = colour;
ctx.fillRect(x,y,rectWidth,rectHeight);
}
function playerDown() {
ctx.fillStyle = trailColour;
ctx.fillRect(x,y,rectWidth,rectHeight);
y += 6;
ctx.fillStyle = colour;
ctx.fillRect(x,y,rectWidth,rectHeight);
}
}
</script>
</head>
<body style="background-color: black">
<canvas id="canvas"></canvas>
<div style="text-align: center; padding: 5px">
<button id="left">Left</button>
<button id="up">Up</button>
<button id="down">Down</button>
<button id="right">Right</button>
</div>
</body>
</html>
One of the many reasons not to use onxyz="..."-style event handlers is that any functions you call from them must be globals. Your functions aren't, they're local to the window.onload callback.
Instead, just assign the function reference directly, either somewhat old-fashioned:
left.onclick = playerLeft;
or using more modern techniques that allow for multiple handlers:
left.addEventListener("click", playerLeft);
Just call the function without parenthesis.
<!DOCTYPE html>
<html>
<head>
<title></title>
<script type="text/javascript">
window.onload = function() {
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
canvas.width = 345;
canvas.height = 410;
canvas.style.border = "1px solid white";
var left = document.getElementById("left");
left.addEventListener("click", playerLeft);
var x = Math.round(canvas.width/2);
var y = Math.round(canvas.width/2);
var rectWidth = 5, rectHeight = 5;
var fps = 30, frames = 1000/fps;
var colour = "white";
var trailColour = "blue";
ctx.fillStyle = colour;
ctx.fillRect(x,y,rectWidth,rectHeight);
function playerLeft() {
ctx.fillStyle = trailColour;
ctx.fillRect(x,y,rectWidth,rectHeight);
x -= 6;
ctx.fillStyle = colour;;
ctx.fillRect(x,y,rectWidth,rectHeight);
}
function playerRight() {
ctx.fillStyle = trailColour;
ctx.fillRect(x,y,rectWidth,rectHeight);
x += 6;
ctx.fillStyle = colour;
ctx.fillRect(x,y,rectWidth,rectHeight);
}
function playerUp() {
ctx.fillStyle = trailColour;
ctx.fillRect(x,y,rectWidth,rectHeight);
y -= 6;
ctx.fillStyle = colour;
ctx.fillRect(x,y,rectWidth,rectHeight);
}
function playerDown() {
ctx.fillStyle = trailColour;
ctx.fillRect(x,y,rectWidth,rectHeight);
y += 6;
ctx.fillStyle = colour;
ctx.fillRect(x,y,rectWidth,rectHeight);
}
}
</script>
</head>
<body style="background-color: black">
<canvas id="canvas"></canvas>
<div style="text-align: center; padding: 5px">
<button id="left">Left</button>
<button id="up">Up</button>
<button id="down">Down</button>
<button id="right">Right</button>
</div>
</body>
</html>

Javascript - Is there a more efficient method to repeat rectangle creation?

So i have this relatively simple code:
var c = document.getElementById("canvas");
var ctx = c.getContext("2d");
ctx.fillStyle = "black";
ctx.fillRect(0, 0, c.width, c.height);
ctx.beginPath();
ctx.fillStyle = "yellow";
ctx.fillRect(400 * Math.random(), 400 * Math.random(), 3, 3);
ctx.stroke();
ctx.closePath();
Essentially it just creates a black canvas then randomly places a yellow square on it. Other than mindlessly copy and pasting, is there a more efficient method to redraw this multiple times? (Maybe some kind of setTimeout function?)
Hope this helps you out.
function myFunction() {
setInterval(function(){callRect();}, 3000);
}
function callRect(){
var c = document.getElementById("canvas");
var ctx = c.getContext("2d");
ctx.fillStyle = getRandomColor();
ctx.fillRect(0, 0, c.width, c.height);
ctx.beginPath();
ctx.fillStyle = "yellow";
ctx.fillRect(400 * Math.random(), 400 * Math.random(), 3, 3);
ctx.stroke();
ctx.closePath();
}
function getRandomColor() {
var letters = '0123456789ABCDEF';
var color = '#';
for (var i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Inspiration</title>
</head>
<body>
<canvas id='canvas'></canvas>
<button type='button' onclick='myFunction();'>Button</button>
</body>
</html>

How would I align circles horizontally using loops?

I have managed to get the circles on top of each other but I have no clue how to make a line of circles that do not overlap.
This is what I have gotten so far.
HTML
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body>
<canvas id="myCanvas" width="800" height="600"></canvas>
<script src="js/main.js"></script>
</body>
</html>
JavaScript
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext('2d');
for(var i = 0; i < 10; i++) {
ctx.fillStyle="rgba(0,0,0,0.5)";
fillCircle(200,200,i*20)
}
var width = window.innerWidth;
var height = 100;
function fillCircle(x, y, radius) {
ctx.beginPath();
ctx.arc(x, y, radius, 0, Math.PI * 2);
ctx.closePath();
ctx.fill();
}
The x-value of any next circle must be at least be the sum of the current and next circle radii beyond the current circle's x-value.
So if:
var currentCircleX=20
var currentCircleRadius=15
var nextCircleRadius=25
Then:
var nextCircleX = currentCircleX + currentCircleRadius + nextCircleRadius
But if you are also stroking the circles:
Since a context stroke will extend half-outside the defined path, you must also add half the lineWidth for each circle to avoid the circles touching:
// account for the lineWidth that extends beyond the arc's path
var nextCircleX =
currentCircleX + currentCircleRadius + nextCircleRadius + context.lineWidth
Example code and a Demo:
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
ctx.fillStyle="rgba(0,0,0,0.5)";
var currentCircleX=0;
var currentCircleRadius=0;
for(var i = 0; i < 10; i++) {
var nextCircleRadius=i*20;
var nextCircleX=currentCircleX+currentCircleRadius+nextCircleRadius;
fillCircle(nextCircleX,200,nextCircleRadius);
currentCircleX=nextCircleX;
currentCircleRadius=nextCircleRadius;
}
function fillCircle(x, y, radius) {
ctx.beginPath();
ctx.arc(x, y, radius, 0, Math.PI * 2);
ctx.closePath();
ctx.fill();
}
body{ background-color: ivory; padding:10px; }
#canvas{border:1px solid red;}
<canvas id="canvas" width=300 height=300></canvas>

How would I put this code together?

I have a Javascript program working in three different places: here,
here, and here.
But I don't know how would I put them in one file. This is where I am at right now.
<!DOCTYPE html>
<html>
<head>
<title>TEST</title>
<style>
body {
background-color:#E4E0FF;
}
#canvas {
border:10px solid red;
background-color:white;
}
#canvas2 {
border:10px solid red;
background-color:white;
}
#canvas3 {
border:10px solid red;
background-color:white;
}
</style>
</head>
<body>
<canvas id="canvas" width="400" height="300">
</canvas>
<canvas id="canvas2" width="400" height="300">
</canvas>
<canvas id="canvas3" width="400" height="300">
</canvas>
<script src="http://code.jquery.com/jquery-latest.min.js"
type="text/javascript"></script>
<script type="text/javascript">
var c = document.getElementById("canvas");
var ctx = c.getContext("2d");
var $canvas = $("#canvas");
var canvasOffset = $canvas.offset();
var offsetX = canvasOffset.left;
var offsetY = canvasOffset.top;
var scrollX = $canvas.scrollLeft();
var scrollY = $canvas.scrollTop();
var toggle=0;
var x=150;
var y=100;
var w=100;
var h=100;
var r=60;
var wasInside=false;
ctx.fillStyle = "#000000";
ctx.fillRect(x, y, w, h);
function changeColor() {
if (toggle == 0) {
ctx.fillStyle = "#04B45F";
toggle = 1;
} else if (toggle ==1){
ctx.fillStyle = "#04B45F";
toggle = 2;
}else if (toggle == 2){
ctx.fillStyle = "#0000FF";
toggle = 3;
}else if (toggle == 3){
ctx.fillStyle == "#190707";
toggle = 4;
}else if (toggle == 4){
ctx.fillStyle = "#210B61";
toggle = 5;
}else if (toggle == 5){
ctx.fillStyle = "#FA58AC";
toggle = 6;
}else if (toggle ==6){
ctx.fillStyle = "#FFFF00";
toggle = 7;
}else{
ctx.fillStyle = "#F5A9D0";
toggle = 0;
}
ctx.fillRect(x, y, w, h);
}
function changeRadius() {
ctx.fillStyle = "#FFFFFF";
ctx.fillRect(0,0, 400, 300);
r = Math.floor((Math.random() * 80) + 20);
ctx.beginPath();
ctx.arc(200, 150, r, 0, 2 * Math.PI);
ctx.stroke();
}
function changeWidth() {
ctx.fillStyle = "#FFFFFF";
ctx.fillRect(0,0, 400, 300);
width = Math.floor((Math.random()*50)+1);
ctx.lineWidth=width;
ctx.stroke();
}
function handleMouseMove(e) {
var mx = parseInt(e.clientX - offsetX);
var my = parseInt(e.clientY - offsetY);
var isInsideNow = (mx > x && mx < x + w && my > y && my <= y + h);
if (isInsideNow && !wasInside) {
changeColor();
wasInside = true;
} else if (!isInsideNow && wasInside) {
wasInside = false;
}
}
$("#canvas").mousemove(function (e) {
handleMouseMove(e);
});
$("#canvas2").mousemove(function (e) {
handleMouseMove(e);
});
$("#canvas3").mousemove(function (e) {
handleMouseMove(e);
});
</script>
</body>
</html>
So, how would I tell the program to do circle thing in 2nd canvas and line in 3rd canvas???
I haven't called the changeWidth and changeRadius functions yet, because it'll just do it in the first canvas making a mess.
I just need something in this part of the code to call different functions in different canvas's
if (isInsideNow && !wasInside) {
changeColor();
wasInside = true;
} else if (!isInsideNow && wasInside) {
wasInside = false;
}
I'm not a canvas expert, but just for giving you an idea, check this FIDDLE
var c = document.getElementById("canvas");
var ctx = c.getContext("2d");
inspect these 2 lines, the context ctx wil draw in the canvas with id=canvas. you can create other contex variables to draw in the other canvas or reuse the same.
updated FIDDLE
Update for the update: FIDDLE

Mouse click not working in my column chart in html5

Hi all again i have problem in my chart construction in html 5. This time did everything well except one part or module. I tried some code which i got through internet for displaying some alert when a rectangle in canvas in clicked. When i comment the module it works fine but not the mouse click. Can anyone help me out. Thanks in advance. Here is my fiddle and code [fiddle]: http://jsfiddle.net/s8kZs/
<!doctype html>
<html>
<head>
<script type="text/javascript">
window.onload=function() {
var canvas=document.getElementById('mycanvas');
var ctx=canvas.getContext('2d');
var graphInfo=[{data:[120,130,140,160,180,100],color:'purple',label:["a","b","c","d","e","f"]},{data:[100,120,130,140,150,190],color:'green',label:["g","h","i","j","k","l"]}];
var width=45;
function renderGrid(gridPixelSize, color)
{
ctx.save();
ctx.lineWidth = 0.5;
ctx.strokeStyle = color;
for(var i = 20; i <= canvas.height-20; i = i + gridPixelSize)
{
ctx.beginPath();
ctx.moveTo(20, i);
ctx.lineTo(canvas.width-20, i);
ctx.closePath();
ctx.stroke();
}
for(var j = 20; j <= canvas.width-20; j = j + gridPixelSize)
{
ctx.beginPath();
ctx.moveTo(j, 20);
ctx.lineTo(j, canvas.height-20);
ctx.closePath();
ctx.stroke();
}
ctx.restore();
}
renderGrid(10, "grey");
ctx.beginPath();
ctx.strokeStyle = 'black';
ctx.moveTo(20, canvas.height-20);
ctx.lineTo(canvas.width-20, canvas.height-20);
ctx.closePath();
ctx.stroke();
ctx.beginPath();
ctx.strokeStyle = 'black';
ctx.moveTo(20, 20);
ctx.lineTo(20, canvas.height-20);
ctx.closePath();
ctx.stroke();
ctx.font = "bold 16px Arial";
function getFunctionForTimeout(j){
var i=0,currx=30,info=graphInfo[j],x5=j*5;
var fTimeout=function(){
var h=Math.max(info.data[i]-x5,0);
var m=info.label[i];
ctx.fillStyle='black'
ctx.fillRect(currx+(10*x5)+2,canvas.height-h-20,width+2,h-1);
ctx.fillStyle=info.color;
ctx.fillRect(currx+(10*x5),canvas.height-h-21,width,h);
ctx.fillText(m, currx+(10*x5)+20, canvas.height-5);
currx+=120;
i++;
/*var ctx = $('#mycanvas').get(0).getContext('2d');
$('#mycanvas').click(function(e) {
var x = e.offsetX,
y = e.offsetY;
for(var k=0;k<j;k++) {
if(x > currx+(10*x5)
&& x < canvas.height-h-21
&& y > width
&& y < h) {
alert('Rectangle ' + j + ' clicked');
}
}
});*/
if(i<info.data.length)setTimeout(fTimeout,2000);
};
return fTimeout;
}
for(var j=graphInfo.length-1;j>=0;j--) {
setTimeout(getFunctionForTimeout(j),2000);
}
};
</script>
</head>
<body>
<canvas id="mycanvas" height="400" width="800" style="border:1px solid #000000;">
</body>
</html>
Here is the code for giving you mouse position where you are clicking on the canvas, i just altered your code for correcting it for the alert you are expecting but there is some issue in your condition which you generate as an alert.
Njoy clicking and alerting the mouse position; if you want the same alert you expect, alter your if condition you will get it by my position alert...
<!doctype html>
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.js"></script>
<script type="text/javascript">
window.onload=function() {
var canvas=document.getElementById('mycanvas');
var ctx=canvas.getContext('2d');
var graphInfo=[{data:[120,130,140,160,180,100],color:'purple',label:["a","b","c","d","e","f"]},{data:[100,120,130,140,150,190],color:'green',label:["g","h","i","j","k","l"]}];
var width=45;
function renderGrid(gridPixelSize, color)
{
ctx.save();
ctx.lineWidth = 0.5;
ctx.strokeStyle = color;
for(var i = 20; i <= canvas.height-20; i = i + gridPixelSize)
{
ctx.beginPath();
ctx.moveTo(20, i);
ctx.lineTo(canvas.width-20, i);
ctx.closePath();
ctx.stroke();
}
for(var j = 20; j <= canvas.width-20; j = j + gridPixelSize)
{
ctx.beginPath();
ctx.moveTo(j, 20);
ctx.lineTo(j, canvas.height-20);
ctx.closePath();
ctx.stroke();
}
ctx.restore();
}
renderGrid(10, "grey");
ctx.beginPath();
ctx.strokeStyle = 'black';
ctx.moveTo(20, canvas.height-20);
ctx.lineTo(canvas.width-20, canvas.height-20);
ctx.closePath();
ctx.stroke();
ctx.beginPath();
ctx.strokeStyle = 'black';
ctx.moveTo(20, 20);
ctx.lineTo(20, canvas.height-20);
ctx.closePath();
ctx.stroke();
ctx.font = "bold 16px Arial";
function getFunctionForTimeout(j){
var i=0,currx=30,info=graphInfo[j],x5=j*5;
var fTimeout=function(){
var h=Math.max(info.data[i]-x5,0);
var m=info.label[i];
var ctx = $('#mycanvas').get(0).getContext('2d');
ctx.fillStyle='black'
ctx.fillRect(currx+(10*x5)+2,canvas.height-h-20,width+2,h-1);
ctx.fillStyle=info.color;
ctx.fillRect(currx+(10*x5),canvas.height-h-21,width,h);
ctx.fillText(m, currx+(10*x5)+20, canvas.height-5);
currx+=120;
i++;
$('#mycanvas').click(function(e) {
var canvas = document.getElementById("myCanvas");
var mousePos = getMousePos(canvas, e);
var message = "Mouse position: " + mousePos.x + "," + mousePos.y;
var x = mousePos.x;
var y = mousePos.y;
alert(message);
for(var k=0;k<j;k++) {
if(x > currx+(10*x5)
&& x < canvas.height-h-21
&& y > width
&& y < h) {
alert('Rectangle ' + j + ' clicked');
}
}
});
if(i<info.data.length)setTimeout(fTimeout,2000);
};
return fTimeout;
}
for(var j=graphInfo.length-1;j>=0;j--) {
setTimeout(getFunctionForTimeout(j),2000);
}
function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect(), root = document.documentElement;
// return relative mouse position
var mouseX = evt.clientX - rect.top - root.scrollTop;
var mouseY = evt.clientY - rect.left - root.scrollLeft;
return {
x: mouseX,
y: mouseY
};
}
};
</script>
</head>
<body>
<canvas id="mycanvas" height="400" width="800" style="border:1px solid #000000;">
</body>
</html>
Just check the change in getMousePos() for the same u needed
Cheers!!! Njoy!!!

Categories

Resources