feat: add entries page
This commit is contained in:
parent
95cd8fa0a8
commit
e1a1471058
3 changed files with 710 additions and 3 deletions
BIN
assets/img/jentry.png
Normal file
BIN
assets/img/jentry.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 44 KiB |
1
elm.json
1
elm.json
|
@ -3,6 +3,7 @@
|
||||||
"direct": {
|
"direct": {
|
||||||
"andrewMacmurray/elm-simple-animation": "2.3.2",
|
"andrewMacmurray/elm-simple-animation": "2.3.2",
|
||||||
"avh4/elm-color": "1.0.0",
|
"avh4/elm-color": "1.0.0",
|
||||||
|
"elm-community/list-extra": "8.7.0",
|
||||||
"elm-explorations/webgl": "1.1.3",
|
"elm-explorations/webgl": "1.1.3",
|
||||||
"elm/browser": "1.0.2",
|
"elm/browser": "1.0.2",
|
||||||
"elm/core": "1.0.5",
|
"elm/core": "1.0.5",
|
||||||
|
|
712
src/Main.elm
712
src/Main.elm
|
@ -20,6 +20,8 @@ import Html.Attributes
|
||||||
import Http
|
import Http
|
||||||
import Json.Decode as Decode
|
import Json.Decode as Decode
|
||||||
import Length
|
import Length
|
||||||
|
import List exposing (length)
|
||||||
|
import List.Extra exposing (getAt)
|
||||||
import Obj.Decode
|
import Obj.Decode
|
||||||
import Pixels
|
import Pixels
|
||||||
import Point3d exposing (Point3d)
|
import Point3d exposing (Point3d)
|
||||||
|
@ -76,7 +78,20 @@ main =
|
||||||
|
|
||||||
|
|
||||||
type alias Model =
|
type alias Model =
|
||||||
{ w : Int, h : Int, last : String, url : Url.Url, key : Nav.Key, mesh : Maybe Object3d, textures : Maybe (Material.Textured Obj.Decode.ObjCoordinates), angle : Float, radius : Float, elevation : Float }
|
{ w : Int
|
||||||
|
, h : Int
|
||||||
|
, last : String
|
||||||
|
, url : Url.Url
|
||||||
|
, key : Nav.Key
|
||||||
|
, mesh : Maybe Object3d
|
||||||
|
, textures : Maybe (Material.Textured Obj.Decode.ObjCoordinates)
|
||||||
|
, angle : Float
|
||||||
|
, radius : Float
|
||||||
|
, elevation : Float
|
||||||
|
, mainColor : Color.Color
|
||||||
|
, show : Bool
|
||||||
|
, entry : String
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
type alias Flags =
|
type alias Flags =
|
||||||
|
@ -89,7 +104,22 @@ init flags url key =
|
||||||
( width, height ) =
|
( width, height ) =
|
||||||
flags
|
flags
|
||||||
in
|
in
|
||||||
( { w = width, h = height, last = "", url = url, key = key, mesh = Nothing, textures = Nothing, angle = 0, radius = 7.5, elevation = 5 }, Cmd.batch [ getMesh, getTexture ] )
|
( { w = width
|
||||||
|
, h = height
|
||||||
|
, last = ""
|
||||||
|
, url = url
|
||||||
|
, key = key
|
||||||
|
, mesh = Nothing
|
||||||
|
, textures = Nothing
|
||||||
|
, angle = 0
|
||||||
|
, radius = 7.5
|
||||||
|
, elevation = 5
|
||||||
|
, mainColor = Color.rgb 173 111 101
|
||||||
|
, show = False
|
||||||
|
, entry = "zero"
|
||||||
|
}
|
||||||
|
, Cmd.batch [ getMesh, getTexture ]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
type alias Object3d =
|
type alias Object3d =
|
||||||
|
@ -106,6 +136,7 @@ type Msg
|
||||||
| Copy String String
|
| Copy String String
|
||||||
| Key String
|
| Key String
|
||||||
| Scroll String
|
| Scroll String
|
||||||
|
| ScrollToEntry String
|
||||||
|
|
||||||
|
|
||||||
modulo : Float -> Float -> Float
|
modulo : Float -> Float -> Float
|
||||||
|
@ -118,6 +149,67 @@ canonicalize angle =
|
||||||
modulo 360 angle
|
modulo 360 angle
|
||||||
|
|
||||||
|
|
||||||
|
frac : Float -> Float
|
||||||
|
frac x =
|
||||||
|
x - toFloat (floor x)
|
||||||
|
|
||||||
|
|
||||||
|
mainColors : List ( Float, Float, Float )
|
||||||
|
mainColors =
|
||||||
|
[ ( 173, 111, 101 ), ( 200, 0, 100 ), ( 100, 0, 200 ), ( 100, 200, 0 ), ( 200, 100, 0 ), ( 173, 111, 101 ) ]
|
||||||
|
|
||||||
|
|
||||||
|
blend : Float -> ( Float, Float, Float ) -> ( Float, Float, Float ) -> Color.Color
|
||||||
|
blend p ( r1, g1, b1 ) ( r2, g2, b2 ) =
|
||||||
|
let
|
||||||
|
blendFlux : Float -> Float -> Float -> Int
|
||||||
|
blendFlux t a b =
|
||||||
|
round (sqrt ((1 - t) * (a ^ 2) + t * (b ^ 2)))
|
||||||
|
in
|
||||||
|
Color.rgb255 (blendFlux p r1 r2) (blendFlux p g1 g2) (blendFlux p b1 b2)
|
||||||
|
|
||||||
|
|
||||||
|
blender : Float -> Color.Color
|
||||||
|
blender t =
|
||||||
|
let
|
||||||
|
n : Int
|
||||||
|
n =
|
||||||
|
length mainColors
|
||||||
|
|
||||||
|
p : Float
|
||||||
|
p =
|
||||||
|
frac (t * toFloat n)
|
||||||
|
|
||||||
|
c1 : Maybe ( Float, Float, Float )
|
||||||
|
c1 =
|
||||||
|
getAt (floor (t * toFloat n)) mainColors
|
||||||
|
|
||||||
|
c2 : Maybe ( Float, Float, Float )
|
||||||
|
c2 =
|
||||||
|
getAt (ceiling (t * toFloat n)) mainColors
|
||||||
|
in
|
||||||
|
case c2 of
|
||||||
|
Nothing ->
|
||||||
|
case c1 of
|
||||||
|
Nothing ->
|
||||||
|
-- no colors to blend
|
||||||
|
Color.rgb255 173 111 101
|
||||||
|
|
||||||
|
Just ( r, g, b ) ->
|
||||||
|
-- missing color to blend
|
||||||
|
Color.rgb255 (round r) (round g) (round b)
|
||||||
|
|
||||||
|
Just color2 ->
|
||||||
|
case c1 of
|
||||||
|
Nothing ->
|
||||||
|
-- missing main color to blend
|
||||||
|
Color.rgb255 173 111 101
|
||||||
|
|
||||||
|
Just color1 ->
|
||||||
|
-- blend both colors
|
||||||
|
blend p color1 color2
|
||||||
|
|
||||||
|
|
||||||
update : Msg -> Model -> ( Model, Cmd Msg )
|
update : Msg -> Model -> ( Model, Cmd Msg )
|
||||||
update msg model =
|
update msg model =
|
||||||
let
|
let
|
||||||
|
@ -170,6 +262,8 @@ update msg model =
|
||||||
| angle = canonicalize (model.angle + 2 * (2 + sin (toFloat (Time.posixToMillis time) / 1000)))
|
| angle = canonicalize (model.angle + 2 * (2 + sin (toFloat (Time.posixToMillis time) / 1000)))
|
||||||
, radius = 7.5 + 1 / 8 * model.radius + 5 * 13 / 11 * sin (toFloat (Time.posixToMillis time + 250) / 1000)
|
, radius = 7.5 + 1 / 8 * model.radius + 5 * 13 / 11 * sin (toFloat (Time.posixToMillis time + 250) / 1000)
|
||||||
, elevation = 9 + 1 / 4 * model.elevation + 5 * cos (toFloat (Time.posixToMillis time) / 1000)
|
, elevation = 9 + 1 / 4 * model.elevation + 5 * cos (toFloat (Time.posixToMillis time) / 1000)
|
||||||
|
, mainColor = blender (frac (toFloat (Time.posixToMillis time) / 3500))
|
||||||
|
, show = modBy 4000 (Time.posixToMillis time) > 2000
|
||||||
}
|
}
|
||||||
|
|
||||||
Copy label text ->
|
Copy label text ->
|
||||||
|
@ -181,6 +275,9 @@ update msg model =
|
||||||
Scroll loc ->
|
Scroll loc ->
|
||||||
( model, scrollTo loc )
|
( model, scrollTo loc )
|
||||||
|
|
||||||
|
ScrollToEntry entry ->
|
||||||
|
( { model | entry = entry }, scrollTo entry )
|
||||||
|
|
||||||
|
|
||||||
keyDecoder : Decode.Decoder String
|
keyDecoder : Decode.Decoder String
|
||||||
keyDecoder =
|
keyDecoder =
|
||||||
|
@ -234,6 +331,22 @@ linkBtn disp addr =
|
||||||
newTabLink btnStyle { url = addr, label = text (String.toUpper disp) }
|
newTabLink btnStyle { url = addr, label = text (String.toUpper disp) }
|
||||||
|
|
||||||
|
|
||||||
|
linkBtnInt : String -> String -> Element msg
|
||||||
|
linkBtnInt disp addr =
|
||||||
|
link btnStyle { url = addr, label = text (String.toUpper disp) }
|
||||||
|
|
||||||
|
|
||||||
|
entryLink : String -> String -> Element Msg
|
||||||
|
entryLink disp addr =
|
||||||
|
button
|
||||||
|
[ Font.underline
|
||||||
|
, Font.bold
|
||||||
|
]
|
||||||
|
{ onPress = Just (ScrollToEntry addr)
|
||||||
|
, label = text disp
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
btn : String -> Msg -> Element Msg
|
btn : String -> Msg -> Element Msg
|
||||||
btn disp act =
|
btn disp act =
|
||||||
button btnStyle { onPress = Just act, label = text (String.toUpper disp) }
|
button btnStyle { onPress = Just act, label = text (String.toUpper disp) }
|
||||||
|
@ -370,7 +483,10 @@ itemize multikeys entry =
|
||||||
|
|
||||||
sitemap : Dict String (Model -> List (Html Msg))
|
sitemap : Dict String (Model -> List (Html Msg))
|
||||||
sitemap =
|
sitemap =
|
||||||
Dict.fromList (itemize ([ "/", "/index.html" ] ++ getPaths "src" ++ getPaths "index" ++ getPaths "home") pageHome)
|
Dict.fromList
|
||||||
|
(itemize ([ "/", "/index.html" ] ++ getPaths "src" ++ getPaths "index" ++ getPaths "home") pageHome
|
||||||
|
++ itemize (getPaths "entries") pageEntries
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
loadUrl : Model -> List (Html Msg)
|
loadUrl : Model -> List (Html Msg)
|
||||||
|
@ -608,6 +724,407 @@ pageHome model =
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
pageEntries : Model -> List (Html Msg)
|
||||||
|
pageEntries model =
|
||||||
|
[ Element.layout
|
||||||
|
[ width fill
|
||||||
|
]
|
||||||
|
(column [ width fill ]
|
||||||
|
[ column
|
||||||
|
[ width fill
|
||||||
|
, height fill
|
||||||
|
, spacing (vh2pt model -100)
|
||||||
|
, id "zero"
|
||||||
|
]
|
||||||
|
[ el
|
||||||
|
[ width fill
|
||||||
|
, height (vh2px model 100)
|
||||||
|
, Background.color black
|
||||||
|
]
|
||||||
|
Element.none
|
||||||
|
, animatedEl crossfadeIn
|
||||||
|
[ width fill
|
||||||
|
, height (vh2px model 100)
|
||||||
|
, Background.gradient { angle = 360 - 45, steps = [ rgb255 100 125 50, rgb255 125 50 100 ] }
|
||||||
|
]
|
||||||
|
Element.none
|
||||||
|
, animatedEl crossfadeOut
|
||||||
|
[ width fill
|
||||||
|
, height (vh2px model 100)
|
||||||
|
, Background.gradient { angle = 360 - 45, steps = [ rgb255 100 50 175, rgb255 100 175 50 ] }
|
||||||
|
]
|
||||||
|
Element.none
|
||||||
|
, el
|
||||||
|
([ alignLeft
|
||||||
|
, alignTop
|
||||||
|
, width (vw2px model 50)
|
||||||
|
, height (vh2px model 100)
|
||||||
|
, paddingEach
|
||||||
|
{ top = vh2pt model 20 - 96
|
||||||
|
, bottom = 0
|
||||||
|
, left = vw2pt model 10
|
||||||
|
, right = 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
++ heading
|
||||||
|
)
|
||||||
|
(column
|
||||||
|
[ spacing 35
|
||||||
|
]
|
||||||
|
[ menu model
|
||||||
|
, text "Meet the entries"
|
||||||
|
, paragraph bodyText
|
||||||
|
[ entryLink "A entry" "A"
|
||||||
|
, text ", "
|
||||||
|
, entryLink "Bentry" "B"
|
||||||
|
, text " (Office of the President), "
|
||||||
|
, entryLink "Centry" "C"
|
||||||
|
, text " (the C is silent), "
|
||||||
|
, entryLink "Dentry" "D"
|
||||||
|
, text ", "
|
||||||
|
, entryLink "E entry" "E"
|
||||||
|
, text ", "
|
||||||
|
, entryLink "Fentry" "F"
|
||||||
|
, text ", "
|
||||||
|
, entryLink "Gentry" "G"
|
||||||
|
, text " (hard G), "
|
||||||
|
, entryLink "Hentry" "H"
|
||||||
|
, text ", 𝑖 entry (imaginary),"
|
||||||
|
, image [ height (px 24), padding 10 ] { description = "flag of j entry", src = "../assets/img/jentry.png" }
|
||||||
|
, entryLink "Jentry" "J"
|
||||||
|
]
|
||||||
|
, column [ spacing 15 ]
|
||||||
|
[ row
|
||||||
|
[ spacing 15
|
||||||
|
]
|
||||||
|
[ linkBtnInt "← Back" "/"
|
||||||
|
, btn "Explore ↓" (ScrollToEntry "J")
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
)
|
||||||
|
, el
|
||||||
|
[ alignRight
|
||||||
|
, alignTop
|
||||||
|
, width (vw2px model 60)
|
||||||
|
, height (vh2px model 100)
|
||||||
|
, paddingEach
|
||||||
|
{ top = vh2pt model 25
|
||||||
|
, bottom = vh2pt model 25
|
||||||
|
, left = 0
|
||||||
|
, right = 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
(if model.entry == "zero" then
|
||||||
|
view3DColors model
|
||||||
|
|
||||||
|
else
|
||||||
|
Element.none
|
||||||
|
)
|
||||||
|
]
|
||||||
|
, column
|
||||||
|
(page model ++ [ id "J", Background.color (rgb255 76 76 254) ])
|
||||||
|
[ column (pageText model)
|
||||||
|
[ row [ spacing 10 ]
|
||||||
|
[ btn "↑" (ScrollToEntry "zero")
|
||||||
|
, btn "↓" (ScrollToEntry "A")
|
||||||
|
]
|
||||||
|
, paragraph
|
||||||
|
subheading
|
||||||
|
[ text "Welcome to the Jentry." ]
|
||||||
|
, paragraph (bodyText ++ [ Font.size 32 ])
|
||||||
|
[ text "(J Entry) The heart of MacGregor. Historic culture, big lore. Jentry memes. Greatest MacGregor Housecomm representation of any entry. Jamily is forever."
|
||||||
|
, image [ width (px 48), padding 12 ] { description = "flag of j entry", src = "../assets/img/jentry.png" }
|
||||||
|
]
|
||||||
|
]
|
||||||
|
, el
|
||||||
|
[ alignRight
|
||||||
|
, alignTop
|
||||||
|
, width (vw2px model 60)
|
||||||
|
, height (vh2px model 100)
|
||||||
|
, paddingEach
|
||||||
|
{ top = vh2pt model 25
|
||||||
|
, bottom = vh2pt model 25
|
||||||
|
, left = 0
|
||||||
|
, right = 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
(if model.entry == "J" then
|
||||||
|
view3DEntries "J" model
|
||||||
|
|
||||||
|
else
|
||||||
|
Element.none
|
||||||
|
)
|
||||||
|
]
|
||||||
|
, column
|
||||||
|
(page model ++ [ id "A", Background.color (rgb255 5 93 243) ])
|
||||||
|
[ column (pageText model)
|
||||||
|
[ row [ spacing 10 ]
|
||||||
|
[ btn "↑" (ScrollToEntry "J")
|
||||||
|
, btn "↓" (ScrollToEntry "B")
|
||||||
|
]
|
||||||
|
, paragraph
|
||||||
|
subheading
|
||||||
|
[ text "Welcome to A Entry." ]
|
||||||
|
, paragraph (bodyText ++ [ Font.size 32 ])
|
||||||
|
[ text "Top floor. Top dog. Lots of dogs, in fact. Historic MacGregor cultural epicenter."
|
||||||
|
]
|
||||||
|
]
|
||||||
|
, el
|
||||||
|
[ alignRight
|
||||||
|
, alignTop
|
||||||
|
, width (vw2px model 60)
|
||||||
|
, height (vh2px model 100)
|
||||||
|
, paddingEach
|
||||||
|
{ top = vh2pt model 25
|
||||||
|
, bottom = vh2pt model 25
|
||||||
|
, left = 0
|
||||||
|
, right = 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
(if model.entry == "A" then
|
||||||
|
view3DEntries "A" model
|
||||||
|
|
||||||
|
else
|
||||||
|
Element.none
|
||||||
|
)
|
||||||
|
]
|
||||||
|
, column
|
||||||
|
(page model ++ [ id "B", Background.color (rgb255 5 180 93) ])
|
||||||
|
[ column (pageText model)
|
||||||
|
[ row [ spacing 10 ]
|
||||||
|
[ btn "↑" (ScrollToEntry "A")
|
||||||
|
, btn "↓" (ScrollToEntry "C")
|
||||||
|
]
|
||||||
|
, paragraph
|
||||||
|
subheading
|
||||||
|
[ text "Welcome to the Bentry." ]
|
||||||
|
, paragraph (bodyText ++ [ Font.size 32 ])
|
||||||
|
[ text "(B Entry) Office of the President. Sweeping views. Crossroads of the High Rise. B is for burgers?"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
, el
|
||||||
|
[ alignRight
|
||||||
|
, alignTop
|
||||||
|
, width (vw2px model 60)
|
||||||
|
, height (vh2px model 100)
|
||||||
|
, paddingEach
|
||||||
|
{ top = vh2pt model 25
|
||||||
|
, bottom = vh2pt model 25
|
||||||
|
, left = 0
|
||||||
|
, right = 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
(if model.entry == "B" then
|
||||||
|
view3DEntries "B" model
|
||||||
|
|
||||||
|
else
|
||||||
|
Element.none
|
||||||
|
)
|
||||||
|
]
|
||||||
|
, column
|
||||||
|
(page model ++ [ id "C", Background.color (rgb255 5 140 40) ])
|
||||||
|
[ column (pageText model)
|
||||||
|
[ row [ spacing 10 ]
|
||||||
|
[ btn "↑" (ScrollToEntry "B")
|
||||||
|
, btn "↓" (ScrollToEntry "D")
|
||||||
|
]
|
||||||
|
, paragraph
|
||||||
|
subheading
|
||||||
|
[ text "Welcome to Centry." ]
|
||||||
|
, paragraph (bodyText ++ [ Font.size 32 ])
|
||||||
|
[ text "(C Entry) Ceriously quiet. High enough to see the clouds, but low enough to stay grounded. MacGregor's creative capital core."
|
||||||
|
]
|
||||||
|
]
|
||||||
|
, el
|
||||||
|
[ alignRight
|
||||||
|
, alignTop
|
||||||
|
, width (vw2px model 60)
|
||||||
|
, height (vh2px model 100)
|
||||||
|
, paddingEach
|
||||||
|
{ top = vh2pt model 25
|
||||||
|
, bottom = vh2pt model 25
|
||||||
|
, left = 0
|
||||||
|
, right = 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
(if model.entry == "C" then
|
||||||
|
view3DEntries "C" model
|
||||||
|
|
||||||
|
else
|
||||||
|
Element.none
|
||||||
|
)
|
||||||
|
]
|
||||||
|
, column
|
||||||
|
(page model ++ [ id "D", Background.color (rgb255 240 140 40) ])
|
||||||
|
[ column (pageText model)
|
||||||
|
[ row [ spacing 10 ]
|
||||||
|
[ btn "↑" (ScrollToEntry "C")
|
||||||
|
, btn "↓" (ScrollToEntry "E")
|
||||||
|
]
|
||||||
|
, paragraph
|
||||||
|
subheading
|
||||||
|
[ text "Welcome to Dentry." ]
|
||||||
|
, paragraph (bodyText ++ [ Font.size 32 ])
|
||||||
|
[ text "(D Entry) Office of the Vice President. Active after dark. Diligently working until dusk. The culture is palpable."
|
||||||
|
]
|
||||||
|
]
|
||||||
|
, el
|
||||||
|
[ alignRight
|
||||||
|
, alignTop
|
||||||
|
, width (vw2px model 60)
|
||||||
|
, height (vh2px model 100)
|
||||||
|
, paddingEach
|
||||||
|
{ top = vh2pt model 25
|
||||||
|
, bottom = vh2pt model 25
|
||||||
|
, left = 0
|
||||||
|
, right = 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
(if model.entry == "D" then
|
||||||
|
view3DEntries "D" model
|
||||||
|
|
||||||
|
else
|
||||||
|
Element.none
|
||||||
|
)
|
||||||
|
]
|
||||||
|
, column
|
||||||
|
(page model ++ [ id "E", Background.color (rgb255 40 20 30) ])
|
||||||
|
[ column (pageText model)
|
||||||
|
[ row [ spacing 10 ]
|
||||||
|
[ btn "↑" (ScrollToEntry "D")
|
||||||
|
, btn "↓" (ScrollToEntry "F")
|
||||||
|
]
|
||||||
|
, paragraph
|
||||||
|
subheading
|
||||||
|
[ text "Welcome to E entry." ]
|
||||||
|
, paragraph (bodyText ++ [ Font.size 32 ])
|
||||||
|
[ text "Board games over Briggs field. Excellence in everything. End of story."
|
||||||
|
]
|
||||||
|
]
|
||||||
|
, el
|
||||||
|
[ alignRight
|
||||||
|
, alignTop
|
||||||
|
, width (vw2px model 60)
|
||||||
|
, height (vh2px model 100)
|
||||||
|
, paddingEach
|
||||||
|
{ top = vh2pt model 25
|
||||||
|
, bottom = vh2pt model 25
|
||||||
|
, left = 0
|
||||||
|
, right = 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
(if model.entry == "E" then
|
||||||
|
view3DEntries "E" model
|
||||||
|
|
||||||
|
else
|
||||||
|
Element.none
|
||||||
|
)
|
||||||
|
]
|
||||||
|
, column
|
||||||
|
(page model ++ [ id "F", Background.color (rgb255 200 50 75) ])
|
||||||
|
[ column (pageText model)
|
||||||
|
[ row [ spacing 10 ]
|
||||||
|
[ btn "↑" (ScrollToEntry "E")
|
||||||
|
, btn "↓" (ScrollToEntry "G")
|
||||||
|
]
|
||||||
|
, paragraph
|
||||||
|
subheading
|
||||||
|
[ text "Welcome to the Fentry." ]
|
||||||
|
, paragraph (bodyText ++ [ Font.size 32 ])
|
||||||
|
[ text "(F entry) F is for Food. F is for Feast. F is for First (low rise block). F is Forever."
|
||||||
|
]
|
||||||
|
]
|
||||||
|
, el
|
||||||
|
[ alignRight
|
||||||
|
, alignTop
|
||||||
|
, width (vw2px model 60)
|
||||||
|
, height (vh2px model 100)
|
||||||
|
, paddingEach
|
||||||
|
{ top = vh2pt model 25
|
||||||
|
, bottom = vh2pt model 25
|
||||||
|
, left = 0
|
||||||
|
, right = 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
(if model.entry == "F" then
|
||||||
|
view3DEntries "F" model
|
||||||
|
|
||||||
|
else
|
||||||
|
Element.none
|
||||||
|
)
|
||||||
|
]
|
||||||
|
, column
|
||||||
|
(page model ++ [ id "G", Background.color (rgb255 200 50 150) ])
|
||||||
|
[ column (pageText model)
|
||||||
|
[ row [ spacing 10 ]
|
||||||
|
[ btn "↑" (ScrollToEntry "F")
|
||||||
|
, btn "↓" (ScrollToEntry "H")
|
||||||
|
]
|
||||||
|
, paragraph
|
||||||
|
subheading
|
||||||
|
[ text "Welcome to the Gentry." ]
|
||||||
|
, paragraph (bodyText ++ [ Font.size 32 ])
|
||||||
|
[ text "(G entry) G is for Greatness. Spans the Charles. Overlooks Fenway. Good things start in Gentry."
|
||||||
|
]
|
||||||
|
]
|
||||||
|
, el
|
||||||
|
[ alignRight
|
||||||
|
, alignTop
|
||||||
|
, width (vw2px model 60)
|
||||||
|
, height (vh2px model 100)
|
||||||
|
, paddingEach
|
||||||
|
{ top = vh2pt model 25
|
||||||
|
, bottom = vh2pt model 25
|
||||||
|
, left = 0
|
||||||
|
, right = 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
(if model.entry == "G" then
|
||||||
|
view3DEntries "G" model
|
||||||
|
|
||||||
|
else
|
||||||
|
Element.none
|
||||||
|
)
|
||||||
|
]
|
||||||
|
, column
|
||||||
|
(page model ++ [ id "H", Background.color (rgb255 200 150 50) ])
|
||||||
|
[ column (pageText model)
|
||||||
|
[ row [ spacing 10 ]
|
||||||
|
[ btn "↑" (ScrollToEntry "G")
|
||||||
|
, btn "TOP" (ScrollToEntry "zero")
|
||||||
|
]
|
||||||
|
, paragraph
|
||||||
|
subheading
|
||||||
|
[ text "Welcome to the Hentry." ]
|
||||||
|
, paragraph (bodyText ++ [ Font.size 32 ])
|
||||||
|
[ text "(H entry) Lots of chickens. Crossroads of the Low Rise. Largest entry in MacGregor."
|
||||||
|
]
|
||||||
|
]
|
||||||
|
, el
|
||||||
|
[ alignRight
|
||||||
|
, alignTop
|
||||||
|
, width (vw2px model 60)
|
||||||
|
, height (vh2px model 100)
|
||||||
|
, paddingEach
|
||||||
|
{ top = vh2pt model 25
|
||||||
|
, bottom = vh2pt model 25
|
||||||
|
, left = 0
|
||||||
|
, right = 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
(if model.entry == "H" then
|
||||||
|
view3DEntries "H" model
|
||||||
|
|
||||||
|
else
|
||||||
|
Element.none
|
||||||
|
)
|
||||||
|
]
|
||||||
|
]
|
||||||
|
)
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
notFound : Model -> List (Html Msg)
|
notFound : Model -> List (Html Msg)
|
||||||
notFound model =
|
notFound model =
|
||||||
[ Element.layout
|
[ Element.layout
|
||||||
|
@ -785,6 +1302,195 @@ view3D model =
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
view3DColors : Model -> Element msg
|
||||||
|
view3DColors model =
|
||||||
|
Element.html
|
||||||
|
(let
|
||||||
|
entity : Entity Obj.Decode.ObjCoordinates
|
||||||
|
entity =
|
||||||
|
case model.mesh of
|
||||||
|
Nothing ->
|
||||||
|
Scene3d.mesh (Material.matte model.mainColor) pyramidMesh
|
||||||
|
|
||||||
|
Just mesh ->
|
||||||
|
Scene3d.mesh (Material.matte model.mainColor) (Mesh.texturedFacets mesh)
|
||||||
|
|
||||||
|
camera : Camera3d.Camera3d Length.Meters coordinates
|
||||||
|
camera =
|
||||||
|
Camera3d.perspective
|
||||||
|
{ viewpoint =
|
||||||
|
Viewpoint3d.lookAt
|
||||||
|
{ focalPoint = Point3d.origin
|
||||||
|
, eyePoint =
|
||||||
|
let
|
||||||
|
theta : Angle.Angle
|
||||||
|
theta =
|
||||||
|
Angle.degrees (5 / 2 * model.angle)
|
||||||
|
in
|
||||||
|
Point3d.meters (10 * Angle.cos theta) 2 (10 * Angle.sin theta)
|
||||||
|
, upDirection = Direction3d.xy (Angle.degrees 90)
|
||||||
|
}
|
||||||
|
, verticalFieldOfView = Angle.degrees 100
|
||||||
|
}
|
||||||
|
in
|
||||||
|
Scene3d.sunny
|
||||||
|
{ entities = [ entity ]
|
||||||
|
, camera = camera
|
||||||
|
, upDirection = Direction3d.z
|
||||||
|
, sunlightDirection = Direction3d.yz (Angle.degrees -120)
|
||||||
|
, background = Scene3d.transparentBackground
|
||||||
|
, clipDepth = Length.centimeters 1
|
||||||
|
, shadows = False
|
||||||
|
, dimensions = ( Pixels.int (round (vw model 60)), Pixels.int (round (vh model 100)) )
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
view3DEntries : String -> Model -> Element msg
|
||||||
|
view3DEntries entry model =
|
||||||
|
Element.html
|
||||||
|
(let
|
||||||
|
entity : Entity Obj.Decode.ObjCoordinates
|
||||||
|
entity =
|
||||||
|
case model.mesh of
|
||||||
|
Nothing ->
|
||||||
|
Scene3d.mesh (Material.matte model.mainColor) pyramidMesh
|
||||||
|
|
||||||
|
Just mesh ->
|
||||||
|
case model.textures of
|
||||||
|
Nothing ->
|
||||||
|
Scene3d.mesh (Material.matte model.mainColor) (Mesh.texturedFacets mesh)
|
||||||
|
|
||||||
|
Just textures ->
|
||||||
|
if model.show then
|
||||||
|
Scene3d.mesh (Material.matte model.mainColor) (Mesh.texturedFacets mesh)
|
||||||
|
|
||||||
|
else
|
||||||
|
Scene3d.mesh textures (Mesh.texturedFacets mesh)
|
||||||
|
|
||||||
|
height : Float
|
||||||
|
height =
|
||||||
|
case entry of
|
||||||
|
"A" ->
|
||||||
|
10
|
||||||
|
|
||||||
|
"B" ->
|
||||||
|
7
|
||||||
|
|
||||||
|
"C" ->
|
||||||
|
5
|
||||||
|
|
||||||
|
"E" ->
|
||||||
|
1
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
2
|
||||||
|
|
||||||
|
perspective : Angle.Angle
|
||||||
|
perspective =
|
||||||
|
let
|
||||||
|
theta : Float
|
||||||
|
theta =
|
||||||
|
180 * frac (model.angle / 180)
|
||||||
|
|
||||||
|
winding : Float
|
||||||
|
winding =
|
||||||
|
360 * frac (model.angle / 360)
|
||||||
|
|
||||||
|
direction : Float
|
||||||
|
direction =
|
||||||
|
abs (180 - winding) / (180 - winding)
|
||||||
|
|
||||||
|
interp : Float -> Float -> Angle.Angle
|
||||||
|
interp a b =
|
||||||
|
Angle.degrees
|
||||||
|
(if direction > 0 then
|
||||||
|
a + (b - a) * theta / 180
|
||||||
|
|
||||||
|
else
|
||||||
|
b + (a - b) * theta / 180
|
||||||
|
)
|
||||||
|
in
|
||||||
|
case entry of
|
||||||
|
"J" ->
|
||||||
|
interp -45 30
|
||||||
|
|
||||||
|
"E" ->
|
||||||
|
interp 30 110
|
||||||
|
|
||||||
|
"F" ->
|
||||||
|
interp 140 230
|
||||||
|
|
||||||
|
"G" ->
|
||||||
|
interp 230 290
|
||||||
|
|
||||||
|
"H" ->
|
||||||
|
interp 290 315
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
Angle.degrees model.angle
|
||||||
|
|
||||||
|
orbit : Float
|
||||||
|
orbit =
|
||||||
|
case entry of
|
||||||
|
"A" ->
|
||||||
|
4
|
||||||
|
|
||||||
|
"B" ->
|
||||||
|
6
|
||||||
|
|
||||||
|
"C" ->
|
||||||
|
6
|
||||||
|
|
||||||
|
"D" ->
|
||||||
|
10
|
||||||
|
|
||||||
|
"F" ->
|
||||||
|
12
|
||||||
|
|
||||||
|
"G" ->
|
||||||
|
10
|
||||||
|
|
||||||
|
"J" ->
|
||||||
|
12
|
||||||
|
|
||||||
|
"H" ->
|
||||||
|
11
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
7
|
||||||
|
|
||||||
|
camera : Camera3d.Camera3d Length.Meters coordinates
|
||||||
|
camera =
|
||||||
|
Camera3d.perspective
|
||||||
|
{ viewpoint =
|
||||||
|
Viewpoint3d.lookAt
|
||||||
|
{ focalPoint = Point3d.origin
|
||||||
|
, eyePoint =
|
||||||
|
let
|
||||||
|
theta : Angle.Angle
|
||||||
|
theta =
|
||||||
|
perspective
|
||||||
|
in
|
||||||
|
Point3d.meters (orbit * Angle.cos theta) height (orbit * Angle.sin theta)
|
||||||
|
, upDirection = Direction3d.xy (Angle.degrees 90)
|
||||||
|
}
|
||||||
|
, verticalFieldOfView = Angle.degrees 60
|
||||||
|
}
|
||||||
|
in
|
||||||
|
Scene3d.sunny
|
||||||
|
{ entities = [ entity ]
|
||||||
|
, camera = camera
|
||||||
|
, upDirection = Direction3d.z
|
||||||
|
, sunlightDirection = Direction3d.yz (Angle.degrees -120)
|
||||||
|
, background = Scene3d.transparentBackground
|
||||||
|
, clipDepth = Length.centimeters 1
|
||||||
|
, shadows = False
|
||||||
|
, dimensions = ( Pixels.int (round (vw model 60)), Pixels.int (round (vh model 100)) )
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
view3DTower : Model -> Element msg
|
view3DTower : Model -> Element msg
|
||||||
view3DTower model =
|
view3DTower model =
|
||||||
Element.html
|
Element.html
|
||||||
|
|
Loading…
Reference in a new issue