I have a client project I inherited that uses javascript to create various animation effects while the user scrolls down through the site (sort of like a parallax site).
The problem with it is that it changes the values in pixels, and what we want it do now is user percentages.
For example, this code brings the #location-left div in from the left, by increasing its width from 0 to 750px, when user scrolls down 1800 pixels. It does this over a 200px interval. It achieves this by writing inline CSS into the DIV tag.:
{
selector: '#location-left',
startAt: 1800,
endAt: 2000,
onEndAnimate:function( anim ) {},
keyframes: [
{
position: 0,
properties: {
"top" : 0,
"width" : 0
}
},
{
position: 1,
properties: {
"top" : 0,
"width" : 750
}
}
]
}
What I want it to do, instead, is go from 0% to 50%. My initial thought was to calculate up a set of var tags:
var a = $(document).width();
var a3= Math.floor(a * 0.3); // 30%
var a5= Math.floor(a * 0.5); // 50%
var a8= Math.floor(a * 0.8); // 80%
etc.
Before I got too far down that rabbit hole, though, I wanted to see if there was an easier approach that I was just missing.
See this question. You can just put the percentages in quotes, like:
{
position: 0,
properties: {
"top" : "10%",
"width" : "30%"
}
},
Related
Problem:
So, made a digital story with illustrations. I pieced it all together by using simple waapi css animations, that gives a parallax effect. Problem with my code is that all my content/images is placed on a timeline in relation to a offset value between 0 and 1. This makes the whole story blast trough in one fast scroll motion on the trackpad/scrollwheel :(
Tried various css and js methods to smooth and slow down the scroll without luck.
How can I best write this so the scroll is slowed down?
Demo (Best in 1440px900px window): https://andyradall.github.io/andylax/
Source code git: https://github.com/Andyradall/andylax
Source code in Jsfiddle: https://jsfiddle.net/Andyradall/yLvboa6t/8/
Example of javascript code for one of the images:
// Settings for animations length
const animasjonSettings = {
duration: 12000,
fill: "both"
}
// Settings for one of the images
const tekstboks3 = document.querySelector("#tekstboks3");
const tekstboks3Keyframes = [
{top: "2.5rem", left: "-22rem", opacity: 1.0},
{top: "2.5rem", left: "-22rem", opacity: 1.0, offset: 0.41},
{top: "2.5rem", left: "3rem", opacity: 1.0, offset: 0.46},
{top: "2.5rem", left: "3rem", opacity: .01, offset: 0.7},
{top: "2.5rem", left: "3rem", opacity: .01,}
];
const tekstboks3Animasjon = tekstboks3.animate(tekstboks3Keyframes, animasjonSettings);
// Start all animations in array on scroll
function animerAlle() {
const y = scrollY;
for(const animasjon of animasjoner) {
animasjon.currentTime = y * 3;
}
}
document.addEventListener("scroll", animerAlle);
I'm not 100% sure since i don't have a tactile device, but I could make the scroll longer (and thus, slower) only by changing these two properties of your code (multiplying by 2 but you can try other operations...)
/* index.css */
body {
height: 1530vh; /* 765 * 2 = 1530 */
background: #7DD3E2;
}
// index.js
// Innstilling for animasjonslengde
const animasjonSettings = {
duration: 24000, // 12000 * 2 = 24000
fill: "both"
}
don't know if it's what you want...
Besides, really good job your site is amazing!
[edit]
for the smooth part, you can look into scroll-snap property but I fear it would make more harm than good
I have two elements whose position and size I am trying to exchange on click of the second element only
<div id="card-1" class="1">
Some Content for 1
</div>
<div id="card-2" class="2">
Some Content for 2
</div>
using jquery path js
$(document).on('click', '.2', function(){
var path_1 = {
start: {
x: 0,
y: 0,
angle: -120
},
end: {
x:0,
y:360,
angle: -120,
length: 0.25
}
}
var path_2 = {
start: {
x: 0,
y: 0,
angle: -180
},
end: {
x:0,
y:-360,
angle: -60,
length: 0.25
}
}
$(".1").animate({
width: "-=50%",
path : new $.path.bezier(path_1)
}, 2500);
$(".2").animate({
width: "+=100%",
path : new $.path.bezier(path_2)
}, 2500);
var x = $('.2').attr('id');
var y = $('.1').attr('id');
$('#'+ x +',#'+ y +'').toggleClass('2 1');
});
Then I exchange the classes as you can see in the last 3 lines of code to get the same effect.
The first time when i click on #card-2 (class 2), the position and size gets exchanged, and also the classes are toggled for the divs but, the when I click on #card-1 (class 2), I do not get the same effect. How do get the same effect again?
This is how my page looks at first
I want #div1 to shrink and go to where #div2 is currently and #div2 to grow and reach where #div1 is currently on click of #div2. Something like this
This is happening. but thin I want the divs to get back to their original position on click of #div1. Something like this.
But this is not happening.
I have used classes for the animation and so after first step, I am exchanging the classes. But instead I am getting this type of result
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
});
I have elements on a page that I want to animate in to view, but after they've animated in, I want to defer further animation on them to CSS (by changing classes)... I am finding that Velocity leaves all my animated properties in the style= tag and makes CSS transitions impossible.
I have a solution below, but resetting the CSS on complete seems iffy, I was wondering if there's a better way to do it?
// first use CSS to hide the element and squish it
$el.css({
width: 0,
left: "-10px",
opacity: 0,
marginRight: 0,
transition: "none"
})
// now animate the width and margin (do this first
// so there's a little gap between existing elements
// before we fade in new element.
.velocity({
width: width,
marginRight: margin
}, {
queue: false,
duration: 230
})
// then fade and move in the new element,
// but this is the iffy bit when it completes
// I have to unset all the styles I've animated?
.velocity({
left: 0,
opacity: 1
}, {
queue: false,
duration: 100,
delay: 130,
complete: function(els) {
$(els).css({
width: "",
left: "",
opacity: "",
marginRight: "",
transition: ""
});
}
});
Typically, you want animation engines to leave styles inline; otherwise final values will pop as they get overwritten by stylesheets upon removal.
You can also do $(els).attr("style", ""); to just clear all styles.
Is there a way to hook into the MooTools Slider class, so the starting position of the knob is at the bottom (step 0) of the bar and you drag the knob up to get to the top of the bar (step 100).
This is what I have so far:
var slider1 = new Slider('#bar', '#knob', {
offset: 6,
steps: 100,
mode: 'vertical'
});
And what I need:
slider1.startingPosition = 'bottom';
Or something to that affect.
Since steps is defined to 100, your max value is 100, which is what you want to set as initialStep (the slider starting point).
For your specific CSS I would remove (or add it womewhere else) the margin on the element of the slider, so it wont shift the slider.
This worked for me:
var slider = $('bar');
var slider1 = new Slider(slider, slider.getElement('.knob'), {
offset: 6,
steps: 100,
initialStep: 100,
mode: 'vertical',
onChange: function (step) {
console.log(step);
}
});
And changed also margin top here to 0px: margin: 0px 0 0 -7px;
Fiddle