Last active
February 4, 2019 09:53
-
-
Save jackrusher/2c979f975925289771f3f3c1d6a37f9c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns drei | |
(:require [clojure.string :as string] | |
["three" :as three] | |
["three.meshline" :refer (MeshLine MeshLineMaterial)] | |
["three-orbitcontrols" :refer (OrbitControls)] | |
["perlin-simplex" :as Simplex] | |
["bezier-easing" :as BezierEasing] | |
["easing" :as easing] | |
[colours :refer [palettes]])) ; from Google's art palettes project | |
;; from the Hershey single line engraving font | |
(def letter-points | |
{\H '[[(0.425,0.575), (0.395,0.59), (0.395,0.59), (0.38,0.62), (0.38,0.62), (0.38,0.635), (0.38,0.635), (0.395,0.665), (0.395,0.665), (0.425,0.68), (0.425,0.68), (0.44,0.68), (0.44,0.68), (0.47,0.665), (0.47,0.665), (0.485,0.635), (0.485,0.635), (0.485,0.605), (0.485,0.605), (0.47,0.545), (0.47,0.545), (0.44,0.455), (0.44,0.455), (0.41,0.395), (0.41,0.395), (0.38,0.365), (0.38,0.365), (0.35,0.365), (0.35,0.365), (0.335,0.38), (0.335,0.38), (0.335,0.41), (0.425,0.5), (0.56,0.545), (0.56,0.545), (0.59,0.56), (0.59,0.56), (0.635,0.59), (0.635,0.59), (0.665,0.62), (0.665,0.62), (0.68,0.65), (0.68,0.65), (0.68,0.665), (0.68,0.665), (0.665,0.68), (0.665,0.68), (0.65,0.68), (0.65,0.68), (0.62,0.65), (0.62,0.65), (0.59,0.59), (0.59,0.59), (0.56,0.5), (0.56,0.5), (0.545,0.425), (0.545,0.425), (0.545,0.38), (0.545,0.38), (0.56,0.365), (0.56,0.365), (0.575,0.365), (0.575,0.365), (0.605,0.38), (0.605,0.38), (0.62,0.395), (0.62,0.395), (0.65,0.44)]] | |
\e '[[(0.455 0.395) (0.485 0.41) (0.485 0.41) (0.5 0.425) (0.5 0.425) (0.515 0.455) (0.515 0.455) (0.515 0.485) (0.515 0.485) (0.5 0.5) (0.5 0.5) (0.485 0.5) (0.485 0.5) (0.455 0.485) (0.455 0.485) (0.44 0.455) (0.44 0.455) (0.44 0.41) (0.44 0.41) (0.455 0.38) (0.455 0.38) (0.485 0.365) (0.485 0.365) (0.515 0.365) (0.515 0.365) (0.545 0.38) (0.545 0.38) (0.56 0.395) (0.56 0.395) (0.59 0.44)]] | |
\l '[[(0.455 0.44) (0.485 0.485) (0.485 0.485) (0.53 0.56) (0.53 0.56) (0.545 0.59) (0.545 0.59) (0.56 0.635) (0.56 0.635) (0.56 0.665) (0.56 0.665) (0.545 0.68) (0.545 0.68) (0.515 0.665) (0.515 0.665) (0.5 0.635) (0.5 0.635) (0.485 0.575) (0.485 0.575) (0.47 0.47) (0.47 0.47) (0.47 0.38) (0.47 0.38) (0.485 0.365) (0.485 0.365) (0.5 0.365) (0.5 0.365) (0.53 0.38) (0.53 0.38) (0.545 0.395) (0.545 0.395) (0.575 0.44)]] | |
\o '[[(0.5,0.5), (0.47,0.5), (0.47,0.5), (0.44,0.485), (0.44,0.485), (0.425,0.47), (0.425,0.47), (0.41,0.44), (0.41,0.44), (0.41,0.41), (0.41,0.41), (0.425,0.38), (0.425,0.38), (0.455,0.365), (0.455,0.365), (0.485,0.365), (0.485,0.365), (0.515,0.38), (0.515,0.38), (0.53,0.395), (0.53,0.395), (0.545,0.425), (0.545,0.425), (0.545,0.455), (0.545,0.455), (0.53,0.485), (0.53,0.485), (0.5,0.5), (0.5,0.5), (0.485,0.485), (0.485,0.485), (0.485,0.455), (0.485,0.455), (0.5,0.425), (0.5,0.425), (0.53,0.41), (0.53,0.41), (0.575,0.41), (0.575,0.41), (0.605,0.425), (0.605,0.425), (0.62,0.44)]]}) | |
(defonce renderer | |
(let [rndr (three/WebGLRenderer. (js-obj "antialias" true))] | |
(.setPixelRatio rndr (.-devicePixelRatio js/window)) | |
(.setSize rndr | |
(.-innerWidth js/window) | |
(.-innerHeight js/window)) | |
(.setClearColor rndr "hsl(60, 85%, 97%)") | |
(.appendChild (.-body js/document) | |
(.-domElement rndr)) | |
rndr)) | |
(defonce scene | |
(three/Scene.)) | |
(defonce light1 | |
(let [l (three/DirectionalLight. 0xFFFFFF 0.8)] | |
(.set (.-position l) 0 0 -2) | |
(.add scene l) | |
l)) | |
(defonce light2 | |
(let [l (three/PointLight. 0x69BB01 1)] | |
(.set (.-position l) -2 -2 0) | |
(.add scene l) | |
l)) | |
(defonce light3 | |
(let [l (three/SpotLight. 0xFFFFFF 0.7)] | |
(.set (.-position l) -1 -2 -2) | |
(.add scene l) | |
l)) | |
(def camera | |
(let [c (three/PerspectiveCamera. 45 1 0.01 100)] | |
(set! (.-aspect c) | |
(/ (.-innerWidth js/window) | |
(.-innerHeight js/window))) | |
(.set (.-position c) 1.5 1.5 -4) | |
(.lookAt c (three/Vector3.)) | |
c)) | |
(defonce mesh (atom nil)) | |
(defn set-mesh [m] | |
(when (not (nil? @mesh)) | |
(.remove scene @mesh)) | |
(reset! mesh m) | |
(.add scene m)) | |
(defonce stroke-texture (atom nil)) | |
(def colors | |
(cycle (rand-nth palettes))) | |
(def simplex (Simplex.)) | |
(defn letter-to-mesh [pts colour-idx] | |
(let [ml (MeshLine.) | |
geo (three/Geometry.) | |
scale 1.7 | |
curve (->> (reverse (first pts)) | |
(map-indexed (fn [i [x y]] | |
(three/Vector3. (* scale x) | |
(* scale y) | |
(- (* 0.01 i (.noise simplex x y)))))) | |
(clj->js) | |
(three/CatmullRomCurve3.))] | |
(.setFromPoints geo (.getPoints curve 20)) | |
(.setGeometry ml geo) | |
(three/Mesh. (.-geometry ml) | |
(MeshLineMaterial. | |
(js-obj "color" (nth colors colour-idx) | |
"useMap" true | |
"map" @stroke-texture | |
"lineWidth" 0.1 | |
"blending" three/NormalBlending | |
"transparent" true | |
"opacity" 0.8))))) | |
(def bezier (concat | |
(map (BezierEasing. 0.74 -0.01 0.21 0.99) | |
(range 0 1 (/ 1.0 24))) | |
(repeat 8 1))) ; static for 8 frames | |
(def last-tick (atom (.now js/Date))) | |
(def current-frame (atom 0)) | |
(defn render [] | |
(let [num-frames 32 | |
fps 24.0 ; goal, often not reality | |
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)) | |
(mapv (fn [m n] | |
(set! (.. m -position -x) | |
(* (nth bezier @current-frame) (+ 1.4 (- (* n 0.3))))) | |
(set! (.. m -rotation -y) | |
(* (nth bezier @current-frame) (* 0.9 Math/PI)))) | |
(.-children @mesh) | |
(range)))) | |
(.render renderer scene camera)) | |
(defn animate [] | |
(.requestAnimationFrame js/window animate) | |
(render)) | |
(defn init [] | |
(println "starting...") | |
(.load (three/TextureLoader.) | |
"stroke.png" | |
(fn [texture] | |
(set! (.-wrapS texture) three/RepeatWrapping) | |
(set! (.-wrapT texture) three/RepeatWrapping) | |
(reset! stroke-texture texture) | |
(set-mesh | |
(let [g (three/Group.)] | |
(doseq [[n letter] (map-indexed vector "Hello")] | |
(.add g (letter-to-mesh (letter-points letter) n))) | |
g)) | |
(animate)))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment