Skip to content

Instantly share code, notes, and snippets.

@jackrusher
Last active February 5, 2019 08:11
Show Gist options
  • Save jackrusher/3dc2f7da660e94b712945b37062f9f13 to your computer and use it in GitHub Desktop.
Save jackrusher/3dc2f7da660e94b712945b37062f9f13 to your computer and use it in GitHub Desktop.
(ns drei
(:require [chia.util.js-interop :as j]
["three" :as three]
["bezier-easing" :as BezierEasing]
[colours :refer [palettes]])) ; from Google's art palettes project
(defonce renderer
(doto (three/WebGLRenderer. (clj->js :antialias true))
(.setPixelRatio (.-devicePixelRatio js/window))
(.setSize (.-innerWidth js/window) (.-innerHeight js/window))
(.setClearColor "#000000")
(j/assoc-in! [:shadowMap :enabled] true)
(-> (j/get :domElement) (->> (.appendChild (.-body js/document))))))
(defonce scene
(three/Scene.))
(defonce ambient-light
(doto (three/AmbientLight. 0xffffff 0.9)
(->> (.add scene))))
(defonce directional-light
(doto (three/DirectionalLight. 0xffeeff 0.3)
(j/update! :position j/call :set 5 10 60)
(->> (.add scene))))
(def camera
(doto (three/PerspectiveCamera. 75 (/ (.-innerWidth js/window) (.-innerHeight js/window)) 0.1 1000)
(j/update! :position j/call :set 0 0 50)
(.lookAt (three/Vector3.))))
(defonce mesh (atom nil))
(defn set-mesh [m]
(when (not (nil? @mesh))
(.remove scene @mesh))
(reset! mesh m)
(.add scene m))
(def bezier
(concat
(map (BezierEasing. 0.74 -0.01 0.21 0.99)
(range 0 1 (/ 1.0 24))) ; 24 frames of motion,
(repeat 8 1))) ; then static for 8 frames
(defn twist [geo amount]
(let [quaternion (three/Quaternion.)
up-vec (three/Vector3. 0 1 0)]
(doseq [v (.-vertices geo)]
(.setFromAxisAngle quaternion up-vec (* (.-y v) amount))
(.applyQuaternion v quaternion))
(set! (.-verticesNeedUpdate geo) true))
geo)
(def last-tick (atom (.now js/Date)))
(def current-frame (atom 0))
(defn render []
(let [fps 24.0 ; goal, often not reality
num-frames 32
frame-duration (/ 1000 (float fps))
time (.now js/Date)]
(when (>= time (+ @last-tick frame-duration))
(reset! last-tick time)
(swap! current-frame #(mod (inc %) num-frames))
(when-let [m (second (.-children @mesh))]
(-> m
(j/assoc! :geometry (twist (three/BoxGeometry. 20 40 20 20 20 20)
(* 0.05 (nth bezier @current-frame))))
(j/assoc-in! [:rotation :y] (* Math/PI (nth bezier @current-frame)))))))
(.render renderer scene camera))
(defn animate []
(.requestAnimationFrame js/window animate)
(render))
(defn init []
(println "starting...")
(set-mesh (three/Group.)) ; initial empty mesh for `animate`
(.load (three/TextureLoader.)
"arroway.de_concrete-19_b005.png"
(fn [texture]
(j/assoc! texture
:wrapS three/RepeatWrapping
:wrapT three/RepeatWrapping)
(set-mesh
(doto (three/Group.)
(.add (-> (three/Mesh. (three/BoxGeometry. 1000 1000 0.25)
(three/MeshStandardMaterial. (js-obj "color" 0x222220)))
(j/assoc-in! [:position :z] -20)))
(.add (-> (three/Mesh. (three/BoxGeometry. 20 40 20 20 20 20)
(three/MeshStandardMaterial. (js-obj "color" 0xeeeeee
"map" texture
"normalMap" texture
"roughness" 0.9
"metalness" 0)))
(j/assoc! :castShadow true)))))))
(animate))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment