rytm-webflow
v2.2.3
Published
rytm webflow pack - ASwap, ShowUp
Downloads
219
Readme
rytm-webflow
Rytm webflow pack is used to make websites rendered on the server (using a PHP or other back-end) more dynamic.
A static website can be transformed into something we call a pseudo single page application (SPA). The pack includes ASwap - a framework under developement by Rytm.Digital since 2016 which uses AJAX / fetch to first load and then swap the page's content in user's browser.
This package comes with a handy WebflowView and WebflowListView.
Another future rytm-webflow includes is ShowUp - a ScrollMagic.js wrapper which can be integrated with ASwap.
Install using NPM:
$ npm install rytm-webflow --save
Dependencies
- gsap
- imagesloaded
- scrollmagic
- scrollmagic-plugin-gsap
ASwap
Basic usage example
In your HTML for each request you neeed a wrapper (default wrapper selector: #stage
)
Inside a wrapper you can have multiple view instances. Each view uses a name defined in data-as-view
and an unique id defined in data-as-id
<div id="stage">
<div data-as-view="item" data-as-id="uid">
...
</div>
</div>
Init ASwap in your JS
import RytmWebflow from 'rytm-webflow'
RytmWebflow.aswap.init()
More examples
Controllers
To programm some interaction within your ASwap views create a controller
import RytmWebflow from 'rytm-webflow'
class ItemController extends RytmWebflow.Controller {
addEventListeners() {
// ...do your stuff
}
removeEventListeners() {
// ...undo your stuff
}
}
And pass the controller class to the routes
parameter
import RytmWebflow from 'rytm-webflow'
import ItemController from './ItemController'
RytmWebflow.aswap.init({
routes: {
"item" : {
controller: ItemController
}
}
})
Read more about it -> Controller class
If you need your controller to wait until all view's images are loaded you can use the ControllerImgLoad
class instance. This will trigger view.show()
not before images are loaded. While images are being loaded an as-images-loading
class name will be added to the view's container.
Usage example:
import RytmWebflow from 'rytm-webflow'
class MyController extends RytmWebflow.ControllerImgLoad {
loadImagesComplete() {
super.loadImagesComplete();
// ...do your stuff...
}
}
If you are using the ControllerImgLoad
- to hide the view before the show animation is triggered you can add some CSS, eg:
.as-images-loading {
display: none;
}
Views
If you need some fancy animations to show / hide your views you can create view instances.
import RytmWebflow from 'rytm-webflow'
class ItemView extends RytmWebflow.View {
show(container) {
// ...do your GreenSock stuff
}
hide(container) {
// ...do your GreenSock stuff
}
}
Then include the ItemView
class in the routes
parameter
import RytmWebflow from 'rytm-webflow'
import ItemController from './ItemController'
import ItemView from './ItemView'
RytmWebflow.aswap.init({
routes: {
"item" : {
controller: ItemController,
view: ItemView
}
}
})
Read more about it -> View class
Sample params
import RytmWebflow from 'rytm-webflow'
import { trace } from 'rytm-helpers'
import routes from './routes'
RytmWebflow.aswap.init({
animationTimeHide: 900,
animationTimeShow: 1200,
preloadOnHover: true,
routes,
trace,
})
Params
| param | default | info |
|---|---|---|
| animationTimeHide
| 800
| Time (ms) for view's hide transition|
| animationTimeShow
| 800
| Time (ms) for view's show transition|
| formsEnabled
| true
| Use ASwap on forms|
| formsSelector
| 'form'
| ASwap forms selector|
| swipeEnabled
| true
| Use ASwap swipe|
| swipeMinDistance
| 5
| Minimum swipe move distance (px) for swipe to fire|
| historyEnabled
| true
| Use history push state |
| historyFallback
| true
| Fallback if browser dosn't support history push state |
| cacheOn
| true
| By default all requests are being cached. Set to false
to turn cache off |
| noCacheClassName
| 'no-as-cache'
| By default all requests are being cached. Links with this class name don't use ajax cache |
| resetScrollOn
| true
| By default on each view swap the window is scrolled back up. This should be disabled if using lenis
|
| noScrollClassName
| 'no-as-scroll'
| By default each page transformation is reseting the window scroll. Links with this class don't scroll window back up |
| noSwapClassName
| 'no-as'
| Links with this class or target=_blank
don't load using ASwap |
| oldschoolBrowserFallback
| true
| If set to true
IE 11 or lower is not supported |
| preloadOnHover
| false
| If true
each hover will run request - to make page work faster |
| refreshOnSameUrl
| true
| When true
each request on same URL will refresh browser's window |
| routes
| {}
| The routes object where you can define controllers and views |
| swapSelector
| '#stage'
| ASwap wrapper selector |
| defaultDocumentScrollBehavior
| 'smooth'
| Default document scroll behaviour |
| trace
| (message) => {}
| A function to log stuff, eg in console |
Controller class
| method | info |
|---|---|
| addEventListeners()
| this method is called after a view is shown on stage |
| removeEventListeners()
| this method is called just before the view is being hidden |
| onRequestUrl()
| read more -> global events |
| onRequestLoad()
| read more -> global events |
| onRequestLoaded()
| read more -> global events |
| onViewHide()
| read more -> global events |
| onViewHidden()
| read more -> global events |
| onViewSwapStart()
| read more -> global events |
| onViewSwapComplete()
| read more -> global events |
| onViewShow()
| read more -> global events |
| onViewShown()
| read more -> global events |
View class
| method | parameters | info |
|---|---|---|
| hide()
| container
| this method is called by the Controller
instance in the onViewShow()
method |
| prepare()
| container
| this method is called by the Controller
instance in the onViewSwapComplete()
method |
| show()
| container
| this method is called by the Controller
instance in the onViewShow()
method |
| loadImagesStart()
| container
| this method is called by the ControllerImgLoad
instance on image load start |
| loadImagesComplete()
| container
| this method is called by the ControllerImgLoad
instance on image load complete |
Global events
You also can pass custom methods to the global ASwap instance events, eg:
import RytmWebflow from 'rytm-webflow'
RytmWebflow.aswap.init(params, {
onRequestLoad: () => { },
onViewHidden: () => { }
})
| method | info |
|---|---|
| onInited()
| fired when ASwap is inited |
| onRequestUrl()
| fired when a new url is requested |
| onRequestLoad()
| fired when a new url is loaded (not whired when url is already saved in cache) |
| onRequestLoaded()
| fired when a url load has completed |
| onViewHide()
| fired when a ASwap is starting it's hide transition. Hide is fired for all views which are available on current stage and are not available on new / loaded stage |
| onViewHidden()
| fired within animationTimeHide
ms from hide transition start |
| onViewSwapStart()
| fired just before the scene's content is replaced |
| onViewSwapComplete()
| fired just after the scene's content is being replaced |
| onViewShow()
| fired when the new scene is loaded and the show transition is being started |
| onViewShown()
| fired within animationTimeShow
ms from show transition start |
Bootstrap integration
Bootstrap v5
A common situation is to hide all Bootstrap offcanvases or modals when an ASwap page transition is in made. To do so just call the RytmWebflow.bootsrap5.hideFlyovers()
method. You can also hide offcanvases or modals separatly by calling the RytmWebflow.bootsrap5.hideOffcanvases()
or RytmWebflow.bootsrap5.hideModals()
methods.
A basic usage example:
import RytmWebflow from 'rytm-webflow'
RytmWebflow.aswap.init(params, {
onViewHide: () => {
RytmWebflow.bootsrap5.hideFlyovers()
},
})
Swipe
Add urls to as-swipe-{direction}
data attributes, eg:
<div
data-as-swipe-left="/path/to-next"
data-as-swipe-right="/path/to-prev"
data-as-swipe-up="/path/to-back">
...
</div>
WebflowView
WebflowView is an universal ASwap View which can be used with the Webflow syntax - a minified way to describe an animation, it's duration (time), easing, delay or the trigger. Eg. y:100,o:0
will animate an element from: y:100px
and opacity: 0
to it's current state. Go to Webflow syntax for more.
Basic usage example
Define the route:
import RytmWebflow from 'rytm-webflow'
RytmWebflow.aswap.init({
routes: {
"webflow" : {
controller: RytmWebflow.Controller,
view: RytmWebflow.WebflowView
}
}
})
Add data attributes to the cointainer element:
<div id="stage">
<div data-as-view="webflow" data-as-id="uid">
...
</div>
</div>
Animate any element within the WebflowView container using the Webflow syntax inside the webview
attributes (initial, show, hide):
<div data-webview-initial="o:0" data-webview-show="o:1,t:.5" data-webview-hide="o:0,t:.4">
...
</div>
or (more complex example):
<div data-webview-initial="x:-10,y:50" data-webview-show="x:0,y:0,t:.5,d:.15,e:power3.out" data-webview-hide="x:10,y:-25,t:.4,d:.2,e:power2.in">
...
</div>
Stagger - animate any list of items
Animate elements nested under the WebflowView container when scrolled into viewport by using stagger
data attributes (initial, show, hide) and the data-webset
attribute:
<ul data-stagger-initial="o:0" data-stagger-show="o:1,t:.5,stagger:.1" data-stagger-hide="o:0,t:.4,stagger:.1" data-webset="selector:li">
<li>...</li>
<li>...</li>
</ul>
Scrollmagic - animate elements when scrolled into viewport
Scroll-triggered-animations of any element inside the WebflowView container. Use the webscroll
data attributes (initial, show, hide):
<div data-webscroll-initial="o:0" data-webscroll-show="o:1,t:.5" data-webscroll-hide="o:0,t:.3">
...
</div>
Use the webset
data attribute to pass some additional parameters, eg. the trigger element. This can be helpful when animating any element in the Y axis, eg:
<div data-webset="trigger:parent" data-webscroll-initial="y:100" data-webscroll-show="y:0,t:.5,e:power3.out" data-webscroll-hide="o:0,t:.4">
...
</div>
By default scroll-troggered animations are only fired once. You can change this by setting the fireOnce
parameter to false
, example:
<div data-webset="fireOnce:false" data-webscroll-initial="o:0" data-webscroll-show="o:1,t:.5">
...
</div>
WebflowListView
The WebflowListView enables staggered show animation for elements which implement the WebflowView Scrollmagic animations.
Basic usage example
Define the route:
import RytmWebflow from 'rytm-webflow'
RytmWebflow.aswap.init({
routes: {
"list" : {
controller: RytmWebflow.Controller,
view: RytmWebflow.WebflowListView
}
}
})
Add data attributes to the cointainer element. Inside the element grabbed by the selector place elements that include the webscroll
data attributes (initial, show, hide):
<div id="stage">
<ul data-as-view="list" data-as-id="uid" data-webset="selector:li,stagger:.1">
<li>
<div data-webscroll-initial="o:0" data-webscroll-show="o:1,t:.5" data-webscroll-hide="o:0,t.4">
...
</div>
</li>
</ul>
</div>
ShowUp
ShowUp makes creating gsap scroll-triggered-animations much faster. It can be used to show content while user scrolls down the page. It can also be used for parallax like animations. ShowUp comes with the Webflow syntax. Go to Webflow syntax for more.
Webflow usage example
To enable ShowUp call the init method in your JS:
import RytmWebflow from 'rytm-webflow'
RytmWebflow.showUp.init()
If you are working on a SPA or using ASwap the only thing you need to do is call the rebuild method on each view load. Check out the ASwap example:
import RytmWebflow from 'rytm-webflow'
const events = {
onViewSwapComplete: () => {
RytmWebflow.showUp.rebuild()
}
}
RytmWebflow.aswap.init({}, events)
To implement ShowUp on your HTML add a data-webflow
or data-webpara
attribute to DOM elements which will describe the animation
<!-- From opacity: 0 in .4s -->
<div data-webflow="o:0,t:.4">...</div>
Add easing for your animations
<!-- gsap easing -->
<div data-webflow="x:-10vw,t:.5,e:expo.out">...</div>
Delay animations
<!-- delay by .3s -->
<div data-webflow="x:-20,t:.5,d:.3">...</div>
Trigger element
By default the ScrollMagic.Scene is triggered by the element itself. Also it is triggered once the element becomes visible (at the window bottom).
You can override these defaults using the data-webset
attribute.
To specyfy an offset:
<!-- offset: 100px from bottom up -->
<div data-webflow="o:0" data-webset="offset:100">...</div>
<!-- offset: window center -->
<div data-webflow="o:0" data-webset="offset:center">...</div>
<!-- offset: window top -->
<div data-webflow="o:0" data-webset="offset:top">...</div>
To specyfy a trigger element:
<!-- target -->
<div data-webflow="o:0" data-webset="trigger:#myTarget">...</div>
Hide animation
You can specify a hide transition (eg. for ASwap View to hide elements)
Separate show and hide animation using ;
<!-- show, hide -->
<div data-webflow="x:-30,t:.5;x:15,t:.3">...</div>
To start the hide animation on each dom element call the hide()
method
RytmWebflow.showUp.hide()
An ASwap example implementing ShowUp along with the hide animation:
import RytmWebflow from 'rytm-webflow'
const events = {
onViewSwapComplete: () => {
RytmWebflow.showUp.rebuild()
},
onViewHide: () => {
RytmWebflow.showUp.hide()
}
}
RytmWebflow.aswap.init({}, events)
Parallax usage example
Parallax like animation:
<!-- parallax duration 100% - by container height -->
<div data-webpara="x:100" data-webset="duration:100%">...</div>
Duration can be relative to viewport:
<!-- parallax duration 30vh - by viewport height -->
<div data-webpara="s:1.2" data-webset="duration:30vh">...</div>
When moving elements in the Y axis you can use the parent
trigger hook:
<!-- parallax triggered by parent Node -->
<div>
<div data-webpara="y:-100" data-webset="duration:100%,trigger:parent"></div>
</div>
Webflow syntax
| short code | prameter | example |
|---|---|---|
| d
| delay | "d:.4"
|
| e
| ease | "e:Bounce.easeOut"
|
| h
| height | "h:10"
|
| o
| opacity | "o:0"
|
| r
| rotation | "r:180"
|
| s
| scale | "s:.1"
|
| t
| time | "t:.35"
|
| w
| width | "w:1200"
| |
More examples
Examples:
<h1>Webflow show up</h1>
<div data-webflow="t:.4,o:0,y:10;t:.4,o:0,y:-30">Webflow Simple ALPHA no delay</div>
<div data-webflow="t:.4,o:0,s:.4;t:.4,o:0,s:1.5">Webflow Scale</div>
<div data-webflow="t:1.4,x:-300,e:expo.out;t:.4,d:0,x:-100,e:expo.in" data-webset="offset:100">Webflow Offset: 100, Ease EXPO</div>
<div data-webflow="t:1.4,x:-100vw;t:.4,d:0,x:-250" data-webset="offset:center">Webflow Offset: center</div>
<div data-webflow="t:1.4,x:-250;t:.4,d:0,x:-250" data-webset="offset:top">Webflow offset: TOP</div>
<div data-webflow="t:1.4,x:-250,w:10;t:.4,d:0,x:-250" data-webset="trigger:#boom">Webflow Triggered by next BLOCK</div>
<div id="boom" >Trigger</div>
<!-- ### Webflow Parallax ### -->
<h1>Webflow parallax</h1>
<div data-webpara="x:400" data-webset="duration:100%">Parallax duration 100%</div>
<div data-webpara="x:400,e:back.out" data-webset="duration:40vh">Parallax duration 40vh, ease: Back</div>
<div >parent TRIGGER
<div data-webpara="y:-500,r:180" data-webset="duration:100%,trigger:parent">Parallax Y</div>
</div>
You can use the parser functions to implement your own view related methods using the Webflow syntax:
| function | descr |
|---|---|
| RytmWebflow.getWebflowProps(str)
| converts a webflow syntax string into an webflow parameters object: {show: {tween: {}, time: X}, hide: {tween: {}, time: X}
|
| RytmWebflow.getParallaxProps(str)
| converts a webflow syntax string into an webflow parameters object: {parallax: {tween: {}}}
|