A-Frame a-animation vs kframe animation__id components behave differently - animation

Code: https://glitch.com/edit/#!/aframe-nyc?path=ballani.html:17:0
Demo: https://aframe-nyc.glitch.me/ballani.html
Description:
I am putting two bouncing balls next to each other Red (left) using kframe animation and Green (right) using the soon deprecating a-animation component
Problem:
Green switches to yellow on the way up, which is the intended behavior.
Red should switch to blue on the way up, but doesn't, what is wrong and how can I fix it?

It works if I use a hash color. I'll look into why a keyword color name doesn't work.
animation__switch="property: material.color; from: #F00; to: #0F0; dur: 1000; delay: 0; dir: alternate; easing: linear; loop: true; autoplay: true"
Note you can get more performant animations this way:
animation__switch="property: components.material.material.color; type: color; from: #F00; to: #0F0; dur: 1000; delay: 0; dir: alternate; easing: linear; loop: true; autoplay: true"

Related

Position circles around a circle given x circles with fixed diameter in SASS

A question of two parts:
End goal is something like this, ala graph DB visualisers - but in html / css/sass
Part 1: How to position x number of circles around a circle so the edges touch (or prefereably, with a little whitespace).
For example, this is what i'm going for given 3, 6 and 7 circles.
I'm trying to get it working using SASS, however if there's a library or something that does what I'm after i'd rather use that - i'm just struggling to formulate the search phrase.
I'm using the trig functions from here, and stole the circle arrangement from here.
CODEPEN of what I've got so far.
I'm bad at maths, but some friends gave me the fomula you'll find below that should work out the distance to the outer circle center. $distance: tan((180-($angle))/2) * $radius;. However its not doing as i expect - given 6 circles, with a diameter of 100 I'd expect an output of 100, but i'm getting 86.602...
Here's the sass - probably easier to look in the codepen though.
#function strip-unit($number) {
#if type-of($number) == 'number' and not unitless($number) {
#return $number / ($number * 0 + 1);
}
#return $number;
}
#mixin on-circle($item-count, $circle-size, $item-size, $break-at) {
position: relative;
height: $circle-size;
padding: 0;
border-radius: 50%;
list-style: none;
>* {
display: block;
position: absolute;
top: 50%;
left: 50%;
width: $item-size;
height: $item-size;
margin: -($item-size / 2);
$angle: (360 / $break-at);
$rot: 0;
$prevLayer: 0;
#for $i from 1 through $item-count {
$layer: ceil($i/ $break-at);
$layerMinusOne: $layer - 1;
// MoveX figured out by aligning stuff by eye
// item-count 3 4 5 6 7 8 9 10 ...12 13 14...20
// moveX (%) 57 70 85 100 115 130 145 160 192 207 225 315
$item-radius: strip-unit($item-size) / 2;
// !! This is where i'm having trouble
$distance: tan((180-($angle * 1deg))/2) * $item-radius;
#debug "tan((180-#{$angle})/2) * #{$item-radius} = #{$distance}";
$moveX: ( $distance / strip-unit($item-size)) * 100 * 1%;
#debug "moveX: #{$moveX}";
#if $layer != $prevLayer {
$prevLayer: $layer;
$rot: $rot + $angle/2;
}
&:nth-of-type(#{$i}) {
transform:
// !! This is where the 'percent of circle diameter' measurements come in, translateX uses the size of the element being transformed when % is used.
rotate($rot * 1deg) translateX($moveX * $layer) rotate($rot * -1deg);
}
$rot: $rot+$angle;
}
}
}
$numOfCircles: 3; // <- Change me in the codepen
.circle-container {
#include on-circle($item-count: 28, $circle-size: 200px, $item-size: 50px,
$break-at: $numOfCircles);
margin: 5em auto 5em;
border: solid 5px red;
.around-a-circle {
text-align: center;
border-radius: 50%;
border: solid 1px #118be1;
}
}
Part 2: The extra layers.
My end goal as seen above is to display x number of circular elements in rings, where the inner most ring is made up of y elements and bubbles out from there.
As i said i'd rather use a library, but i couldn't find anything that does what i want. I was going to use the inner ring as a starting point and each alternating layer, rotate an extra bit and place the element nestled between the previous rings elements, but again i'm struggling with the dimensions, and how much to offset by.
$layer: ceil($i/ $break-at);
...
#if $layer != $prevLayer {
$prevLayer: $layer;
$rot: $rot + $angle/2;
}
The above code does that, mostly, however the spacings aren't optimised and the whitespace is too much compared to my end goal photo.
The distance needs to be between center of circle 1 and center of circle 2 and half that is your radius for all the circles.
I don't know sass so here is a working JS version as proof that this works.
https://jsfiddle.net/hk5spy20/
If you change line 32-33 from
var x1 = pointXY[0].x;
var y1 = pointXY[0].y;
to
var x1 = xPos;
var y1 = yPos;
You will replicate what you are currently doing which results in overlapping circles.
***** Added *****
The way you have the 2nd, 3rd, 4th level bubbles working will become gappy as you expand out because of the radius of the circle increases in size.
It won't work this way.
I have something but require work but I have this so far... https://jsfiddle.net/hd7qp06b/2/
I think for each row you will need two different set of formulas to get this working perfectly, the second row works, the 3rd row doesn't which is where a new formula is required. Will come back to this.
This seems to work: https://jsfiddle.net/eo170zsu/
You have to keep a track of pair adjacent bubbles and attachBubble next to it. If you put the co-ordinate of bubble 9 and 15 on the stack, it'll place new bubble perfectly next to it. However, you can't put bubble 9 and 16 on stack as well because this would cause an overlap. There is a sequence of pairs that are safe and probably be consistent for certain levels, I suspect odd / even levels has different rules for pairing.
Actually, thinking about it, just pair 9,15 and 9,16 process each one and if there is an overlap between two circles on screen, throw it away and try next pair.

Aframe-animation-component direction: alternate bug

I'm using the following code, but can't get the animations to work with direction: alternate. The animations refuse to alternate but always start from their initial value.
<a-entity
gltf-model="models/u323/u323-2k1024.gltf"
position="-0.4 1.7 -1.7"
rotation="-2.7 0 0"
scale="1.2 1.2 1.2"
animation__position="property: position;
dir: alternate;
startEvents: click;
from: -0.4 1.7 -1.7;
to: -0.47272469351429525 2.3 -2;
dur: 2000"
animation__light="property: light.intensity;
dir: alternate;
startEvents: click;
from: 0;
to: 5;
dur: 2000"
>
try adding loop: 2, the second animation should be in the alternate direction:
animation__position="property: position;
dir: alternate;
startEvents: click;
from: -0.4 1.7 -1.7;
to: -0.47272469351429525 2.3 -2;
dur: 2000"
loop: 2

rgba() is producing a blackish tone in HTML5 Canvas Gradient

I wanted to draw three gradients on top of the other on a HTML5 Canvas. But it wasn't not producing the desired effect. So I dug into the thing a little bit, and found out that rgba(0, 0, 0, 0) was not completely transparent when used in canvas gradient. Rather it was producing an unexpected blackish tone.
In CSS, it works fine though.
How can I have the same effect as it works in CSS? (see attached screenshot please)
CSS properties:
background: linear-gradient(rgba(0, 0, 0, 0), rgb(255, 0, 0));
Canvas properties:
var grad = ctx.createLinearGradient(0, 0, 0, height);
grad.addColorStop(0, 'rgba(0, 0, 0, 0)');
grad.addColorStop(1, 'rgb(255, 0, 0)');
Indeed the algorithms seem to be different.
Not quite sure why, but I'd say that CSS doesn't consider rgba(0,0,0,0) as transparent black pixel like canvas does, but instead just as transparent.
The 2D canvas will composite straight from all the 4 RGBA channels values, until the ones of the next stop, while CSS one seems to comprehend transparent as a particular case.
To get the same result as CSS on a canvas, you'd have to set your first transparent stop to the next one, by only changing the alpha value:
var ctx = c.getContext('2d'),
grad = ctx.createLinearGradient(0,0,0,150);
grad.addColorStop(0, 'rgba(255,0,0,0)'); // transparent red
grad.addColorStop(1, 'rgba(255,0,0)');
ctx.fillStyle = grad;
ctx.fillRect(0,0,300,150);
#html{
background: linear-gradient(rgba(0, 0, 0, 0), rgb(255, 0, 0));
height: 150px;
width: 300px;
display: inline-block;
}
<div id="html"></div>
<canvas id="c"></canvas>

Is there a way for me to modify the size of the circle in nvd3's interactive layer?

NVD3's interactive layer has circles/points that highlight a point in the line of a linechart when your mouse hovers over the chart. Is there a way to change the size of that circle? My aim is to make it smaller.
Here are the circles I'm talking about.
By Increasing the stroke-width in css.
.nv-scatter .nv-groups .nv-point.hover, .nvd3 .nv-groups
.nv-point.hover {
stroke-width: 14px; //(7px -> 14 px)
fill-opacity: .5 !important;
stroke-opacity: .5 !important;
}

Accelerated Ball leaving screen (Processing 2.1)

It is supposed to be a balloon going up, stoping when the window ends. I cannot understand why my ball eventually disappears... Somebody help me.... When I try to tune the gravity parameter or the accelereation one, it either starts moving crazy fast (and dissapears), or real slow (eventually dissapears too). I have the checkEdges(), method defined so that this does not happen. Obviously something is not right
Mover mover;
void setup(){
size(300,600);
background(255);
mover = new Mover();
}
void draw(){
background(255,50);
mover.applyForceWind();
mover.applyForceGravity();
mover.update();
mover.display();
mover.checkEdges();
}
class Mover {
PVector location;
PVector velocity;
PVector acceleration;
PVector gravity;
PVector wind;
Mover(){
location = new PVector(width/2,height*0.9);
velocity = new PVector(0,0);
acceleration = new PVector(0,-1);
}
void applyForceWind(){
PVector wind = new PVector(0.001,0);
acceleration.add(wind);
}
void applyForceGravity(){
PVector gravity = new PVector(0,0.1);
acceleration.add(gravity);
}
void update(){
velocity.add(acceleration);
location.add(velocity);
acceleration.mult(0);
}
void display(){
stroke(0);
fill(155);
ellipse(location.x,location.y,30,30);
}
void checkEdges(){
if ( location.x > width || location.x < 0){ velocity.x *= (-1);}
if ( location.y > height || location.y < 0){ velocity.y *=(-1);}
}
}
You had an extra close curly brace in your code, just FYI. The problem with the ball eventually getting "stuck" on the floor and disappearing is due to your checkEdges() code, as you suspected. To shed some light on the issue, try this code:
void checkEdges(){
if ( location.x > width || location.x < 0){ velocity.x *= (-1);}
if ( location.y > height || location.y < 0){
velocity.y *=(-1);
println("velocity: " + velocity.y + "; position: " + location.y);
}
}
And it will give something like this:
...
velocity: -2.3999999; position: 602.1
velocity: -2.3; position: 602.1
velocity: -2.2; position: 602.1
velocity: -2.1000001; position: 602.1
velocity: 2.0000002; position: 600.1
velocity: -2.1000001; position: 602.19995
velocity: 2.0000002; position: 600.19995
velocity: -2.1000001; position: 602.2999
velocity: 2.0000002; position: 600.2999
...
As you can see, the y-velocity at each successive "bounce" is slightly lower than the one before it, meaning that your system is bleeding energy. In particular, when the velocity becomes too low to get it back above the bottom of the screen (it goes below 2.1, which how far it has to go to get back up), it starts behaving erratically. Imagine it goes for a while, and then the next time it has to bounce, it only has a y velocity of -2. It's at y=602.1 > 600, so multiply y velocity by negative one. On the next iteration, it moves up 2 units, so y is now 600.1, but that is still off the screen so it inverts the velocity again! Here's a (crude) picture to illustrate the idea:
The red lines represent the iteration after the velocity was reversed. The length of each red line decreases as time goes on (the ball doesn't bounce quite as high), and eventually it doesn't actually get back above the barrier! At this point, it's still below the bottom of the screen, and so the inversion test still passes, so it turns the positive velocity negative, while it's still below the bottom of the screen.
There are a few ways to fix this:
Prevent the ball from losing energy as time goes on. This can be tricky to do. Here's a clue: if you swap the order of these two lines in your update() function, the ball will gain energy as time goes on! An interesting result.
location.add(velocity);
velocity.add(acceleration);
It doesn't make sense to allow the ball to go below the edge of the window anyway, so if it is there, then force it back up to the edge, ie insert this into your checkEdges() method:
location.y = height;
When I use the second bullet, I get a constant bounce response and no loss of speed as time goes on:
velocity: -3.5999987; position: 600.0
velocity: -3.5999987; position: 600.0
velocity: -3.5999987; position: 600.0
velocity: -3.5999987; position: 600.0
velocity: -3.5999987; position: 600.0
velocity: -3.5999987; position: 600.0
Also, a side note: there is no need to create new wind and gravity PVectors each time you call the methods. In fact, you even declared them as class variables anyways! Set their values in the constructor and then you can use them in your other methods.
Dude, acceleration is constant, but you're adding to it every iteration....

Resources