66 lines
2.9 KiB
Clojure
66 lines
2.9 KiB
Clojure
(ns heyarne.all-my-friends.views
|
|
(:require [reagent.core :as r]
|
|
[heyarne.all-my-friends.facemesh :refer [webcam-facemesh]]))
|
|
|
|
;; minimalistic re-frame-like event handling
|
|
|
|
(defonce state (r/atom {:status :welcome-message}))
|
|
|
|
(def events
|
|
{:welcome/continue (fn [db _]
|
|
(assoc db :status :running))
|
|
:running/snapshot (fn [db result]
|
|
(assoc-in db [:snapshots :current] result))})
|
|
|
|
(defn dispatch [[event data]]
|
|
(when-let [handler (events event)]
|
|
(js/requestAnimationFrame #(swap! state handler data))))
|
|
|
|
;; views
|
|
|
|
(defn welcome-message [{:keys [hidden?]}]
|
|
[:section#welcome-message
|
|
{:class (str (when hidden? "hidden"))}
|
|
[:h1 "Hi Freund!"]
|
|
[:p "Ich möchte dir kurz erklären, was dich hier erwartet:
|
|
Seit der globalen Covid19-Pandemie sind wir alle dazu gezwungen, auf physischen Kontakt weitgehend zu verzichten. Ein Großteil der Zeit, die ich mit euch verbringe, hat sich ins Digitale verlagert."]
|
|
[:p "Das fühlt sich sicher bald komplett normal an -- vorher möchte ich aber gerne irgendwas mit dem komischen Gefühl machen, das das hinterlässt."]
|
|
[:p "Ich würde mich freuen, wenn du mir dabei hilfst. Folge dazu einfach den Anweisungen. Das Ergebnis wird hoffentlich eine schöne Sammlung von Webcambildern und 3D-Modellen eurer Köpfe."]
|
|
[:button {:on-click #(dispatch [:welcome/continue])} "Cool cool, weiter bitte"]])
|
|
|
|
(defn video-snapshot [video-elem]
|
|
(let [canvas (js/document.createElement "canvas")
|
|
ctx (.getContext canvas "2d")]
|
|
(set! (.-width canvas) (.-videoWidth video-elem))
|
|
(set! (.-height canvas) (.-videoHeight video-elem))
|
|
(.drawImage ctx video-elem 0 0 (.-width canvas) (.-height canvas))
|
|
(.getImageData ctx 0 0 (.-width canvas) (.-height canvas))))
|
|
|
|
|
|
(defn running [{:keys [on-faces-detected halt?]}]
|
|
(let [result (atom {:video nil
|
|
:predictions nil})]
|
|
(fn [{:keys [on-faces-detected halt?]}]
|
|
[:div.container
|
|
[:p "Tippe auf den Button um ein Bild zu machen."]
|
|
[webcam-facemesh {:on-faces-detected (fn [ctx video predictions]
|
|
(swap! result assoc
|
|
:video video
|
|
:predictions predictions)
|
|
(on-faces-detected ctx video predictions))
|
|
:halt? halt?}]
|
|
[:button {:on-click #(dispatch [:running/snapshot (update @result :video video-snapshot)])} "Cheese"]])))
|
|
|
|
(defn app [{:keys [on-faces-detected]}]
|
|
(let [state @state
|
|
status (:status state)
|
|
halt? (some? (get-in state [:snapshots :current]))]
|
|
[:<>
|
|
[welcome-message {:hidden? (not= :welcome-message status)}]
|
|
(case status
|
|
:permission-rejected [:div "Sad :("]
|
|
:running [running {:on-faces-detected on-faces-detected
|
|
:halt? halt?}]
|
|
|
|
;; default
|
|
nil)]))
|