mciastek / sal Goto Github PK
View Code? Open in Web Editor NEW🚀 Performance focused, lightweight scroll animation library 🚀
Home Page: https://mciastek.github.io/sal/
License: MIT License
🚀 Performance focused, lightweight scroll animation library 🚀
Home Page: https://mciastek.github.io/sal/
License: MIT License
There is an example in the documentation regarding different options for specific viewport sizes.
const scrollAnimations = sal();
// Provide new options
scrollAnimations.reset({
selector: 'animated-element',
once: true,
});
I am not sure I understand the logic. I want to disable animations on mobile. Is there any way to do it?
Sal.js does not work correctly if the animated element is larger than the viewport, because the threshold values implicitly suppose that the element is smaller than the viewport.
E.g. if you have an element with the height of three times the viewport, Sal.js will never trigger with a threshold of 0.5, because the largest overlap is 0.3333 in this case.
Sal.js should not use one global threshold for all elements. Instead Sal.js should individually check each element if it is larger than the viewport, if so recalculate the threshold, else use the original threshold.
Here is an example code for this logic taken from a post on StackOverflow
function doTheThing (el) {
el.classList.add('in-view');
}
const threshold = 0.5;
document.querySelectorAll('section').forEach(el => {
const elHeight = el.getBoundingClientRect().height;
var th = threshold;
// The element is too tall to ever hit the threshold - change threshold
if (elHeight > (window.innerHeight * threshold)) {
th = ((window.innerHeight * threshold) / elHeight) * threshold;
}
new IntersectionObserver(iEls => iEls.forEach(iEl => doTheThing(iEl)), {threshold: th}).observe(el);
});
I am trying to load the library for use in WordPress. I am enqueuing sal.css
and sal.js
from the dist folder and also a sal-init.js
file that has the sal();
initialization function. In a WordPress page, I use the block editor and I am adding custom attributes to a block through an addon.
data-sal="slide-up"
data-sal-delay="300"
data-sal-easing="ease-out-back"
I can see the scripts enqueued in the header and the attributes added to the element:
<div class="gb-container gb-container-9b1bc616" data-sal="slide-right" data-sal-delay="300" data-sal-easing="ease-out-back"> ...
</div>
but the animation doesn't work, the element is invisible (probably the animation hasn't been completed) and I get an error in the console:
sal.js?ver=5.6:1 Uncaught TypeError: Cannot read property 'classList' of null
at h (sal.js?ver=5.6:1)
at w (sal.js?ver=5.6:1)
at sal-init.js?ver=5.6:1
I must be doing something wrong, right?
Really nice framework thanks!
I've got one problem. I want to change a class on another element when data-sal is fired, they are not related to the data-sal objects. At the same time I want to use the features that sal.js provides.
So its fired once but not the second time:
HTML:
<nav id="nav" class="p-4 w-full fixed nav" Nav</nav>
<div data-sal class="whiteMenu bg-gray-300 h-screen">ds</div>
<div class=" bg-gray-500 h-screen">ds</div>
<div class=" bg-gray-500 h-screen">ds</div>
<div data-sal class="whiteMenu bg-gray-300 h-screen">ds</div>
<div class=" bg-gray-500 h-screen">ds</div>
<div class=" bg-gray-500 h-screen">ds</div>
<div data-sal class="whiteMenu bg-gray-300 h-screen">ds</div>
The script tag:
sal({
threshold: 0.01,
once: false
});
const whiteMenu = document.querySelector('.whiteMenu');
var nav = document.getElementById("nav");
whiteMenu.addEventListener('sal:in', ({ detail }) => {
alert('white');
someOtherStuff();
});
whiteMenu.addEventListener('sal:out', ({ detail }) => {
alert('black');
someOtherStuff();
});
I would like to be able to have animations running once on almost every elements, except some. Currently, the once
option is global. What about supporting an individual option (via data attributes) for specific elements?
Something like <div data-sal="fade" data-sal-repeat></div>
const onIntersection = (entries, observer) => {
entries.forEach(entry => {
if (entry.intersectionRatio >= options.threshold) {
animate(entry);
if (options.once && entry.target.dataset.salRepeat === undefined) {
observer.unobserve(entry.target);
}
} else if (!options.once || entry.target.dataset.salRepeat !== undefined) {
reverse(entry);
}
});
};
Is there currently a way to designate certain threshold per target? I'd like to do something like data-sal-threshold
for some elements.
Hi, I'd like to use this with Shadow DOM and would like the option to set the root node of the observer or the ability to pass a list of elements as an alternative to the current string selector option and just type check on init. I know Intersection Observer has a root option also, but which would work. I think IO on the body penetrates shadow DOM, so passing elements would probably work best.
Hello,
Currently have this install on my website with some slide and flip animations and it is causing a horizontal scrollbar to appear only on mobile. I have the "once" property set to true meaning after I scroll down all the way and load all of the animations the scrollbar goes away. Is there some css styling I have to have? or is this a bug with sal.js
Hi,
I am designing a website with sal animation and everything is working fine and the contents displays fine
When browsing with a Ultrawide (2560 pixels), the "slide-up" animation is never triggering. I have to reduce window size, trigger the animation and when I maximize the window again, the content is displaying fine.
Any ideas ?
<div class="col-12 col-md-10 " data-sal="slide-up" data-sal-duration="700">
Currently when IntersectionObservers is not available, sal disables the animations gracefully but throws an Error afterwards.
This causes it to show up in Sentry, but more importantly, when it is bundled with other scripts (in my case by WP Rocket) all other scripts in the same file are not executed anymore.
Would you consider adding an option to disable the error and just let sal.js exit silently?
i'm using sal.js in gridsome (vue.js) application, when an event fires siblings animated elements automatically hides
I installed the plugin as directed in the readme file.
I initially included the css and js files in the angular.json file, but for some reason it was not seeing it, complains about Sal not defined.
I then copied the entire sal.js folder from my node_modules folder into my assets folder and linked to the files from my index.html file, it now finds it, but when I add the data-sal attribute to any element, using either fade, slide-up or any other value, the element disappears from the screen,
On inspecting I realized the data-sal somewhere in the scss turns the opacity of the element to 0, if I manually change it, the animation does not work.
After installing Sal with npm, call Sal by using
import sal from "sal.js";
in <script>
tag, then use
mounted() {
sal();
}
method. After that you can use Sal attributes but do not forget to import Sal.css!
So I'm using this on a site and its been working perfectly well. I decided to see what would break on the site when the user has js disabled, ideally most things would work since it's just a static site but everything element with data-sal
is not displayed (but are still in the DOM after checking devtools).
It's a gatsby site and I'm using the gatsby-plugin-scroll-reveal which calls this library. Just wanted to know how you would recommend getting around this.
My sals are working in my local machine but when i upload in github
the sals.js and sals.css unable to load.
Example:
1. Firefox browser error : Loading failed for the <script> with source
2. Google Chrome: Failed to load resource: the server responded with a status of 404 ()
On my Shopify collection page, as the user scrolls down products get loaded into the DOM. These products however, stay hidden when I try to animate them with Sal.js. I previously used AOS where this problem did not occur (looking to change to Sal since I am experiencing some weird bugs under iOS14 with AOS).
I uploaded a Gif of the problem here
"gatsby": "^2.19.7",
"gatsby-plugin-scroll-reveal": "0.0.6",
On first load page the items are revealing with animations and with no problems. But if I change to another page (client protected routes) and go back to my animated page, the items wont appear again,
Thanks for this create library. It works great!
I am using it for a project that requires IE11 support, so following your note I added the Intersection Observer polyfill. That did fix the Intersection Observer, however IE11 was also triggering an error for the CustomEvent. So I found a nice polyfill for that (https://github.com/kumarharsh/custom-event-polyfill) which did the trick. So I propose adding another note for this polyfill to help support older browsers.
I have everything imported into my page but keep getting the following errors:
GET http://10.0.0.249:8080/t2m/wp-content/themes/t2m/css/~sal.js/sal.css net::ERR_ABORTED 404 (Not Found) sal.js:6 Uncaught TypeError: Cannot set property 'sal' of undefined at sal.js:6 at sal.js:7 (anonymous) @ sal.js:6 (anonymous) @ sal.js:7 (index):330 Uncaught ReferenceError: sal is not defined at (index):330
I can't get this running in IE 11 although I polyfill my build with the IntersectionObserver.
Can somebody provide a solution/configuration for this? Your documentary only tells that I have to use the IntersectionObserver polyfill, but not how to get it running after that.
I have a question, can I animate elements in a group (children)? If so, how to do it? I would like to combine animation with a group of the same elements, but so that each subsequent one starts with a slight delay. Something like staggering (gsap)
Hey,
I've just started using Sal and I love it! I actually have a feature request; I'd love to implement it myself as well.
I had to disable certain animations on mobile vs. desktop, so having responsive animation classes would be great. I'd love to do that if you want!
Let me know if you're interested!
I'm getting this issue when I apply sal.js to my project.
I included the file in the header and run sal(); in the header as well.
Line 161 in 3833c57
I would like to have a DOM event fired whenever intersection occurs. It should be trivial to add such functionality. Let me know if you are willing to add, and I can submit a PR for it.
I've using the library for 2-3 days and I observed that if the data-sal-delay property is set to a value greater than 1000 then the animation doesn't work.
I have a suggestion: instead of having fixed choices for duration and delay, use CSS custom properties instead.
Change the CSS to:
[data-sal] {
transition-duration: var(--animation-duration, $sal-animation-duration);
transition-delay: var(--animation-delay, $sal-animation-delay);
}
This gives you the existing default values, but overriding them is much easier:
<div data-sal="fade" style="--animation-duration: 2000ms">...
Hi!
Could you publish the scss file to NPM, so it can be imported?
Thank you
When using once:false with slide-up slide-down it can cause the image to go in an infinite loop because the class keeps getting removed and added again since the image is on the border of the screen.
const onIntersection = (entries, observer) => {
entries.forEach((entry) => {
if (entry.intersectionRatio >= options.threshold) {
animate(entry.target);
if (options.once) {
observer.unobserve(entry.target);
}
} else if (!options.once) {
reverse(entry.target);
}
});
};
Part that causes the issue.
EDIT: removed image cause it showed nothing decent. Great little library btw!
EDIT EDIT: i meant ONCE:FALSE !!!
Hi @mciastek,
Trying to use your library in my angular 5+ project import sal from 'sal.js';
I get the next error :
(TS) Module "node_modules/sal.js/index" has no default export.
Thanks
Hi Mirek,
so I have some custom transitions set and it seems that I cannot use your library together with my css on the same element. What I did is that I added extra div and one element is for my css and the second is for sal.js.
Is there a different fix for this?
When testing different scenarios on my website I noticed if JavaScript is disabled or sal.js couldn't be loaded for some reason, the animated elements are staying invisible.
On my sites I’m usually detecting disabled js with removing a „no-js“ class from the html tag and loading a different css-file. But this doesn’t solve the problem if js is enabled but Sal.js couldn’t be loaded, so I think it would be a simple and effective but really useful feature for sal.js to have a „native“ way for creating a fallback.
I’m not sure what the best practice would be for sal of the following two simple ways:
having a specific class on the html element which is removed if sal is loaded. So there only a class must be added in manually/not by sal.js, which has the advantage that the according css is smaller as the additional class is only needed for the fallback-part and no additional class has to be included when creating additional/custom animations.
adding a sal.js specific (Like „sal-enabled“) class to the html or body element, like most js librarys do. The advantage would be that no “manual“/separate js work has to be done, as sal handles this by its own and there is done nothing if it couldn’t be loaded. Disadvantage is that the sal-activated class has to be included in all css selectors which makes the the css file a bit larger (not much larger than version 1 when using gzip) and as written above the class has to be included in all custom animations.
I personally prefer the second way, which I’m currently integrating in my project, as my compiled css is already has already around 15k lines of code and I’m not done yet, so i don’t mind the bit additional code I don’t have to care about adding the class on the html element.
How would you recommend changing Sal options responsively?
For example, changing the threshold for mobile VS desktop using Bootstrap grid sizes.
I would write my own screen width resize handler with debounce and passive options, but I cannot see a way in your documentation to re-create or reset Sal?
Many thanks!
Example repo, run yarn build
I get the following error when I try to build with Gatsby. I'm not initializing sal, just importing it:
WebpackError: ReferenceError: window is not defined
- sal.js:1 Object../node_modules/sal.js/dist/sal.js [as js]
node_modules/sal.js/dist/sal.js:1:187
The error points at column 187 of dist/sal.js
. This commit added one more window
at column 187.
The title says it all. There is no way to specify delay longer than one second. Maybe I am missing something obvious, but providing values like bigger than 1000 causes no delay at all.
Hi, some components are not showing up on mobile browser can I disable it like "mobile: false" in options?
Is it possible to fire many animations in the same time?
For example: fade and slide-up like in this website: https://www.runhunters.app/
Hello! Is there any way to bind certain animation to a class so every element with that class acts same when scrolled into view?
I found a bug! The bug can also be seen on the demo website: https://mciastek.github.io/sal/
Once an item reaches the top / bottom of the screen, the class ".sal-animation" is added and removed in a loop. This causes the item to fade in and out over and over again.
The bug is not always visible. Seemingly only at a certain scroll position.
No idea.
I was wondering if there's any way I can install Sal.js using a CDN instead of installing it with NPM.
Let me know! :)
Hi, I want animate large area (height), I try different pourcentage value for threshold but result are not good.
Is it possible to use a fixed value for threshold
like `threshold: '100px' or is there any others way to fix that?
Thank you, Florian.
How to create custom animations within the library, can anyone help me on this ?
I know it can sound silly, but what if we create a react
wrapper for this package?
Hi
Cool library but ie is not supported
I've seen websites use sal with custom animations (eg: something else than available from stock; fade, slide-in). How would I go about creating my own animation?
Let's say I want to create an animation called 'subtleFade'. I'd want to call it giving an element the data attribute 'data-sal-subtleFade
'.
Let me know! 🙌🏻
Suppose one wants to have different animation for when element is entering threshold and different when exiting
Is there an easy way without resorting to javascript solution ?
Is there a way to apply multiple data-sal
animations? fade slide-right
, for example.
Hi there and thx for this useful feature !
I'm using it through gatsby-plugin-scroll-reveal
Anim works well in my website home page to show (zoom-in) my first banner.
But if a go to another page and then go back to my home page using my home button, anim (zoom-in and sal:in) is not fired again.
Everything works fine if I use the browser back button to go to home page.
Here my Banner component
import React, { Component } from 'react';
import Typewriter from 'typewriter-effect';
import '../assets/sass/main.scss';
class Banner extends Component {
constructor(props) {
super(props);
this.state = { writer: null };
this.startAnim = this.startAnim.bind(this);
}
componentDidMount() {
console.log('componentDidMount');
document.addEventListener('sal:in', this.startAnim);
}
componentWillUnmount() {
console.log('componentWillUnmount');
document.removeEventListener('sal:in', this.startAnim);
}
startAnim() {
console.log('start anim');
this.state.writer.start();
}
render() {
return (
<section id="banner">
<div data-sal="zoom-in" className="content">
<Typewriter
onInit={typewriter => {
this.setState({
writer: typewriter,
});
var delay = 20;
var pause = 500;
typewriter
.changeDelay(delay)
.pauseFor(pause * 2)
.typeString('<header><h2>Bonjour et bienvenue</h2></header>');
}}
/>
</div>
</section>
);
}
}
export default Banner;
Hello, I am using sal.js and everything seems fine, but when I am trying to use Angular Universal for Server-Side Rendering, I am getting this error: "ERROR ReferenceError: window is not defined" because it is a client side package and the DOM is not supported in SSR.
@mciastek , can the package be made Universal-compatible?
First of all, thank you for great library, I really like to use it.
I believe, after macOS update (10.15.4), especially Safari update 13.1 and Chrome (80+) sal.js stopped working for SVG's paths animations.
I've simplified the problem in Codepen. Fade-in works well in Firefox, but not in current Safari or Chrome (page is blank). I believe it has something to do with CSS opacity
property and [data-sal|=fade]
selector. But I might be wrong.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.