Restrict Javascript Rotation Angle (With Propeller.js) - javascript

I am trying to figure out how to use propeller.js to restrict the rotation angle of an image. As of right now, if I spin my image twice, my output would read 720. I would like to make it so the element’s output will reset to 0 when spun over 360. In addition, I would like it to not output negative angles if I spin counterclockwise. For example going from 10 to 280.
Here is a codepen of where I am currently at: http://codepen.io/anon/pen/YyZaXK
$('img').propeller({inertia: 1, speed: 10,onRotate: function(){ console.log(this.angle); }});
Any suggestions?
Thanks!

Figured it out!
Using a Modulo made this work the way I wanted!
Here’s what I added:
(degrees + 360) % 360
Which resulted in:
$('img').propeller({inertia: 1, speed: 10,onRotate: function(){ console.log((this.angle + 360) % 360); }});

Looked in the Propeller.js source, found another solution. You can set zero angle if 360 is reached:
onRotate: function(){
if(this.angle===360)
{
this.virtualAngle = 0;
}
console.log(this.angle);
}

You could also make use of the normalizeAngle() method of Propeller itself:
onRotate: function () {
console.log(this.normalizeAngle(this.angle));
}
That also avoids negative angles.

Related

How to normalize the compass input?

I want to rotate the compass image according to the degrees I receive. The input degrees are between 0 and 359 so when I rotate -1 degree from 0 , the image rotates one complete round and sets on 359:
function setCompass(degrees){
$("#compass").stop().transition({rotate: -1*degrees +'deg'});
}
I tried to solve the problem by going back to -1 instead of 359 so I changed the code to the following:
function setCompass(degrees){
if (degrees>180){degrees=degrees-360}
$("#compass").stop().transition({rotate: -1*degrees +'deg'});
}
It solved the lag on 0 and 360 but the problem was shifted to 180. Now when I rotate the device from 180 to 181, it rotates a complete negative round to go back to -179 ! Please suggest me how to modify the calculations so I get smooth changes on every degree?
You could use some modulo formula to find out whether to turn clockwise or anti-clockwise. Persist the current angle with jQuery's data method (so you could have more than one such compass if you wanted to), and allow the angle that you pass as CSS value to be outside the 0-359 range.
Here is how it could work:
function setCompass(degrees){
var curr = $("#compass").data("rotation") || 0;
var next = curr + ((degrees - curr)%360 + 180*3) % 360 - 180;
$("#compass").data("rotation", next).stop().transition({rotate: -next + 'deg'});
}
// Demo with randomly generated angles between 0 and 359
setInterval(function() {
setCompass(Math.floor(Math.random()*360));
}, 1000);
<img id="compass" src="https://i.stack.imgur.com/zdHVn.png" width="100px" height="100px">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.transit/0.9.12/jquery.transit.min.js"></script>

Stack "transform: translateY" values in GreenSock?

I just came across this wonderful product and realized this is exactly what I need! I have a huge image that is x times the window size, so I want to scroll to the very bottom of it on button click. I would do so with CSS like this:
#keyframes {
to {
transform: translateY(-100%) translateY(100vh);
}
}
This proved to be a crossbrowser way in CSS instead of:
transform: translateY(calc(-100% + 100vh));
Is there any way to do so with TweenMax? I do understand that I can calculate these values in pixels and specify them explicitly:
var value = -$('img').height() + $(window).height();
var tweenDown = TweenMax.to("img", 5, {y: value});
However the advantage of the "stacked" way is that when you resize the window, it keeps the image in the same position.
Thanks in advance!
This is what I came up with for those wondering:
TweenMax.to('img', 5, {
transform: 'translate3d(0,100vh,0)',
percentY: -100
});
[My solution to the bottom]
Actually, with current version of GSAP I think this would be
TweenMax.to('img', 5, {
y: '100vh',
yPercent: -100
});
But, the 'the notes about transforms' documentation section says
To do percentage-based translation use xPercent and yPercent (added in version 1.13.0) instead of x or y which are typically px-based
https://greensock.com/docs/Plugins/CSSPlugin
Judging by the above,
I think 100vh for y would be interpreted as 100px when added in the css matrix property. In order for this to fully work, I opted for the following:
TweenMax.to('img', 5, {
y: window.innherHeight, // or $(window).heigth()
yPercent: -100
});

Add curved path on left / right arrow in JavaScript

if(game.pressedKeys[37]) {
this.ship.x -= this.shipSpeed * dt;
}
if(game.pressedKeys[39]) {
this.ship.x += this.shipSpeed * dt;
}
This code works very well. But I want, scroll path be curved. A kind of like this:
What should be my solution? How can I solve this? Thanks.
You always know the x position of your ship. Create a function that takes an x position and returns a y.
The curve you have could be represented by the parabolic function y=a(x-s)^2+b where a is the vertical stretch, s is the sideways shift, and b is the vertical shift.
Here I created such a function that works for a screen width of 500, and the ship goes up to a max of 150
function parabolic(x) {
return Math.pow((((1/20.412415)*x)-12.24745),2)+150;
}
//I am using ugly numbers, however you can have a variable `w` for the screen width
Here is a working demo: JSFiddle (Click on the canvas for keyboard to work)
document.addEventListener('keydown', function(e) {
if(e.which===37) {
ship.x--;
} else if(e.which===39) {
ship.x++;
}
ship.y = parabolic(ship.x);
update();
})

How to animate slide left smoothly?

I have the following
$('.left_arrow').hover(function() {
$('.chart').stop().animate({
left: "+=10"
});
},
function() {
$('.chart').stop();
});
And I want to have it when you mouse over the arrow it smoothly moves the .chart to the left, and the right arrow it moves it to the right. I am doing this by applying a - left (-7500px is the max) to move it to the left and a 0 is the farthest it can go right.
The above moves it over 10, but it doesn't keep on moving it. How can I get it so it keeps on moving it. I was using something like
$('.left_arrow').hover(function() {
$('.chart').stop().animate({
left: "-7500px"
}, 20000);
},
function() {
$('.chart').stop();
});
But the problem is if I am say -6500px over it takes 20 seconds to go the rest of the 1000, vs 20 seconds to go the full distance. So the speed is skewed, I want a standard increment.
Basically what you need is a rate function. I had the same issue when I was creating my carousel.
rate = distance/time
So, your rate is 0.375
Now, all you will need to do is find the distance and you can adjust your timing accordingly.
time = distance/0.375
So it should look something like this:
$('.left_arrow').hover(function() {
var distance = /*Get Distance Remaining*/
var sd = 7500;
var time = 20000;
var rate = sd/time;
var time = distance/rate
$('.chart').stop().animate({
left: "-7500px"
}, time);
},
function() {
$('.chart').stop();
});
Obviously it would need some tweaking to get just right. But the concept is there.
For my situation, because I was using a <ul> since it was a carousel this is the way I got distance:
distance = Math.abs($ul.position().left);
Not fully understanding the question, but you can increment/decrement animations like so:
$('.chart').stop().animate({
"left": "+=100px"
}, 250);
Note the += operator.
EDIT: This answer is only partially correct. Animation behavior on hover is not as desired. Trying to solve.

Animation starts moving out of position after some time

I am trying to create a sort of slideshow animation. I have the codes here: jsFiddle.
These tablets would rotate around.
The problem is that, at random times, the animation will move out of line. The wrong tablets undergo wrong animations. Here are the screenshots:
And this is how it looks like when the animations goes wrong
The main problem is I don't understand why the animation would go wrong random times. In my computer it will run properly for hours, but in other cases (especially on Safari).
You could store the expected final css values for each animated el and then in the animate callback set these values, so for each animated el something like
var el = $(selector);
el.data("finalCSS", { your expected final CSS values })
$("selector").animate({animation properties}, function() {
el.css(el.data("finalCSS")).data("finalCSS", undefined);
})
This doesn't help with figuring out why it's happening (but I can't recreate the issue myself), but provides a failsafe to make sure the layout doesn't break;
I believe this happens when you try to animate before the previous animation has ended. Use jQuery stop() just before you animate. For example:
$('#animatingDiv').stop(false, true).animate({height:300}, 200, callback);
The first param(false) will empty the animation queue on that element and the second param(true) will jumps to the end of current animation before starting a new animation.
You can do this with far less code and far fewer headaches.
1. Store your tablet position attributes in classes
.tablet1{
height:100px;
width:140px;
margin-left:-540px;
top: 200px;
z-index:10;
}
2. Use a general function to handle all your transitions.
JQuery UI will do all the work for you if you use switchClass
switchTabletsRight = function(){
var i, next, max = 5;
for(i = 1; i <= max; i++){
next = (i < max)? i + 1 : 1;
$(".tablet" + i).switchClass("tablet" + i, "tablet" + next);
}
};​
Here's the JSfiddle proof of concept: http://jsfiddle.net/nRHag/4/
You are setting CSS positions to decimal values.
img_w = $("#tablet"+num+" img").width();
img_w = img_w *140 / 600;
img_h = $("#tablet"+num+" img").height();
img_h = img_h *140 /600;
...
var new_width = $(this).width() * 140 / 600;
$(this).css('width', new_width);
var new_height = $(this).height() * 140 / 600;
$(this).css('height', new_height);
Your division could be cause decimal results which have different effects in different browsers. Sub pixel CSS positioning may be creating your unintended errors.

Categories