diff --git a/src/Main.elm b/src/Main.elm index 762f948..2af6de7 100644 --- a/src/Main.elm +++ b/src/Main.elm @@ -490,6 +490,7 @@ sitemap = (itemize ([ "/", "/index.html" ] ++ getPaths "src" ++ getPaths "index" ++ getPaths "home") pageHome ++ itemize (getPaths "entries") pageEntries ++ itemize (getPaths "about") pageAbout + ++ itemize (getPaths "colophon") colophon ) @@ -1365,6 +1366,125 @@ notFound model = ] +colophon : Model -> List (Html Msg) +colophon model = + [ Element.layout + [ width fill ] + (column [ width fill ] + [ column + [ width fill + , height fill + , spacing (vh2pt model -100) + ] + [ el + [ width fill + , height (vh2px model 100) + , Background.color black + ] + Element.none + , animatedEl crossfadeIn + [ width fill + , height (vh2px model 100) + , Background.gradient { angle = 45, steps = [ rgb255 100 200 0, rgb255 200 100 0 ] } + ] + Element.none + , animatedEl crossfadeOut + [ width fill + , height (vh2px model 100) + , Background.gradient { angle = 45, steps = [ rgb255 0 150 50, rgb255 0 50 150 ] } + ] + Element.none + , el + ([ alignLeft + , alignTop + , width (vw2px model 50) + , height (vh2px model 100) + , paddingEach + { top = vh2pt model 25 - 96 + , bottom = 0 + , left = vw2pt model 10 + , right = 0 + } + , id "zero" + ] + ++ heading + ) + (column + [ spacing 35 + ] + [ text "Colophon." + , row [ spacing 15 ] + [ linkBtnInt "← Back" "/" + , linkBtn "Source" "https://forgejo.mit.edu/ananthv/macgregor" + , btn "Literature" (Scroll "one") + ] + , paragraph (bodyText ++ [ Font.size 24, width (vw2px model 70) ]) + [ text "You may be wondering why a website (especially this one) has a colophon, which is typically reserved for books and other seemingly serious publications." ] + , paragraph (bodyText ++ [ width (vw2px model 70) ]) + [ text "This section exists to highlight our principles of development. This entire site, and most software components that it relies on (" + , inlineLink "Elm" "https://seas.harvard.edu/news/2015/10/alumni-profile-evan-czaplicki-ab-12" + , text ", " + , inlineLink "MIT Forgejo instance" "https://forgejo.mit.edu/" + , text ", " + , inlineLink "Athena servers" "https://ist.mit.edu/athena" + , text ", " + , inlineLink "software licensing" "https://en.wikipedia.org/wiki/MIT_License" + , text ", among others) was built in " + , paragraph [ Font.bold ] [ text "Cambridge, MA" ] + , text ". We make every effort possible to source " + , paragraph [ Font.bold ] [ text "local, free, and open-source software" ] + , text " and other infrastructure. We adhere strictly to the principles of " + , paragraph [ Font.bold ] [ inlineLink "free software" "https://www.gnu.org/philosophy/free-sw.html" ] + , text " (\"free\" as in \"freedom\"). This entire website is designed in a " + , inlineLink "purely functional" "https://en.wikipedia.org/wiki/Functional_programming" + , text " language and built using a purely functional " + , inlineLink "build tool" "https://nixos.org/" + , text " with provable reproducibility. In doing so, we build on decades of academic research to create a website that will survive the next generation of the internet. You can review some of the relevant literature involved in designing this website below." + ] + ] + ) + ] + , column + (page model ++ [ id "one", Background.color (rgb255 173 111 101) ]) + [ column (pageText model) + [ row [ spacing 10 ] + [ btn "↑" (Scroll "zero") + , btn "↓" (Scroll "two") + ] + , paragraph + subheading + [ text "Relevant literature" ] + , paragraph bodyText + [ text "Here is a sampling of the most relevant papers referenced in the most recent redesign of this website: (1) " + , inlineLink "\"Elm: Concurrent FRP for Functional GUIs\"" "https://elm-lang.org/assets/papers/concurrent-frp.pdf" + , text ", (2) " + , inlineLink "\"NeRF: Representing Scenes as Neural Radiance Fields for View Synthesis\"" "https://arxiv.org/abs/2003.08934" + , text ", (3) " + , inlineLink "\"The Purely Functional Software Deployment Model\"" "https://edolstra.github.io/pubs/phd-thesis.pdf" + , text ", (4) " + , inlineLink "\"Asynchronous Functional Reactive Programming for GUIs\"" "https://people.seas.harvard.edu/~chong/pubs/pldi13-elm.pdf" + , text ". Note that all these papers are " + , paragraph [ Font.bold ] [ text "open access" ] + , text " because we refuse to compromise our fundamental principles." + ] + ] + ] + , column + [ id "two", Background.color (rgb255 200 50 150), width fill, height (vh2px model 100) ] + [ el + [ alignLeft + , alignTop + , width (vw2px model 100) + , height (vh2px model 100) + , padding 0 + ] + (spin3D model) + ] + ] + ) + ] + + pyramidMesh : Mesh.Uniform coordinates pyramidMesh = let @@ -1415,6 +1535,55 @@ pyramidMesh = Mesh.indexedFacets triangularMesh +spin3D : Model -> Element msg +spin3D model = + Element.html + (let + entity : Entity Obj.Decode.ObjCoordinates + entity = + case model.mesh of + Nothing -> + Scene3d.mesh (Material.matte (Color.rgb255 173 111 101)) pyramidMesh + + Just mesh -> + case model.textures of + Nothing -> + Scene3d.mesh (Material.matte (Color.rgb255 173 111 101)) (Mesh.texturedFacets mesh) + + Just textures -> + Scene3d.mesh textures (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 (3 * model.angle) + in + Point3d.meters (model.radius * Angle.cos theta) 7 (-model.radius * Angle.sin theta) + , upDirection = Direction3d.xy (Angle.degrees 90) + } + , verticalFieldOfView = Angle.degrees 90 + } + in + Scene3d.sunny + { entities = [ entity ] + , camera = camera + , upDirection = Direction3d.x + , sunlightDirection = Direction3d.yz (Angle.degrees -120) + , background = Scene3d.transparentBackground + , clipDepth = Length.centimeters 1 + , shadows = False + , dimensions = ( Pixels.int (round (vw model 100)), Pixels.int (round (vh model 100)) ) + } + ) + + view3D : Model -> Element msg view3D model = Element.html @@ -1487,7 +1656,7 @@ view3DColors model = let theta : Angle.Angle theta = - Angle.degrees (5 / 2 * model.angle) + Angle.degrees (2 * model.angle) in Point3d.meters (10 * Angle.cos theta) 2 (10 * Angle.sin theta) , upDirection = Direction3d.xy (Angle.degrees 90)