Variable amount of slices : Pie Chart concept - javascript

This is my image sketch:
Here is a jsfiddle to work on:
<div id="a"></div>
the goal is to divide this circle into variable amount of slices.
for instance if i want 10 slices.. i can just change something to "10"
and it will show me this ring that has been divided into 10 pieces.
or '20' or '50' or '100'.
in other words some way to avoid having to deal with each individual line.
being able to rotate would be a plus.
alternatively.. i also would like the version of this.. within which only the border is divided into X slices.
either would work fine for me.

So came up with a nice little script for you. Fairly straight forward, and should work on any size circle you throw at it.
Used minimalist HTML and took care of the rest using jQuery:
HTML
<div id="a" data-lines="8"></div>
jQuery
$(document).ready(function(){
var numLines = parseInt($('#a').data('lines'));
var theta = 180/(numLines/2);
var center = $('#a').innerWidth()/2 - 1; /*-1 to account for the line width*/
var currAngle = 0;
for(var i = 0; i < numLines/2; i++){
$('<div class="lines" style="' + setAngle(currAngle) +' top: ' + center + 'px;"></div>').appendTo('#a');
currAngle += theta;
}
});
function setAngle(theta) {
return '-ms-transform: rotate('+ theta +'deg); -webkit-transform: rotate('+ theta +'deg); transform: rotate('+ theta +'deg);';
}
Example Fiddle
--Just a side note... the more lines you add the cooler it looks
Also, just playing around and added a spin animation on hover... http://jsfiddle.net/bqah9jex/4/

Here you go http://jsfiddle.net/bqah9jex/10/ .. extra compact Javascript, HTML and CSS code to represent Pie Chart.
HTML
<div id="a"></div>
CSS
#a{width:25em;height:25em;border:1em red solid;text-align:center;
border-radius:50%;background:#fff;position:relative
}
.l{width:100%;border:1px solid black;position:absolute}
Javascript
$(function () {
for (var a = 0, c = 200; c--;) {
var b = "transform: rotate(" + a + "deg)";
$('<div class="l" style="'+ ("-ms-"+ b + ";
-webkit-"+ b + ";" + b + ";") + 'top: 50%;"></div>').appendTo("#a");
a += 194; // number of lines
}
});
Demo result
http://i.stack.imgur.com/gFQZ6.png

Related

Body style Javascript function seems slow

I have made a little Javascript function that changes the background color of the body. However, it seems very slow and jagged when it is run. Does anyone know why and how can I improve the code so it runs smoother?
Please see JSfiddle for working example: https://jsfiddle.net/2s2e737w/
window.addEventListener('scroll', function() {
var fromTop = window.pageYOffset;
document.body.style.backgroundColor = "rgb("+fromTop/5 + ','+fromTop/2 +','+fromTop/3+")";
});
body{
margin:0 ;
padding: 0;
height: 3000px;
background-color:rgb(0,0,0);
}
p{
color:white
}
<p>
Scroll
</p>
Use integer RGB values only, as decimal values are ignored by the browser and this leads to the perceived delay:
document.body.style.backgroundColor = "rgb(" +
parseInt(fromTop/5, 10) + ',' +
parseInt(fromTop/2, 10) + ',' +
parseInt(fromTop/3, 10) + ")";
Percentage values are also acceptable:
https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#rgb

Several rotating divs using Javascript

I need to have several divs and each of them should be able to rotate in four(!) directions independently by mouse click.
From this question (and some other) I've found pretty suitable way to rotate in 4 directions (not in two which is much easier)
Rotate a div using javascript, here is the fiddle
JS:
$(document).ready(function() {
var degree = 0; //Current rotation angle, 0->0, 1->90, 2->180, 3->270
$('.rotating').click(function() {
$(this).toggleClass('rotated' + degree.toString()); //Disable previous rotation
degree = (degree + 1) % 4;
$(this).toggleClass('rotated' + degree.toString()); //Add new rotation
});
});
But it works well only for one rotating element. As soon as I add the second div, it stops working as expected (rotations are not independent, try to click on "A" first and then on "B")
<div class="rotating rotated0">A</div>
<div class="rotating rotated0">B</div>
I assume, the root cause is because I use one "degree" variable and it's shared between my divs. So, that's the question - how can I implement several divs which can be rotated independently?
I've updated the code according to first answers (changed id to class), but initial issue with independence is still in place.
id attribute must be only one. Change id into class.
UPDATED
Here is final code:
$(document).ready(function() {
$('.rotating').click(function() {
var currentDeg = $(this).attr("data-deg");
$(this).css({ '-moz-transform': 'rotate(' + currentDeg + 'deg)'});
$(this).css({ WebkitTransform: 'rotate(' + currentDeg + 'deg)'});
currentDeg = eval(currentDeg)+eval(90);
$(this).attr("data-deg", currentDeg.toString());
//restore
if(currentDeg > 270){
$(this).attr("data-deg", "0");
}
});
});
.rotating {
width: 20px;
height: 20px;
background-color: red;
margin-top: 0px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="rotating" data-deg="90">A</div>
<div class="rotating" data-deg="90">A</div>
Here is your code fixed.
$(document).ready(function() {
var degree = 0; //Current rotation angle, 0->0, 1->90, 2->180, 3->270
$('.rotating').click(function() {
$(this).toggleClass('rotated' + degree.toString()); //Disable previous rotation
degree = (degree + 1) % 4;
$(this).toggleClass('rotated' + degree.toString()); //Add new rotation
});
});
Markup:
<div class="rotating">A</div>
<div class="rotating">B</div>

Filling in the screen with a diamond grid with pure javascript (jsfiddle is available)

Those who solve this will get 150 reputation points once im eligible for a bounty.
https://jsfiddle.net/testopia/xzxe6y5k/
As you can see in the jsfiddle I did some trigonometric calculations to figure out the exact position for the adjacent placements.
The following formula gives me the exact positioning:
elem.offsetHeight * Math.cos(degrees converted into radians) + elem.offsetTop
elem.offsetWidth * Math.cos(degrees converted into radians) + elem.offsetLeft
Of course the same thing is also possible by getting the vertex points, the code would just be larger. Here a small example:
elem.offsetLeft + elem.offsetWidth
elem.offsetTop + elem.offsetHeight
Anyways, I figure that automatic placement is pretty hard. I mean I am trying to achieve something like in the image below: http://www.purplesquirrels.com.au/wp-content/uploads/2015/02/dg.png
Question: So how can I make the diamond grid spread to the full height and width of the screen / container from the center? Not a loop from left to right and top to bottom but starting from the center in a somewhat circular way.
I was able to get the screen filled with two while loops. For now I used some static margins, so the spacings are not perfect, but I guess your computePosition function can help with generating the right spacings between the diamonds.
https://jsfiddle.net/xzxe6y5k/3/
var wrapper = document.getElementById('grid'), diamond = wrapper.children, newDiamond, prevDiamond, evenRow = true;
function createDiamonds() {
while (!newDiamond || newDiamond.getBoundingClientRect().bottom < window.innerHeight) {
evenRow = !evenRow;
prevDiamond = newDiamond;
newDiamond = wrapper.appendChild(document.createElement('div'));
if (prevDiamond) {
newDiamond.style.top = prevDiamond.getBoundingClientRect().bottom + 10 - (newDiamond.getBoundingClientRect().height / 2) + 'px';
if (evenRow) {
newDiamond.style.left = diamond[0].getBoundingClientRect().left + newDiamond.getBoundingClientRect().width / 2 + 7 + 'px';
}
}
while (newDiamond.getBoundingClientRect().right < window.innerWidth) {
prevDiamond = newDiamond;
newDiamond = wrapper.appendChild(document.createElement('div'));
newDiamond.style.left = prevDiamond.getBoundingClientRect().right + 10 + 'px';
newDiamond.style.top = prevDiamond.style.top;
}
}
}
createDiamonds();
#grid div {
background: black;
height: 25px;
width: 25px;
position: absolute;
transform: rotate(45deg)
}
<div id="grid"></div>

Show/Hide Text Every Time An Arrow Is Clicked

I need help showing/hiding text on a button click (specifically an arrow). I have a block of text that I have hidden and I need to slide it down in a time consistent with the arrow rotating 180 degrees. I also want it to do this only for the post above the arrow that was clicked. The solution I have come up with in this fiddle has many problems.
Here is the code:
$(function () {
var angle = -180,
height = "100%";
$(".down-arrow").click(function () {
$(".down-arrow").css({
'-webkit-transform': 'rotate(' + angle + 'deg)',
'-moz-transform': 'rotate(' + angle + 'deg)',
'-o-transform': 'rotate(' + angle + 'deg)',
'-ms-transform': 'rotate(' + angle + 'deg)',
});
$(".blog-post").animate({
'height' : height
});
angle -= 180;
height = "50px";
});
});
And these are the issues I am having:
It slides down way too fast
Once it slides back up it won't slide down again.
It does it for every post
This would be more dynamic and clean to use:
First we will take height's of all the .blog-post div's in an array.
Now making height: 50px of the div, after once we know actual height of all the div's. Which will helpful in making div smooth slide as we know height's.
Next on click of arrow class, we will toggle class which holds transform:rotate properties. Along with that we would check corresponding .blog-post div's height. So if it is more than 50px we would make it 50px, else we would take it's actual height from array and give to it.
Here is the JS/JQuery Code:
var totalNum = $('.blog-post').length; // Counting number of .blog-post div on page.
var i, myArray = [];
for (i = 0; i < totalNum; i++) {
var curHeight = $('.blog-post:eq(' + i + ')').outerHeight();
myArray.push(curHeight);
}
$('.blog-post').css('height', '50px');
$('.down-arrow').click(function () {
$(this).toggleClass('invert');
var index = $('.down-arrow').index(this);
var heightCheck = $('.blog-post:eq(' + index + ')').outerHeight();
if (heightCheck < 51) {
$('.blog-post:eq(' + index + ')').css('height', myArray[index] + 'px');
} else {
$('.blog-post:eq(' + index + ')').css('height', '50px');
}
});
Working : Fiddle
If you still do not understand feel free to ask.
I guess you should convert the 100% to pixels (with $(this).parent().innerHeight() or something like that, then it works well.
You should build some sort of toggle: keep track of which blog-post/arrow is up and which one is down (flag the blog posts or the arrows with some sort of class) and based on that, you should let it slide up or down.
Of course, you're referring to the post with a css selector. You should use a combination of $(this), .next() and .prev() functions in order to get the right post(s).
"It slides down way too fast"
Just set an animation duration. See the jquery.animate() documentation.
It seems that jquery is pretty buggy when it comes to animating using percentages. http://bugs.jquery.com/ticket/10669 http://bugs.jquery.com/ticket/9505 Try using pixels instead of percentage http://jsfiddle.net/8obybt1d/1/
"Once it slides back up it won't slide down again."
Because you are not changing the value of height back to hundred%
A rough piece of code:
if (height == "50px") {
height = "100%";
}
else {
height == "50px"
}
"It does it for every post"
Try using the 'this' keyword.
To solve point 2:
$(".blog-post").animate({
...
height = (height === "50px") ? height = "100%": height = "50px";
});

Collision detection of two balls using images

I am a beginner in JS programming and I have an assignment to do something like a screensaver.
I already have two balls bouncing around on the screen but I need an algorithm to make them bounce off each other. I went through the articles here but the code is not sufficient.. or at least for me. Here is the code.
<html>
<head>
<style type="text/css">
.b {position:absolute; left:0px; top:0px; width:50px; height:50px;}
.c {position:absolute; left:0px; top:0px; width:50px; height:50px;}
</style>
<SCRIPT language="javascript">
var x =Math.random();
var y =0 ;
var h =12;
var v =22;
var g =1;
var r =0;
var q =0;
var gg = 0;
var u = Math.random() ;
var i =222;
var o = 12;
var p = 22;
var l =1;
var k =0;
var j = 0;
var mm = 0;
var height=window.innerHeight;
var width=window.innerWidth;
function moveball()
{
var b1 = document.getElementById('ball');
v=v+g;r=q;q=y;
if(y==r&&y>394&&g==5)return;
x=x+h;y=y+v;
if(x>width){x=width;h=h*-1;}
if(y>height){y=height;v=v*-1;}
if(x<0){x=0;h=h*-1;}
if(y<0){y=0;v=v*-1;}
if(v==-26&&gg==5){gg=0;g=5;}
b1.style.top=y + 'px';
b1.style.left=x + 'px';
var b2 = document.getElementById('ball2');
p=p+l;k=j;j=i;
if(i==k&&i>394&&l==5)return;
u=u+o;i=i+p;
if(u>width){u=width;o=o*-1;}
if(i>height){i=height;p=p*-1;}
if(u<0){u=0;o=o*-1;}
if(i<0){i=0;p=p*-1;}
if(p==-26&&mm==5){mm=0;l=5;}
b2.style.top=i + 'px';
b2.style.left=u + 'px';
t=setTimeout("moveball()",32);
}
</script>
</head>
<body onLoad="moveball();" >
<div id="ball" class="b"><img src="ballA.gif" width="50" height="50"></div>
<div id="ball2" class="c"><img src="trol.png" width="50" height="50"></div>
</body>
As far as I can understand my problem is that I am not handling balls that have been created by js2Draw but I am using images of balls. If you have any idea how I can do that please help I am desparate.
Right now your code allows the balls to bounce off the "walls" of your screen, but not each other. What you need to do is calculate when they get too close - that is, their centers are closer than their diameter apart.
You're making life more difficult for yourself (and for me...) by using an inconvenient naming convention - instead of having x1, x2 for the x coordinate of balls 1, 2 (even better, have x[i] for the coordinate of the ith ball), you are using different letters. I won't try to fix that but I would recommend you will get better code when you use sensible variables.
So right now you have an object at (x,y) with velocity (h,v), and a second object at (u,i) with velocity (o,p). We need to know if these two objects will "collide" during the next move step. That is - is the distance of these balls after their move step closer than 50? If a collision occurs, we can swap the velocities of balls 1 and 2 - that is approximately what happens in an elastic collision:
var xnew = x + h;
var ynew = y + v;
var unew = u + o;
var inew = i + p;
var newDist = Math.sqrt(Math.pow(xnew-unew,2) + Math.pow(ynew-inew,2));
if (newDist < 50) {
v1x = o;
v1y = p;
o = h; p = v; h = v1x; v = v1y;
}
I added these lines just before you update b2 position, and it shows that things "pretty much" work. You would want to re-arrange your code a little bit so you do this calculation before updating either position of b1 or b2, but the general gist should be obvious from this code (which does seem to produce roughly what you want, even if the physics isn't quite right - but then this is a screensaver, not a physics experiment).

Categories

Resources