Why's my wheel spinning repugnantly when clicking? - javascript

I'd like to know why the wheel spins like a bent bicycle tire when clicking Spin Now. I've tried a lot of ways to try to rectify this so that it spins normally like the Wheel of Fortune wheel but to no avail.
I tried switching up the image, give it a height and width, slow down the wheel but nothing seems to be working and it feels like I'm running out of options
I think my jQuery code is a bit off and is causing this inconsistent behavior but I could be wrong. How can make the wheel spin normally? A JsFiddle (https://jsfiddle.net/hbxL2s8r/26/) and code below is provided for reference.
Here's HTML:
<div id="spin-now" class="buttons">
<img src="https://i.postimg.cc/28JSM5Kf/spin-now-glow-button-NEW.png" alt="">
</div>
<div id="image-spinner" class="text-center">
<img src="https://i.postimg.cc/nzZz2wwj/wheel-no-glow-v03.png"/>
</div>
Here's my jQuery:
var degrees = 0, previousRotation = 0;
var spinNow = document.getElementById('spin-now');
spinNow.addEventListener("click", function (e) {
console.log("triggered");
$('#spin-now').hide();
previousRotation = degrees;
degrees += parseInt(360 * 10 + 315);
// controls speed of wheel
var milliseconds = parseInt((degrees - previousRotation)) * 1.5;
$("#image-spinner").css({
"-webkit-transform" : "rotate("+ degrees +"deg)",
"-webkit-transition-duration" : milliseconds + "ms"
});
});

Related

fabricjs - creating endless animation loop without lags

I am trying to create an endless animation loop of rotation with FabricJS. It works like this: the rotate function gets animation details (object to animate, duration of one animation loop, starting angle of rotation) as parameters, and invokes inner function rotateInner to launch the animation itself. rotateInner rotates given object using fabric.util.animate with linear easing function (to make rotation speed constant) to run one animation loop and to invoke itself after the loop ends, which results in an infinite animation loop.
The problem is that rotateInner lags every time between animation loops when it invokes itself through fabric.util.animate.
For example, I use animation loop with duration = 1 second and rotation angle = 180 degrees. In that case, animation makes lag every 1 second after rotating by 180 degrees.
I've found a solution to make lag occur N times less. Instead of rotating by 180 degrees for 1 second, I rotate object by 180*N degrees for N seconds. If I pick enough big N, the user will meet lag potentially never. But only potentially.
What are reasons of lags and is it possible to remove lags between animation loops completely? Or, perhaps, I went wrong way, and I should use something completely different to create endless animation loop?
Here's example which demonstrates lag (on jsfiddle). (The rotate function has additional argument - multiplier. It's N I've just wrote about above) Left rectangle rotates 180 degrees per 800 milliseconds, and the right rectangle rotates 180*10 degrees per 800*10 milliseconds, and thus the right one rotates quicker than the left one.
And, if you don't want to use jsfiddle or if example became inaccessible for some reason, here's the example itself in code:
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/3.4.0/fabric.min.js"></script>
<style>canvas {border: 5px dotted black;}</style>
<title>FabricJS animation loop lag</title>
</head>
<body>
<canvas id="mycanvas" width="700" height="300"></canvas>
<script>
var canvas = new fabric.StaticCanvas('mycanvas');
var rectCreationOptions = {
left: canvas.getWidth()/4,
top: canvas.getHeight()/2,
fill: '#0bb',
width: canvas.getWidth()/5,
height: canvas.getHeight()/5,
originX: 'center',
originY: 'center'
};
// creating left rectangle:
var rect1 = new fabric.Rect(rectCreationOptions);
rectCreationOptions.left *= 3;
// creating right rectangle:
var rect2 = new fabric.Rect(rectCreationOptions);
canvas.add(rect1);
canvas.add(rect2);
function rotate(animatedObject, duration = 1000, multiplier = 1, startAngle = 0) {
duration *= multiplier;
var addAngle = 180 * multiplier;
(function rotateInner(startAngle) {
fabric.util.animate({
startValue: startAngle,
endValue: startAngle+addAngle,
duration: duration,
// linear easing function:
easing: function(t, b, c, d) { return c*t/d + b; },
onChange: function (value) {
animatedObject.angle = value;
canvas.renderAll();
},
onComplete: function() {
rotateInner(startAngle+addAngle);
}
});
})(startAngle);
}
rotate(rect1, 800, 1); // lags every 800 ms
rotate(rect2, 800, 10); // lags every 800*10 ms
</script>
</body>
</html>
I will be thankful for help.
Please, don't throw rotten tomatoes at me if I made tiny mistake. This is my first question on stackoverflow. :)
Best wishes everyone.

How to select individual elements with javascript here?

See here: https://siteweb.synergieetvitalite.com/monportfolio/
I would like the smartphone and laptop to come close togheter as the user moves his mouse. The code i am using :
HTML:
<div class="scene">
<div data-speed="51" class="layer layer-middle"></div>
<div data-speed="81" class="layer layer-top"></div>
</div>
JS:
<script> document.addEventListener('mousemove', parallax);
function parallax(e) {
e.preventDefault();
this.querySelectorAll('.layer-middle').forEach((layer) => {
let speed = layer.getAttribute('data-speed');
layer.style.transform = `translateX(${e.clientX * speed / 1000}px)`;
})
}
</script>
I tried to modify this so that .layer-top moves to the right, but then the layer-middle stopped moving alltogheter, probablement because of SelectorAll or forEach. I don't really know javascript so I wasn't able to simply make the function work for each element individually.
thanks for your help!
I think you can remove the foreach and select each element separately like below. So this way you will move the laptop to right and the phone to left or vice versa.
I've changed your code a little. Try it and let me know if its what which you are looking for.
<script> document.addEventListener('mousemove', parallax);
function parallax(e) {
e.preventDefault();
laptop = document.querySelector('.layer-middle');
let speed = laptop.getAttribute('data-speed');
laptop.style.transform = `translateX(${e.clientX * speed / 1000}px)`;
phone = document.querySelector('.layer-top');
phone.style.transform = `translateX(${-1*e.clientX * speed / 1000}px)`;
}
</script>

jQuery "slime menu" - pixel perfect rounding

I've successfully programmed my jQuery slime menu, and now it works beautiful. My only problem is that I move the arrow and the ending circle (the icon) of the slime separately, so if you move the cursor too away from the starting point, it will not connect to the slime precisely. It must be a rounding issue. Here's an image of what I'm talking about:
And here's the fiddle I'm working on:
http://jsfiddle.net/41Lcj653/4/
EDIT (Working): http://jsfiddle.net/41Lcj653/7/
Can anyone help with this issue? I use CSS transformations, and JS for update the CSS rules in each step.
The JS part of the code:
$(function(){
$(window).mousemove(function(e){
moveslime(e);
});
});
function moveslime(e){
var rad = $('.arrow').height() / 2;
var ofs = $('.arrow').offset();
var mPos = {x: e.pageX-25-rad, y: e.pageY-25-rad};
var dir = Math.round( -(Math.atan2(mPos.x, mPos.y)) / (Math.PI/180) );
$('.arrow').css('transform','rotate('+dir+'deg)');
$('.arrow').css('border-width','0 25px '+pdist(0, 0, mPos.x, mPos.y)+'px 25px');
$('.bubble').css('left', mPos.x+'px').css('top', mPos.y+'px');
}
function pdist(x1,y1,x2,y2) {
return Math.sqrt(Math.pow(x1-x2,2)+Math.pow(y1-y2,2));
}
the reason you see this 'not precisely connected' is that rotate goes in 360 steps (the 360 degrees of a circle). when you are near the center the effect can be neglected, but the more you get away from the center (increasing circle circumference!) the visible gap between the degrees increases.
Maybe try this with svg?
actually you can use float numbers a degree .. so dont round the deg!
https://jsfiddle.net/41Lcj653/5/
// without math.round
var dir = -(Math.atan2(mPos.x, mPos.y)) / (Math.PI/180);
Some jQuery method like height rounds decimals. You could try this:
$(".arrow")[0].getBoundingClientRect().height
More information: https://developer.mozilla.org/es/docs/Web/API/Element/getBoundingClientRect

Constrain jquery draggable to stay only on the path of a circle

So Im trying to make something where the user is able to drag planets along their orbits and it will continuously update the other planets. Ideally I would like this to work with ellipses too.
So far I can drag an image node with jquery and check/change the coordinates, but i cannot update the position reliably while the user is dragging the object. I know there is an axis and a rectangle containment for draggable but this doesn't really help me.
I have a site for calculating planetary orbits http://www.stjarnhimlen.se/comp/ppcomp.html and a formula i think should help me if i can figure out how to constrain the draggable object with coordinate checks Calculating point on a circle's circumference from angle in C#?
But it seems like there should be an easier way to have a user drag a sphere along a circular track while it updates coords for other spheres
here's what i have so far. It's not much
http://jsfiddle.net/b3247uc2/2/
Html
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script src="//code.jquery.com/ui/1.11.2/jquery-ui.js"></script>
Js
var $newPosX = 100,
$newPosY = 100;
//create image node
var x = document.createElement("IMG");
x.src = "http://upload.wikimedia.org/wikipedia/commons/a/a4/Sol_de_Mayo_Bandera_Argentina.png";
x.width = 100;
x.height = 100;
x.id = "sun";
x.hspace = 100;
x.vspace = 100;
document.body.appendChild(x);
//coords
var text = document.createTextNode($newPosX + " " + $newPosY);
document.body.appendChild(text);
//make sun draggable and update coords
$("#sun").draggable({
drag: function (event, ui) {
$newPosX = $(this).offset().left;
$newPosY = $(this).offset().top;
}
});
//0 millisecond update for displayed coords
setInterval(check, 0);
function check() {
//tries to constrain movement, doesn't work well
/*
if ($newPosX > 300) {
$("#sun").offset({
left: 200
});
}
*/
text.nodeValue = ($newPosX + " " + $newPosY);
}
Edit:
I found this and am trying to modify it to suit my purposes but have so far not had luck.
http://jsfiddle.net/7Asn6/
Ok so i got it to drag
http://jsfiddle.net/7Asn6/103/
This is pretty close to what I want but can be moved without being clicked on directly
http://jsfiddle.net/7Asn6/104/
Ok final edit on this question. This one seems to work well and have fixed my problems. I would still very much like to hear peoples implementation ideas or ideas to make it work smoother.
http://jsfiddle.net/7Asn6/106/

Articulated animation

I am trying to figure out how to sequence the train animation so I can offset and rotate each wagon in turn around curves, for example, in Route_51 (click Test>Run[twice]) in this display. Needs Chrome or other HTML5 compliant browser.
Here is my so far 'non-complying' code (using KineticJs):
function animate(nr,path,incr,train,dirX,dirY){
var steps,offsetX,offsetY,count,a;
steps = Math.round(path[nr][2] / incr);
offsetX = path[nr][2]/steps;
offsetY = path[nr][3]/steps;
count = 0;
stage.onFrame(function(frame){
layer = train[0].getLayer();
if(count < steps){
for(a=0; a<train.length; a+=1){
incrX = train[a].getX() + offsetX * -dirX;
incrY = train[a].getY() - offsetY * -dirY;
train[a].setX(incrX);
train[a].setY(incrY);
}
layer.draw();
count += 1;
}
else{
stage.stop();
nr += 1;
if(path[nr]){
animate(nr,path,incr,train,dirX,dirY);
}
}
});
stage.start();
}
I don't seem to be able to grasp the logic (getting old).
All help appreciated. Thanks.
It seems a certain amount of time has to pass before some kind of logic emerges.
In this case it was that each loco/wagon needed its own fully incremented path for the starts and optionally finishes to be staggered. Here is a screenshot of the train in motion with the "normal" scale view inset. Room for improvement of course especially with curve coordinates.
For the animation visit http://glasier.hk and follow the KJS link.

Categories

Resources