Last active
October 17, 2019 21:48
-
-
Save jeovazero/40d8c15bff70357729ce9444734bf7f4 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/elm.json b/elm.json | |
index 10e470f..6f7d607 100644 | |
--- a/elm.json | |
+++ b/elm.json | |
@@ -9,12 +9,12 @@ | |
"elm/browser": "1.0.1", | |
"elm/core": "1.0.2", | |
"elm/html": "1.0.0", | |
+ "elm/time": "1.0.0", | |
"rtfeldman/elm-css": "16.0.1" | |
}, | |
"indirect": { | |
"Skinney/murmur3": "2.0.8", | |
"elm/json": "1.1.3", | |
- "elm/time": "1.0.0", | |
"elm/url": "1.0.0", | |
"elm/virtual-dom": "1.0.2", | |
"rtfeldman/elm-hex": "1.0.0" | |
diff --git a/src/CombinatorsAnimated.elm b/src/CombinatorsAnimated.elm | |
index 2f2db78..bb00a0d 100644 | |
--- a/src/CombinatorsAnimated.elm | |
+++ b/src/CombinatorsAnimated.elm | |
@@ -1,5 +1,15 @@ | |
-module CombinatorsAnimated exposing (Model, combinatorsBackground, initModel) | |
- | |
+module CombinatorsAnimated exposing | |
+ ( Model | |
+ , Msg(..) | |
+ , combinatorsBackground | |
+ , initAnimation | |
+ , initModel | |
+ , subscriptions | |
+ , update | |
+ ) | |
+ | |
+import Browser.Dom exposing (getElement) | |
+import Browser.Events exposing (onAnimationFrame) | |
import Css exposing (..) | |
import Html.Styled exposing (..) | |
import Html.Styled.Attributes as Attrs exposing (..) | |
@@ -16,37 +26,148 @@ import Styles | |
, textMedium | |
, textXLarge | |
) | |
+import Task | |
+import Time | |
type alias Combinator = | |
{ letter : String | |
- , delay : Float | |
+ , delay : Int | |
+ , initialTime : Int | |
, translate : ( Float, Float ) | |
, shiftX : Float | |
} | |
type alias Model = | |
- List Combinator | |
+ { totalHeight : Float | |
+ , combinators : List Combinator | |
+ } | |
+ | |
+ | |
+type Msg | |
+ = Init (Result Browser.Dom.Error ( Time.Posix, Browser.Dom.Element )) | |
+ | Tick Time.Posix | |
+ | |
+ | |
+duration = | |
+ 3000 | |
+ | |
+ | |
+setInitialTime currentTime combinator = | |
+ { combinator | |
+ | initialTime = currentTime | |
+ } | |
+ | |
+ | |
+updateCombinators : Int -> Float -> Combinator -> Combinator | |
+updateCombinators currentTime totalHeight ({ initialTime, delay, translate } as combinator) = | |
+ let | |
+ elapsed = | |
+ currentTime - initialTime - delay | |
+ | |
+ progress = | |
+ if elapsed < 0 then | |
+ 0 | |
+ | |
+ else | |
+ Basics.min ((elapsed |> toFloat) / duration) 1.0 | |
+ | |
+ ty = | |
+ totalHeight * progress | |
+ | |
+ initialTimeNext = | |
+ if progress == 1.0 then | |
+ currentTime | |
+ | |
+ else | |
+ initialTime | |
+ in | |
+ { combinator | |
+ | initialTime = initialTimeNext | |
+ , translate = Tuple.mapSecond (always ty) translate | |
+ } | |
+ | |
+ | |
+update : Msg -> Model -> ( Model, Cmd Msg ) | |
+update msg model = | |
+ case msg of | |
+ Init result -> | |
+ case result of | |
+ Result.Ok ( timePosix, { element } ) -> | |
+ let | |
+ currentTime = | |
+ Time.posixToMillis timePosix | |
+ in | |
+ ( { model | |
+ | totalHeight = element.height + element.y | |
+ , combinators = List.map (setInitialTime currentTime) model.combinators | |
+ } | |
+ , Cmd.none | |
+ ) | |
+ | |
+ Result.Err _ -> | |
+ ( model, Cmd.none ) | |
+ | |
+ Tick timePosix -> | |
+ let | |
+ currentTime = | |
+ Time.posixToMillis timePosix | |
+ | |
+ combinators = | |
+ List.map | |
+ (updateCombinators currentTime model.totalHeight) | |
+ model.combinators | |
+ in | |
+ ( { model | |
+ | combinators = combinators | |
+ } | |
+ , Cmd.none | |
+ ) | |
+ | |
+ | |
+initAnimation : String -> Cmd Msg | |
+initAnimation parentId = | |
+ Task.attempt | |
+ Init | |
+ (Task.map2 (\r -> \t -> ( t, r )) (getElement parentId) Time.now) | |
+ | |
+ | |
+onTick = | |
+ Task.perform Tick Time.now | |
-- Testing | |
-initModel : List Combinator | |
+initModel : Model | |
initModel = | |
- [ { letter = "S" | |
- , delay = 500 | |
- , translate = ( 0, 0 ) | |
- , shiftX = 20 | |
- } | |
- , { letter = "K" | |
- , delay = 0 | |
- , translate = ( 0, 0 ) | |
- , shiftX = 80 | |
- } | |
- ] | |
+ { totalHeight = 0 | |
+ , combinators = | |
+ [ { letter = "S" | |
+ , delay = 500 | |
+ , initialTime = 0 | |
+ , translate = ( 0, 0 ) | |
+ , shiftX = 20 | |
+ } | |
+ , { letter = "K" | |
+ , delay = 0 | |
+ , initialTime = 0 | |
+ , translate = ( 0, 0 ) | |
+ , shiftX = 80 | |
+ } | |
+ ] | |
+ } | |
+ | |
+ | |
+subscriptions : Model -> Sub Msg | |
+subscriptions model = | |
+ if model.totalHeight == 0 then | |
+ Sub.none | |
+ | |
+ else | |
+ onAnimationFrame Tick | |
combinatorWrapper : Combinator -> Html msg | |
@@ -67,6 +188,7 @@ combinatorWrapper data = | |
, bottom (px 0) | |
, left (pct sx) | |
, textLarge | |
+ , transforms [ translate2 (px tx) (px -ty) ] | |
-- temporary | |
, color Theme.colors.pink | |
@@ -75,8 +197,8 @@ combinatorWrapper data = | |
[ text label ] | |
-combinatorsBackground : List Combinator -> Html msg | |
-combinatorsBackground combinatorsList = | |
+combinatorsBackground : Model -> Html msg | |
+combinatorsBackground model = | |
div | |
[ css | |
[ position absolute | |
@@ -84,4 +206,4 @@ combinatorsBackground combinatorsList = | |
, Css.height (pct 100) | |
] | |
] | |
- (List.map combinatorWrapper combinatorsList) | |
+ (List.map combinatorWrapper model.combinators) | |
diff --git a/src/Main.elm b/src/Main.elm | |
index efad4f0..d5b3c46 100644 | |
--- a/src/Main.elm | |
+++ b/src/Main.elm | |
@@ -1,6 +1,10 @@ | |
module Main exposing (..) | |
import Browser | |
+import CombinatorsAnimated | |
+ exposing | |
+ ( combinatorsBackground | |
+ ) | |
import Contents | |
import Css exposing (..) | |
import Css.Global exposing (body, global) | |
@@ -78,7 +82,8 @@ lambdaDescription = | |
] | |
-homeSection = | |
+homeSection : Model -> Html msg | |
+homeSection model = | |
section | |
[ css | |
[ displayFlex | |
@@ -89,9 +94,12 @@ homeSection = | |
, maxWidth (px 720) | |
, boxSizing borderBox | |
, margin auto | |
+ , position relative | |
] | |
+ , id "home" | |
] | |
- [ lambdaLogoLarge | |
+ [ combinatorsBackground model.combinators | |
+ , lambdaLogoLarge | |
, lambdaTitleXLarge | |
, lambdaSeparator | |
, lambdaDescription | |
@@ -184,20 +192,30 @@ lambdaFooter = | |
type alias Model = | |
- String | |
+ { combinators : CombinatorsAnimated.Model | |
+ } | |
-init : () -> ( Model, Cmd msg ) | |
+type Msg | |
+ = UpdateCombinators CombinatorsAnimated.Msg | |
+ | |
+ | |
+init : () -> ( Model, Cmd Msg ) | |
init _ = | |
- ( "void", Cmd.none ) | |
+ ( { combinators = | |
+ CombinatorsAnimated.initModel | |
+ } | |
+ , Cmd.map UpdateCombinators (CombinatorsAnimated.initAnimation "home") | |
+ ) | |
+view : Model -> Browser.Document msg | |
view model = | |
{ title = Contents.title | |
, body = | |
List.map toUnstyled | |
[ globalCss | |
- , homeSection | |
+ , homeSection model | |
, languagesSection | |
, repositoriesSection | |
, lambdaFooter | |
@@ -205,12 +223,19 @@ view model = | |
} | |
-update _ model = | |
- ( model, Cmd.none ) | |
+update msg model = | |
+ case msg of | |
+ UpdateCombinators msgCombinators -> | |
+ let | |
+ ( combinators, cmdMsg ) = | |
+ CombinatorsAnimated.update msgCombinators model.combinators | |
+ in | |
+ ( { model | combinators = combinators }, Cmd.map UpdateCombinators cmdMsg ) | |
-subscriptions _ = | |
- Sub.none | |
+subscriptions model = | |
+ Sub.map UpdateCombinators | |
+ (CombinatorsAnimated.subscriptions model.combinators) | |
main = |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment