phollyer/elm-motion/2.1.0

NOTE: the latest version is 3.0.4

Scroll.Engine.Sub

A stateful scroll engine for when you need progress, control, or scroll events.

📖 See Scroll Sub Engine Documentation and Scroll Overview for details.

Use the Builder module to configure scroll targets.

Types

type alias ScrollState =
ScrollState

Holds the scroll engine state.

Keep this in your model.

import Scroll.Engine.Sub as Sub


type alias Model =
    { scrollState : Sub.ScrollState }
type alias ScrollBuilder =
ScrollBuilder

Builder type for scroll animations.

= Document
| Container String

Identifies the scroll surface handled by the engine.

Use Document for the document body, or Container "element-id" for a specific scrollable element.

Initialize

init : ScrollState

Initialize empty scroll animation state.

import Scroll.Engine.Sub as Sub


init : Model
init =
    { scrollState = Sub.init }

Trigger

(ScrollMsg -> msg)
-> ScrollState
-> (ScrollBuilder -> ScrollBuilder)
-> ( ScrollState, Cmd msg )

Start a scroll animation and keep tracking it in state.

import Scroll.Engine.Sub as Sub


type Msg
    = ScrollMsg Sub.ScrollMsg
    | ...


let
    ( newScrollState, scrollCmd ) =
        Sub.scroll ScrollMsg model.scrollState <|
            scrollToElement "target-section"
in
( { model | scrollState = newScrollState }, scrollCmd )

Update

type alias ScrollMsg =
ScrollMsg

Message type used with update.

(ScrollMsg -> msg)
-> ScrollMsg
-> ScrollState
-> ( ScrollState, List ScrollEvent, Cmd msg )

Handle messages from this engine.

import Scroll.Engine.Sub as Sub


type Msg
    = ScrollMsg Sub.ScrollMsg
    | ...


update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
    case msg of
        ScrollMsg scrollMsg ->
            let
                ( newScrollState, events, scrollCmd ) =
                    Sub.update ScrollMsg scrollMsg model.scrollState
            in
            handleEvents events <|
                ( { model | scrollState = newScrollState }, scrollCmd )

Subscriptions

subscriptions : (ScrollMsg -> msg) -> ScrollState -> Sub msg

Subscribe to receive scroll animation updates - without this your scrolls won't run.

import Scroll.Engine.Sub as Sub


type Msg
    = ScrollMsg Sub.ScrollMsg
    | ...


subscriptions : Model -> Sub Msg
subscriptions model =
    Sub.subscriptions ScrollMsg model.scrollState

Events

= Started Container
| Ended Container
| Stopped Container
| Restarted Container
| Paused Container
| Resumed Container
| Progress
{ x : Float
, y : Float
}
Float

Scroll lifecycle events from this engine.

  • Started - A scroll animation began playing
  • Ended - A scroll animation completed naturally
  • Stopped - A scroll animation was stopped via stop
  • Restarted - A scroll animation was restarted via restart
  • Paused - A scroll animation was paused via pause
  • Resumed - A scroll animation was resumed via resume
  • Progress - A scroll animation frame with current position and progress (0.0 to 1.0)

The Container parameter identifies the scroll surface.

You receive these events from update.

Timing

delay : Int -> ScrollBuilder -> ScrollBuilder

Set the delay for all scrolls.

This will be inherited by all scrolls that don't define their own delay.

import Scroll.Builder as Scroll
import Scroll.Engine.Sub as Sub


scrollToElement : String -> ScrollBuilder -> ScrollBuilder
scrollToElement elementId =
    Sub.delay 100
        >> Scroll.forDocument
        >> Scroll.toElement elementId
        >> Scroll.speed 200
        >> Scroll.build
duration : Int -> ScrollBuilder -> ScrollBuilder

Set the duration of all scrolls.

This will be inherited by all scrolls that don't define their own duration.

import Scroll.Builder as Scroll
import Scroll.Engine.Sub as Sub


scrollToElement : String -> ScrollBuilder -> ScrollBuilder
scrollToElement elementId =
    Sub.duration 1000
        >> Scroll.forDocument
        >> Scroll.toElement elementId
        >> Scroll.build
speed : Float -> ScrollBuilder -> ScrollBuilder

Set the speed that scrolls should run at.

This will be inherited by all scrolls that don't define their own speed.

import Scroll.Builder as Scroll
import Scroll.Engine.Sub as Sub


scrollToElement : String -> ScrollBuilder -> ScrollBuilder
scrollToElement elementId =
    Sub.speed 200
        >> Scroll.forDocument
        >> Scroll.toElement elementId
        >> Scroll.build

Easing

easing : Easing -> ScrollBuilder -> ScrollBuilder

Set the easing function to be used by all scrolls.

This will be inherited by all scrolls that don't define their own easing.

import Scroll.Builder as Scroll
import Scroll.Engine.Sub as Sub


scrollToElement : String -> ScrollBuilder -> ScrollBuilder
scrollToElement elementId =
    Sub.easing BounceOut
        >> Scroll.forDocument
        >> Scroll.toElement elementId
        >> Scroll.speed 200
        >> Scroll.build

Controls

-> (ScrollMsg -> msg)
-> ScrollState
-> ( ScrollState, Cmd msg )

Stop a scroll animation by jumping to the target position.

import Scroll.Engine.Sub as Sub


let
    ( newScrollState, scrollCmd ) =
        Sub.stop Document ScrollMsg model.scrollState
in
( { model | scrollState = newScrollState }, scrollCmd )
pause : Container -> ScrollState -> ScrollState

Pause a scroll animation.

import Scroll.Engine.Sub as Sub


Sub.pause (Container "my-container") model.scrollState
resume : Container -> ScrollState -> ScrollState

Resume a scroll animation.

import Scroll.Engine.Sub as Sub


Sub.resume Document model.scrollState
-> (ScrollMsg -> msg)
-> ScrollState
-> ( ScrollState, Cmd msg )

Reset a scroll animation to its starting position.

import Scroll.Engine.Sub as Sub


let
    ( newScrollState, scrollCmd ) =
        Sub.reset (Container "my-container") ScrollMsg model.scrollState
in
( { model | scrollState = newScrollState }, scrollCmd )
-> (ScrollMsg -> msg)
-> ScrollState
-> ( ScrollState, Cmd msg )

Restart a scroll animation from its starting position.

import Scroll.Engine.Sub as Sub


let
    ( newScrollState, scrollCmd ) =
        Sub.restart Document ScrollMsg model.scrollState
in
( { model | scrollState = newScrollState }, scrollCmd )

State Queries

anyRunning : ScrollState -> Maybe Bool

Check if any scroll animations are currently running.

Returns Nothing if there are no animations.

isRunning : Container -> ScrollState -> Maybe Bool

Check if a scroll animation for a specific container is currently running.

Returns Nothing if there are no animations for the container.

Querying Scroll Position

-> ScrollState
-> Maybe
{ x : Float
, y : Float
}

Get the current scroll position for a specific container.

Returns X and Y coordinates as a record.

Returns Nothing if the container is not found or scroll position is unavailable.

getPositionX : Container -> ScrollState -> Maybe Float

Get current horizontal scroll position for a specific container.

getPositionY : Container -> ScrollState -> Maybe Float

Get current vertical scroll position for a specific container.