@nam-hai/water-flow

0.1.0 • Public • Published

Waterflow

npm version

Introduction

Waterflow is a Nuxt3 library that enables flawless page transitions (Vue3's router too).

QUICK START

$ npm i @nam-hai/water-flow

Setup

Waterflow and its <BufferPage /> hijack <router-view> and can be placed as a replacement (<slot /> in layout.vue for Nuxt3)

<template>
  <BufferPage />
</template>

<script lang='ts'>
import { BufferPage } from '@nam-hai/water-flow';
</script>

App.vue

import index from '@/pages/index.vue';
import about from '@/pages/about.vue';
import home from '@/pages/home.vue';
import { FlowProvider, provideFlowProvider } from '@nam-hai/waterflow'

// provide useFlowProvider through out your whole project
const flowProvider = new FlowProvider()
provideFlowProvider(flowProvider)

// register each page where you will use 
flowProvider.registerPage('index', index)
flowProvider.registerPage('home', home)
flowProvider.registerPage('about', about)

Example

Now use usePageFlow for the page transitions :

usePageFlow({
  props: {
    buttonRef,
    wrapperRef
  },
  // enable crossfade animations and set if the BufferPage is on top or under the current page
  enableCrossfade: 'TOP',
  flowOut: ({ }, resolve) => {
    // insert animation out for the current page
  },
  flowInCrossfade: ({ buttonRef }, resolve) => {
    // insert animation of the next page

    // use the animation engine you like
    const tl = anime.timeline({
        easing: 'easeOutExpo',
        duration: 750
    });

    tl
    .add({
        targets: wrapperRef.value,
        translateX: 250,
    })
    .add({
        targets: buttonRef.value,
        translateX: 250,
        complete: function(anim) {

            // make sure to call the resolve callback to trigger the route change once the animation is over
            resolve()
        }
    }, '+=600') 
  },
})

usePageFlow props

Name Type Default Description
props T Pass props (Vue Refs) the way you want
enableCrossfade boolean or 'TOP' or 'BOTTOM' false Enable crossfade animations and set if the BufferPage is on top or under the current page. True and 'BOTTOM' are the same
flowOutMap Map<string, FlowFunction<T>> undefined Specify a Map of animations for the current page (see more)
flowOut FlowFunction<T> undefined Specify a default animation for the current page
flowInCrossfadeMap Map<string, FlowFunction<T>> undefined Specify a Map of animations for the next page (see more)
flowOut FlowFunction<T> undefined Specify a default animation for the next page
disablePointerEvent boolean true Disable pointer events for the duration of the animation. Still experimental, clicking on a link during the animation can break app

Type FlowFunction

type FlowFunction<T> = (props: T, resolve: () => void, flowProps?: FlowProps) => void

Function of type FlowFunction have the responsibility to trigger the resolve callback and can be used to animate your pages. Those functions are called in usePageFlow when the route change, ie: onBeforeRouteLeave(to, from, next) and resolve leads to trigger the next callback. props are the Refs you want the access during the animations. They are the ones passed to usePageFlow.

flowProps are props not tied to one specific page. Can be useful for animations on layout elements or canvas. type FlowProps = Record<string, any>

You can add flowProps anywhere in the app :

const webglScene = new WebGLScene()
const flowProvider = useFlowProvider()
flowProvider.addProps('canvas', webglScene)

flowOutMap and flowInCrossfadeMap

You can setup multiple animations to leave one page to another. To do so, you need to pass "FlowMaps". They map from a key to a FlowFunction with the key following the naming convention : routeNameFrom => routeNameTo

index.flow.ts

const transitionIndexOutAbout = ({wrapperRef, buttonRef}, resolve, {canvas}) => {
  // insert your animations
}
const transitionIndexOutHome = ({wrapperRef, buttonRef}, resolve, {canvas}) => {
  // insert your animations
}
const transitionIndexOutDefault = ({wrapperRef, buttonRef}, resolve, {canvas}) => {
  // insert your animations
}

const IndexFlowOutMap = new Map([
  ['index => about', transitionIndexOutAbout],
  ['index => home', transitionIndexOutHome]
  ['default', transitionIndexOutDefault]
])

onFlow

You might want to init things or start some animation after crossfade animations have ended. onMounted will trigger when the crossfade animation start. Use onFlow the same way you'd use onMounted to trigger callback when the page is officially changed and crossfade animations have ended.

Connect your smooth scroll

Waterflow reset the scroll after each page transitions. But if you use a smooth scroll, like Lenis or Locomotive Scroll, this might create conflict. To prevent this, you can connect your smooth scroll to FlowProvider.

Example for Lenis

const flowProvider = useFlowProvider()

useRaf((e) => {
  !flowProvider.flowIsHijacked.value && lenis.raf(e.elapsed)
})

flowProvider.registerScrollInterface({
  resume: () => { lenis.start() },
  stop: () => { lenis.stop() },
  scrollToTop: () => { lenis.scrollTo('top', { immediate: true }) }
})

flowIsHijacked.value is true while the crossfade animations.

Versions

Current Tags

VersionDownloads (Last 7 Days)Tag
0.1.00latest
0.0.9-10next

Version History

VersionDownloads (Last 7 Days)Published
0.1.00
0.0.230
0.0.220
0.0.210
0.0.200
0.0.190
0.0.180
0.0.170
0.0.160
0.0.150
0.0.140
0.0.130
0.0.120
0.0.110
0.0.100
0.0.90
0.0.9-10
0.0.9-00
0.0.80
0.0.70
0.0.60
0.0.50
0.0.40
0.0.30
0.0.20
0.0.10

Package Sidebar

Install

npm i @nam-hai/water-flow

Weekly Downloads

0

Version

0.1.0

License

ISC

Unpacked Size

18.1 kB

Total Files

9

Last publish

Collaborators

  • nam-hai