1.1.0 ā€¢ Published 30 days ago

svelte-reveal v1.1.0

Weekly downloads
-
License
MIT
Repository
github
Last release
30 days ago

npm.io

Svelte Reveal

npm npm GitHub

Svelte Reveal is a library created with the purpose of helping Svelte users add reveal on scroll animations to their web applications in the easiest way possible. This library leverages the Intersection Observer API in order to know when to trigger the animations.

Features

  • āš”ļø Near zero config
  • šŸ‘€ Intersection Observer
  • šŸ§© Customizable transitions
  • šŸ”Œ Extensive API
  • šŸ“š Exhaustive documentation
  • šŸ”„ 100% TypeScript

Table of Contents

  1. Demo
  2. Usage
  3. Why Svelte Reveal
  4. SvelteKit
  5. Options
  6. Global config
  7. API
  8. Suggestions
  9. Troubleshooting
  10. Funding
  11. Versioning
  12. Changelog
  13. License

Demo

You can see Svelte Reveal in action in this StackBlitz project.

Usage

  1. Install the library:

    # npm
    npm install -D svelte-reveal
    
    # yarn
    yarn add -D svelte-reveal
    
    # pnpm
    pnpm add -D svelte-reveal
    
    # bun
    bun add -D svelte-reveal
  2. Import the library in your Svelte component:

    <script>
      import { reveal } from 'svelte-reveal';
    </script>
  3. Add the imported reveal action to the DOM element you want to transition:

    <h1 use:reveal>Hello world</h1>
    <p use:reveal={{ transition: "slide" }}>A paragraph</p>

    If you want to use the action on a Svelte component, you need to pass the reveal options via props:

    // App.svelte
    
    <script>
      import Heading from './Heading.svelte';
    </script>
    
    <Heading useReveal={{ transition: "slide" }}>Hello world</Heading>
    // Heading.svelte
    
    <script lang="ts">
      import { reveal, type RevealOptions } from 'svelte-reveal';
      export let useReveal: RevealOptions;
    </script>
    
    <h1 use:reveal={ useReveal }>
      <slot />
    </h1>

    Using SvelteKit? Please refer to the "SvelteKit" section.

Why Svelte Reveal

If you happened to scout the internet for other similar libraries, you might have noticed that other authors have decided to create their own library using Svelte slots (similar to React children). There is nothing wrong with that approach, but in my opinion it goes a bit against one of Svelte's core purpose: writing more concise code. Having to wrap every to-be-transitioned component adds at least 2 extra lines of code each time, making your files unnecessarily bloated for such a simple add-on.

You might have also noticed people adding event listeners to the window object in order to transition elements, but in terms of performance it doesn't scale very well.

Instead, I decided to use Svelte actions, which are functions you can attach to a DOM element and that allow you to get access to that particular element and hook into its lifecycle. They take up considerably fewer lines of code, and so far I haven't encountered any big obstacle or performance drawback. Morever, this library is backed by the Intersection Observer API, which is great for performance.

SvelteKit

āš ļø This is an active area of research. Please submit a bug report in case of issues.

šŸ“… Last update: April 2024

Since Svelte actions were conceived to operate in a client-side environment, they don't always work 100% in SvelteKit and SSR (server-side rendering) out of the box. Svelte Reveal is no exception, as it needs DOM access, and in order not to incur in weird animation behaviors some small setup is required by the end-users. Out of the following two methods, pick the one that most suit your project requirements.

Without SSR

If your page doesn't need to be server-side rendered then the fix is very trivial. Turn off ssr in your +page.ts file as follows.

// +page.ts
export const ssr = false;

With SSR

If your page does need to leverage server-side rendering, the setup remains easy but it requires a few more steps.

  1. Import the bundled stylesheet in your page or layout

    // +layout.svelte
    
    <script lang="ts">
      import "svelte-reveal/styles.css";
      ...
    </script>
    
    ...
  2. Add the sr__hide css class to every element targeted by Svelte Reveal with use:reveal. This will prevent the elements to flicker as soon as the page is hydrated and the DOM is accessible to the library.

    // +page.svelte
    
    <script lang="ts">
      import { reveal } from 'svelte-reveal';
    </script>
    
    <h1 use:reveal class="sr__hide">Hello world</h1>

Options

Depending on the use case, you can either use this library as-is (which applies some default options), or customize it to your liking. If you choose to do so, you can pass an object to this action containing your own options to be applied.

Keep in mind that these options are applied to the single DOM element you add Svelte Reveal to. For global and more in-depth settings, refer to the API section.

NameTypeDefaultDescription
disablebooleanfalseWhen set to false, the transition is disabled for the target element.
rootElement \| Document \| nullnullThe root element used by the Intersection Observer.
rootMarginstring"0px 0px 0px 0px"The root margin property of the Intersection Observer.
thresholdnumber0.6The threshold (in percentage from 0.0 to 1.0) property used by the Intersection Observer to know when its target element is considered visible.
preset"fade" \| "slide" \| "fly" \| "spin" \| "blur" \| "scale""fade"The transition preset that should be applied. Check out the "presets" subsection for more info.
resetbooleanfalseWhen set to true, the node transitions out when out of view, and is revealed again when back in view.āš ļø Be careful not to overuse this option, as it prevents the Intersection Observer to stop observing the target node. Performance is therefore not guaranteed when many elements have reset set to true.
durationnumber800How long the transition lasts (in ms).
delaynumber0How long the transition is delayed (in ms) before being triggered.
easingEasing"easeInOutCubic"The easing function to use. Check out the full list of available easing functions and this other website to preview timing functions.
xnumber0The starting offset position in pixels on the x-axis.
ynumber0The starting offset position in pixels on the y-axis.
rotatenumber0The starting rotation offset in degrees.
opacitynumber0The starting opacity value.
blurnumber0The starting blur value in pixels.
scalenumber1The starting scale value in percentage. 1 corresponds to 100%.

Presets

āš ļø All presets have the "fade" preset backed in

Presets are sets of options with predefined values, packaged under a name to achieve a certain transition effect. The following table shows the presets that come bundled with Svelte Reveal and which options they map to.

NameOptionsDescription
"fade"{ opacity: 0 }The element fades in gracefully.In practice: opacity: 0 -> 1
"fly"{ opacity: 0, y: -20 }The element fades in and moves along a translation on the y-axis.In practice: opacity: 0 -> 1 + transform: translateY(-20px -> 0px)
"slide"{ opacity: 0, x: -20 }The element fades in and performs a translation on the x-axis.In practice: opacity: 0 -> 1 + transform: translateX(-20px -> 0px)
"blur"{ opacity: 0, blur: 2 }The element fades in and becomes unblurred.In practice: opacity: 0 -> 1 + filter: blur(2px -> 0px)
"scale"{ opacity: 0, scale: 0.8 }The element fades in and gets to the original size.In practice: opacity: 0 -> 1 + transform: scale(0.8 -> 1)āš ļø In order to use this transition it is required to use the width CSS property on the element to reveal. If you are not already using this property for other things, you can set it to width: fit-content .
"spin"{ opacity: 0, rotate: -10 }The element fades in and gets to the original rotation degree.In practice: opacity: 0 -> 1 + transform: rotate(-10 -> 0)āš ļø In order to use this transition it is required to use the width CSS property on the element to reveal. If you are not already using this property for other things, you can use set it to width: fit-content .

Callbacks

The following table shows all the callback functions we provide to you.

NameArgsReturnDescription
onRevealStart(node: HTMLElement)voidFunction that gets fired when the node starts being revealed.
onRevealEnd(node: HTMLElement)voidFunction that gets fired when the node is fully revealed.
onResetStart(node: HTMLElement)voidFunction that gets fired when thereset option is set to true and the node starts transitioning out.
onResetEnd(node: HTMLElement)voidFunction that gets fired when the reset option is set to true and the node has fully transitioned out.
onMount(node: HTMLElement)voidFunction that gets fired when the node is mounted on the DOM.
onUpdate(node: HTMLElement)voidFunction that gets fired when the action options are updated.
onDestroy(node: HTMLElement)voidFunction that gets fired when the node is unmounted from the DOM.

Global config

The following table shows how this library is globally configured right of out the box.

Parameter(children)(children)TypeDefaultDescription
oncebooleanfalseWhether the reveal effect runs only once (i.e. it doesn't re-run on page reload).
responsiveResponsiveSpecifies how the library handles responsiveness. It can be used to enable/disable the reveal effect on some devices.
mobileDeviceConfigConfiguration of mobile devices.
enabledbooleantrueWhether the reveal effect is performed on mobile devices.
breakpointnumber425The max viewport width of mobile devices.
tabletDeviceConfigConfiguration of tablet devices.
enabledbooleantrueWhether the reveal effect is performed on tablet devices.
breakpointnumber768The max viewport width of tablet devices.
laptopDeviceConfigConfiguration of laptop devices.
enabledbooleantrueWhether the reveal effect is performed on laptop devices.
breakpointnumber1440The max viewport width of laptop devices.
desktopDeviceConfigConfiguration of desktop devices.
enabledbooleantrueWhether the reveal effect is performed on desktop devices.
breakpointnumber2560The max viewport width of desktop devices.

API

āš ļø If you want to customise the behavior of a single DOM node, you are supposed to use options.

Svelte Reveal also exposes several functions you can call to change the default options and global configuration of this library. Since these functions operate on a global level across all components using Svelte Reveal, you are supposed to only call them from a single file, otherwise you'll keep overriding the default options and global config from multiple points.

NameArgsReturnDescription
setOnce(once: boolean)RevealConfigSets the reveal animations activation status on page reload.
setDeviceStatus(device: Device, status: boolean)RevealConfigSets the status of a device.
setDevicesStatus(devices: Device[], status: boolean)RevealConfigSets the status of multiple devices.
setDeviceBreakpoint(device: Device, breakpoint: number)RevealConfigSets the breakpoint of a device.
setDevice(device: Device, settings: IDevice)RevealConfigSets the settings of a device.
setResponsive(responsive: Responsive)RevealConfigUpdates how responsiveness is handled by the library.
setObserverRoot(root: Element \| Document \| null)IntersectionObserverConfigSets the Intersection Observer root element.
setObserverRootMargin(rootMargin: string)IntersectionObserverConfigSets the Intersection Observer rootMargin property.
setObserverThreshold(threshold: number)IntersectionObserverConfigSets the Intersection Observer threshold property.
setObserverConfig(observerConfig: IntersectionObserverConfig)IntersectionObserverConfigSets the Intersection Observer configuration.
setConfig(userConfig: RevealConfig)RevealConfigUpdates the library global configuration.
setDefaultOptions(options: RevealOptions)RevealOptionsUpdates the default options to be used for the reveal effect.

Suggestions

If you need to considerably customize the behavior of this library, I suggest creating a dedicated file and to import it from the top-most component in the components tree of your project. Within that file you can then call the API functions to set global settings or shared transition properties.

// reveal.config.ts

import { setDefaultOptions } from 'svelte-reveal';

setDefaultOptions({
  blur: 20,
  x: -50,
  duration: 3000
});
// App.svelte

<script>
  import 'reveal.config';
</script>

<div>{ your markup goes here }</div>

Troubleshooting

Feel free to open a new issue in case of any problems.

Funding

Want to buy me a coffee?

Versioning

This project uses Semantic Versioning to keep track of its version number.

Changelog

CHANGELOG

License

MIT

1.1.0

30 days ago

1.0.4

1 month ago

1.0.2

1 month ago

1.0.1

1 month ago

1.0.0

1 month ago

1.0.3

1 month ago

0.7.0

2 years ago

0.5.0

2 years ago

0.6.0

2 years ago

0.4.0

2 years ago

0.3.3

2 years ago

0.3.2

2 years ago

0.3.1

2 years ago

0.3.0

2 years ago

0.2.0

2 years ago

0.1.0

2 years ago