~singpolyma/post-part

49cd267788fccd698bd5d54a081c39572a99a211 — Stephen Paul Weber 4 years ago 18b7714
Transcripts pop up along with their audio
3 files changed, 99 insertions(+), 24 deletions(-)

M Main.purs
M index.scss
M index.slim
M Main.purs => Main.purs +30 -11
@@ 20,7 20,7 @@ import Effect
import Data.Maybe
import Data.Array
import Debug.Trace
import Data.Foldable
import Data.Traversable
import Data.Tuple (Tuple(..))
import Data.Int as Int
import Web.DOM.ParentNode (querySelector, querySelectorAll, QuerySelector(..), ParentNode)


@@ 28,13 28,14 @@ import Web.DOM.Document as DOMDocument
import Web.HTML.HTMLDocument as HTMLDocument
import Web.HTML.HTMLElement as HTMLElement
import Web.HTML.HTMLMediaElement as HTMLMediaElement
import Web.HTML (window)
import Web.HTML (window, HTMLElement, HTMLMediaElement)
import Web.HTML.Event.EventTypes (load)
import Web.UIEvent.MouseEvent as MouseEvent
import Web.UIEvent.MouseEvent.EventTypes (mousemove, mouseout)
import Web.HTML.Window as Window
import Web.DOM.Element as Element
import Web.DOM.NodeList as NodeList
import Web.DOM.DOMTokenList as DOMTokenList
import Web.Event.EventTarget (addEventListener, eventListener)
import Partial.Unsafe (unsafePartial)
import Web.CSSOM.ElementCSSInlineStyle as Style


@@ 48,13 49,27 @@ clipCircle el size x y = do
  style <- Style.style $ Style.fromHTMLElement el
  Style.setProperty style "clip-path" ("circle(" <> size <> " at " <> (show x) <> "px " <> (show y) <> "px)")

triggerSpot :: Partial => ParentNode -> Maybe Int -> Effect Unit
getFigures :: ParentNode -> Effect (Array (Tuple HTMLElement HTMLMediaElement))
getFigures parent = do
  figNodes <- NodeList.toArray =<< querySelectorAll (QuerySelector "figure") parent
  let figEls = mapMaybe HTMLElement.fromNode figNodes
  audios <- catMaybes <$> traverse (\figure ->
      (HTMLMediaElement.fromElement =<< _) <$> querySelector (QuerySelector $ "audio") (HTMLElement.toParentNode figure)
    ) figEls
  pure $ zip figEls audios

triggerSpot :: ParentNode -> Maybe Int -> Effect Unit
triggerSpot doc n = do
  -- Just caption <- querySelector (QuerySelector $ "figure:nth-of-type(" <> show n <> ") > figcaption") doc
  audio <- NodeList.toArray =<< querySelectorAll (QuerySelector $ "figure > audio") doc
  traverse_ (\(Tuple i a) ->
      if Just i == n then HTMLMediaElement.play a else HTMLMediaElement.load a
    ) (zip (1..5) (mapMaybe (HTMLMediaElement.fromElement <=< Element.fromNode) audio))
  figures <- getFigures doc
  traverse_ (\(Tuple i (Tuple figure audio)) -> do
    style <- Style.style (Style.fromHTMLElement figure)
    if Just i == n then do
      Style.setProperty style "display" "block"
      HTMLMediaElement.play audio
    else do
      Style.setProperty style "display" "none"
      HTMLMediaElement.load audio
  ) (zip (1..5) figures)

triggerN width height x y =
  case Tuple across down of


@@ 73,17 88,21 @@ main = unsafePartial $ do
  doc <- HTMLDocument.toParentNode <$> Window.document win
  addEventListener' load (Window.toEventTarget win) $ \_ -> do
    Just wallpaper <- querySelector (QuerySelector "#wallpaper") doc
    height <- Element.clientHeight wallpaper
    width <- Element.clientWidth wallpaper

    Just img <- (HTMLElement.fromElement =<< _) <$>
      querySelector (QuerySelector "#wallpaper > img") doc

    (flip DOMTokenList.add "js") =<< Element.classList wallpaper
    clipCircle img "0" 0 0

    addEventListener' mouseout (Element.toEventTarget wallpaper) $ \_ ->
    addEventListener' mouseout (Element.toEventTarget wallpaper) $ \_ -> do
      clipCircle img "0" 0 0
      triggerSpot doc Nothing

    addEventListener' mousemove (Element.toEventTarget wallpaper) $ \e -> do
      height <- Element.clientHeight wallpaper
      width <- Element.clientWidth wallpaper
      let Just mouseEvent = MouseEvent.fromEvent e
      traceM (Tuple height (MouseEvent.offsetY mouseEvent))
      clipCircle img "10vw" (MouseEvent.offsetX mouseEvent) (MouseEvent.offsetY mouseEvent)
      triggerSpot doc (triggerN width height (MouseEvent.offsetX mouseEvent) (MouseEvent.offsetY mouseEvent))

M index.scss => index.scss +56 -0
@@ 158,7 158,63 @@ body > p {
}

#wallpaper {
	position: relative;
	background: url(assets/img/BROCADE.png);
	img {
		pointer-events: none;
		width: 100%;
	}

	figure {
		background: black;
		border-radius: 2em;
		padding: 1em;
		text-align: left;
		h1 {
			font-size: 1.25em;
			font-weight: normal;
			font-family: druk, sans-serif;
			color: $fg-alt;

			&:before { content: "“"; }
		}
		p:after { content: "”"; }
		&:last-of-type p:after { content: ""; }
	}

	&.js figure {
		display: none;
		pointer-events: none;
		position: absolute;
		width: 45%;

		&:nth-of-type(1) {
			top: 1em;
			right: 1em;
		}

		&:nth-of-type(2) {
			top: 1em;
			left: 1em;
		}

		&:nth-of-type(3) {
			top: 33%;
			right: 1em;
		}

		&:nth-of-type(4) {
			top: 33%;
			left: 1em;
		}

		&:nth-of-type(5) {
			bottom: 1em;
			right: 1em;
		}

		audio { display: none; }
	}
}

#credits {

M index.slim => index.slim +13 -13
@@ 43,19 43,19 @@ html
		#wallpaper
			img src="assets/img/WALLPAPER-HIDDEN.png" alt="Wallpaper"

		- (1..5).each do |n|
			figure
				figcaption
					h1= transcripts[n-1].shift
					p
						- transcripts[n-1].each_with_index do |t, i|
							- if i > 0
							  br
							= t
				audio controls="controls"
					source src="assets/audio/#{n}.opus" type="audio/ogg; codecs=opus"
					source src="assets/audio/#{n}.mp3" type="audio/mpeg"
					a href="assets/audio/#{n}.opus" listen
			- (1..5).each do |n|
				figure
					figcaption
						h1= transcripts[n-1].shift
						p
							- transcripts[n-1].each_with_index do |t, i|
								- if i > 0
								  br
								= t
					audio controls="controls"
						source src="assets/audio/#{n}.opus" type="audio/ogg; codecs=opus"
						source src="assets/audio/#{n}.mp3" type="audio/mpeg"
						a href="assets/audio/#{n}.opus" listen

		section#credits
			h1= paras[6]