├── .gitignore ├── LICENSE ├── README.md ├── physics-strands ├── README.md ├── out │ ├── css │ │ └── main.css │ └── index.html ├── project.clj └── src │ └── physics_strands │ └── core.cljs ├── ws-bln-1 ├── LICENSE ├── day1 │ ├── .gitignore │ ├── out │ │ └── .empty │ ├── project.clj │ └── src │ │ └── day1 │ │ ├── core.clj │ │ └── github.clj ├── day2-reagent │ ├── .gitignore │ ├── project.clj │ ├── resources │ │ └── public │ │ │ ├── css │ │ │ └── site.css │ │ │ └── index.html │ └── src │ │ └── day2 │ │ └── core.cljs ├── day2-webgl │ ├── .classpath │ ├── .gitignore │ ├── .project │ ├── project.clj │ ├── resources │ │ └── public │ │ │ ├── css │ │ │ ├── cm-material.css │ │ │ ├── cm-solarized.css │ │ │ ├── codemirror.css │ │ │ └── site.css │ │ │ └── index.html │ └── src │ │ └── day2 │ │ └── webgl.cljs └── day3 │ ├── .classpath │ ├── .gitignore │ ├── .project │ ├── project.clj │ ├── resources │ ├── data │ │ ├── global-temp-annual.csv │ │ ├── global-temp-annual.json │ │ └── global-temp-monthly.csv │ └── public │ │ ├── css │ │ ├── cm-material.css │ │ ├── cm-solarized.css │ │ ├── codemirror.css │ │ └── site.css │ │ └── index.html │ └── src │ └── day3 │ ├── core.clj │ └── csv.clj ├── ws-bra-1 ├── LICENSE ├── README.org ├── project.clj └── src │ └── ws_bra_1 │ ├── core.clj │ └── utils.clj ├── ws-ldn-1 ├── .classpath ├── .project ├── LICENSE ├── README.md ├── assets │ ├── airports.svg │ ├── csg-mesh.stl │ ├── heatmap-example.jpg │ ├── mesh.stl │ └── webgl-example.jpg ├── project.clj ├── resources │ ├── airports.csv │ ├── day1 │ │ └── people.edn │ └── public │ │ └── index.html ├── src-cljs-day2 │ └── ws_ldn_1 │ │ └── ui │ │ └── day2 │ │ └── core.cljs ├── src-cljs-day3-1 │ └── ws_ldn_1 │ │ └── ui │ │ └── day3 │ │ └── viz.cljs ├── src-cljs-day3-2 │ └── ws_ldn_1 │ │ └── ui │ │ └── day3 │ │ └── webgl.cljs └── src │ └── ws_ldn_1 │ ├── day1 │ ├── csv.clj │ └── people.clj │ ├── day2 │ ├── mercator.clj │ └── svgmap.clj │ └── day3 │ └── threedee.clj ├── ws-ldn-10 ├── LICENSE ├── README.org ├── assets │ ├── agents.png │ ├── dejong.png │ ├── ex03.png │ ├── ex04.png │ ├── lsys-dragon.png │ ├── lsys-gasket.png │ ├── lsys-penrose.png │ ├── lsys-tree.png │ └── noise-lines.png ├── makevideo ├── project.clj ├── resources │ └── public │ │ ├── css │ │ └── style.css │ │ └── index.html └── src │ ├── clj │ ├── piksel │ │ └── core.clj │ └── ws_ldn_10 │ │ ├── ex01.clj │ │ ├── ex02.clj │ │ ├── ex03.clj │ │ ├── ex04.clj │ │ ├── ex05.clj │ │ └── ex06.clj │ └── cljs │ └── ws_ldn_10 │ └── speech.cljs ├── ws-ldn-11 ├── LICENSE ├── day1 │ ├── ex01 │ │ ├── project.clj │ │ ├── resources │ │ │ └── public │ │ │ │ ├── css │ │ │ │ └── style.css │ │ │ │ └── index.html │ │ └── src │ │ │ └── ex01 │ │ │ ├── core.cljs │ │ │ ├── shapes01.cljs │ │ │ ├── shapes02.cljs │ │ │ └── utils.cljs │ ├── ex02 │ │ ├── project.clj │ │ ├── resources │ │ │ └── public │ │ │ │ ├── css │ │ │ │ └── style.css │ │ │ │ └── index.html │ │ └── src │ │ │ └── ex02 │ │ │ ├── core.cljs │ │ │ ├── faster.cljs │ │ │ ├── fastest.cljs │ │ │ ├── naive.cljs │ │ │ ├── state.cljs │ │ │ └── utils.cljs │ └── ex03 │ │ ├── project.clj │ │ ├── resources │ │ └── public │ │ │ ├── css │ │ │ └── style.css │ │ │ ├── img │ │ │ ├── cubev.png │ │ │ ├── dione.jpg │ │ │ ├── earth.jpg │ │ │ └── moon.jpg │ │ │ ├── index.html │ │ │ ├── js │ │ │ └── stats.js │ │ │ └── suzanne.stl │ │ └── src │ │ └── ex03 │ │ ├── webgl01.cljs │ │ ├── webgl02.cljs │ │ ├── webgl03.cljs │ │ ├── webgl04.cljs │ │ ├── webgl05.cljs │ │ ├── webgl06.cljs │ │ ├── webgl07.cljs │ │ └── webgl08.cljs ├── day2 │ ├── ex04 │ │ ├── project.clj │ │ ├── resources │ │ │ └── public │ │ │ │ ├── css │ │ │ │ └── style.css │ │ │ │ ├── img │ │ │ │ ├── cubev.png │ │ │ │ ├── sjo512.png │ │ │ │ └── sjo512_2.png │ │ │ │ ├── index.html │ │ │ │ └── js │ │ │ │ └── stats.js │ │ └── src │ │ │ └── ex04 │ │ │ ├── cache.cljs │ │ │ ├── camera.cljs │ │ │ ├── config.cljs │ │ │ ├── core.cljs │ │ │ ├── game.cljs │ │ │ ├── mesh.cljs │ │ │ ├── shaders.cljs │ │ │ └── texture.cljs │ ├── ex05 │ │ ├── project.clj │ │ ├── resources │ │ │ └── public │ │ │ │ ├── index.html │ │ │ │ └── js │ │ │ │ ├── app.js │ │ │ │ ├── base.js │ │ │ │ ├── main.js │ │ │ │ └── worker.js │ │ └── src │ │ │ └── ex05 │ │ │ ├── core.cljs │ │ │ └── worker.cljs │ ├── ex05b │ │ ├── README.org │ │ ├── postprocess.js │ │ ├── project.clj │ │ ├── resources │ │ │ └── public │ │ │ │ ├── assets │ │ │ │ ├── deadpool.stl │ │ │ │ ├── suzanne.stl │ │ │ │ └── voxel.stl │ │ │ │ ├── css │ │ │ │ └── style.css │ │ │ │ ├── figwheel.html │ │ │ │ └── index.html │ │ └── src │ │ │ └── ex05b │ │ │ ├── core.cljs │ │ │ └── meshworker.cljs │ └── ex06 │ │ ├── project.clj │ │ ├── resources │ │ └── public │ │ │ ├── css │ │ │ └── style.css │ │ │ └── index.html │ │ └── src │ │ └── ex06 │ │ ├── core.cljs │ │ ├── main.cljs │ │ └── shaders.cljs └── day3 │ └── ex07 │ ├── compile.sh │ ├── externs.js │ ├── memory.png │ ├── particles.c │ ├── project.clj │ ├── resources │ └── public │ │ ├── css │ │ └── style.css │ │ ├── img │ │ └── tex32.png │ │ ├── index.html │ │ └── js │ │ └── empty │ └── src │ └── ex07 │ └── core.cljs ├── ws-ldn-2 ├── LICENSE ├── README.md ├── assets │ ├── ldn-heatmap-count.jpg │ └── ldn-heatmap.jpg ├── project.clj ├── resources │ ├── data │ │ ├── london-boroughs.nt.gz │ │ ├── london-sales-2013-2014.csv.gz │ │ ├── queries.edn │ │ └── sales-2013.edn.gz │ └── public │ │ ├── css │ │ ├── cm-material.css │ │ ├── cm-solarized.css │ │ ├── codemirror.css │ │ └── site.css │ │ └── index.html ├── src │ ├── clj │ │ └── ws_ldn_2 │ │ │ ├── async.clj │ │ │ ├── core.clj │ │ │ ├── csvconvert.clj │ │ │ └── utils.clj │ └── cljs │ │ └── ws_ldn_2 │ │ ├── components │ │ ├── dropdown.cljs │ │ └── editor.cljs │ │ ├── core.cljs │ │ ├── map_project.cljs │ │ ├── nav.cljs │ │ ├── router.cljs │ │ ├── state.cljs │ │ ├── utils.cljs │ │ └── views │ │ ├── home.cljs │ │ ├── map.cljs │ │ └── query.cljs └── workshop.org ├── ws-ldn-8 ├── day1 │ ├── ex01 │ │ ├── project.clj │ │ ├── resources │ │ │ └── public │ │ │ │ ├── css │ │ │ │ └── style.css │ │ │ │ └── index.html │ │ └── src │ │ │ └── ex01 │ │ │ ├── core.cljs │ │ │ ├── faster.cljs │ │ │ ├── fastest.cljs │ │ │ ├── naive.cljs │ │ │ └── utils.cljs │ ├── ex02 │ │ ├── project.clj │ │ ├── resources │ │ │ └── public │ │ │ │ ├── css │ │ │ │ └── style.css │ │ │ │ └── index.html │ │ └── src │ │ │ └── ex02 │ │ │ ├── core.cljs │ │ │ ├── csgtest.clj │ │ │ ├── shapes01.cljs │ │ │ ├── shapes02.cljs │ │ │ └── utils.cljs │ └── ex03 │ │ ├── project.clj │ │ ├── resources │ │ └── public │ │ │ ├── css │ │ │ └── style.css │ │ │ ├── img │ │ │ ├── cubev.png │ │ │ ├── dione.jpg │ │ │ ├── earth.jpg │ │ │ └── moon.jpg │ │ │ └── index.html │ │ └── src │ │ └── ex03 │ │ ├── webgl01.cljs │ │ ├── webgl02.cljs │ │ ├── webgl03.cljs │ │ ├── webgl04.cljs │ │ ├── webgl05.cljs │ │ ├── webgl06.cljs │ │ └── webgl07.cljs ├── day2 │ ├── ex04 │ │ ├── project.clj │ │ ├── resources │ │ │ └── public │ │ │ │ ├── css │ │ │ │ └── style.css │ │ │ │ ├── img │ │ │ │ ├── cubev.png │ │ │ │ ├── sjo512.png │ │ │ │ └── sjo512_2.png │ │ │ │ └── index.html │ │ └── src │ │ │ └── ex04 │ │ │ ├── cache.cljs │ │ │ ├── camera.cljs │ │ │ ├── config.cljs │ │ │ ├── core.cljs │ │ │ ├── game.cljs │ │ │ ├── mesh.cljs │ │ │ ├── shaders.cljs │ │ │ └── texture.cljs │ └── ex05 │ │ ├── project.clj │ │ ├── resources │ │ └── public │ │ │ └── index.html │ │ └── src │ │ └── ex05 │ │ ├── core.cljs │ │ └── worker.cljs ├── day3 │ ├── ex06 │ │ ├── project.clj │ │ ├── resources │ │ │ └── public │ │ │ │ ├── css │ │ │ │ └── style.css │ │ │ │ └── index.html │ │ └── src │ │ │ └── ex06 │ │ │ ├── core.cljs │ │ │ ├── main.cljs │ │ │ └── shaders.cljs │ └── ex07 │ │ ├── compile.sh │ │ ├── externs.js │ │ ├── particles.c │ │ ├── project.clj │ │ ├── resources │ │ └── public │ │ │ ├── css │ │ │ └── style.css │ │ │ ├── img │ │ │ └── tex32.png │ │ │ └── index.html │ │ └── src │ │ └── ex07 │ │ └── core.cljs └── docs │ ├── GLSL_ES_Specification_1.0.17.pdf │ └── WebGL1.0-Specification.pdf ├── ws-ldn-9 ├── README.md ├── day1 │ └── ex01 │ │ ├── .gitignore │ │ ├── project.clj │ │ ├── src │ │ └── ex01 │ │ │ └── core.clj │ │ └── test │ │ └── ex01 │ │ └── core_test.clj ├── day2 │ ├── ex02 │ │ ├── project.clj │ │ ├── resources │ │ │ ├── airports.csv │ │ │ └── countries.csv │ │ └── src │ │ │ └── ex02 │ │ │ ├── csv.clj │ │ │ ├── mercator.clj │ │ │ └── svgmap.clj │ └── ex03 │ │ ├── project.clj │ │ ├── resources │ │ └── public │ │ │ └── css │ │ │ └── main.css │ │ └── src │ │ └── ex03 │ │ ├── core.clj │ │ └── walker.clj └── day3 │ └── ex04 │ ├── project.clj │ ├── resources │ └── public │ │ ├── css │ │ └── style.css │ │ └── index.html │ └── src │ └── ex04 │ ├── canvas.cljs │ ├── core.cljs │ ├── home.cljs │ ├── nav.cljs │ ├── router.cljs │ ├── state.cljs │ └── users.cljs └── ws-mz-1 ├── LICENSE ├── README.org ├── project.clj ├── resources ├── airports.csv └── public │ ├── css │ └── style.css │ └── index.html ├── src-cljs └── day2 │ └── ex03 │ ├── canvas.cljs │ ├── core.cljs │ ├── home.cljs │ ├── nav.cljs │ ├── router.cljs │ ├── state.cljs │ └── users.cljs └── src ├── day1 └── ex01.clj └── day2 └── ex02 ├── csv.clj ├── mercator.clj └── svgmap.clj /.gitignore: -------------------------------------------------------------------------------- 1 | *.log 2 | js/ 3 | target/ 4 | out/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # thi.ng/demos 2 | 3 | A collection of small demos using various thi.ng libraries, organized by project: 4 | 5 | - [geom](geom/) 6 | 7 | More demos forthcoming... 8 | -------------------------------------------------------------------------------- /physics-strands/README.md: -------------------------------------------------------------------------------- 1 | # geom demos 2 | 3 | - [SVG physics strands](http://demo.thi.ng/geom/physics/strands.html) (Clojurescript online demo) 4 | 5 | ## Building from source 6 | 7 | ``` 8 | lein cljsbuild once prod 9 | open out/index.html 10 | ``` 11 | 12 | ## License 13 | 14 | Copyright © 2015 Karsten Schmidt 15 | 16 | Distributed under the [Apache Software License 2.0](http://www.apache.org/licenses/LICENSE-2.0). 17 | -------------------------------------------------------------------------------- /physics-strands/out/css/main.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | padding: 0; 4 | font-family: 'Inconsolata', Menlo, monospace; 5 | font-size: 14px; 6 | background-color: #fff; 7 | color: #333; 8 | } 9 | 10 | #app { 11 | padding: 10px; 12 | } 13 | 14 | footer { 15 | position: fixed; 16 | bottom: 0px; 17 | width: 100%; 18 | z-index: 1000; 19 | } 20 | 21 | footer div { 22 | padding: 10px; 23 | } 24 | 25 | footer a:link, 26 | footer a:visited { 27 | color: #fff; 28 | } 29 | 30 | footer .desc { 31 | background-color: #ccc; 32 | } 33 | 34 | footer .creds { 35 | background-color: #000; 36 | color: #fff; 37 | } -------------------------------------------------------------------------------- /physics-strands/out/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | geom-physics demos 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /physics-strands/project.clj: -------------------------------------------------------------------------------- 1 | (defproject physics-strands "0.1.0-SNAPSHOT" 2 | :description "physics-strands demo" 3 | :url "https://github.com/thi-ng/demos" 4 | :license {:name "Apache Software License" 5 | :url "http://www.apache.org/licenses/LICENSE-2.0"} 6 | :dependencies [[org.clojure/clojure "1.9.0"] 7 | [org.clojure/clojurescript "1.10.238"] 8 | [thi.ng/geom "1.0.0-RC3"] 9 | [thi.ng/domus "0.1.0"]] 10 | 11 | :plugins [[lein-cljsbuild "1.1.7"]] 12 | 13 | :clean-targets ^{:protect false} ["out/js"] 14 | 15 | :cljsbuild {:builds [{:id "dev" 16 | :source-paths ["src"] 17 | :compiler {:output-to "out/js/app.js" 18 | :optimizations :whitespace 19 | :pretty-print true}} 20 | {:id "prod" 21 | :source-paths ["src"] 22 | :compiler {:output-to "out/js/app.js" 23 | :optimizations :advanced 24 | :pretty-print false}}]}) 25 | -------------------------------------------------------------------------------- /ws-bln-1/day1/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /classes 3 | /checkouts 4 | pom.xml 5 | pom.xml.asc 6 | *.jar 7 | *.class 8 | /.lein-* 9 | /.nrepl-port 10 | .hgignore 11 | .hg/ 12 | -------------------------------------------------------------------------------- /ws-bln-1/day1/out/.empty: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thi-ng/demos/048cd131099a7db29be56b965c053908acad4166/ws-bln-1/day1/out/.empty -------------------------------------------------------------------------------- /ws-bln-1/day1/project.clj: -------------------------------------------------------------------------------- 1 | (defproject day1 "0.1.0-SNAPSHOT" 2 | :description "FIXME: write description" 3 | :url "http://example.com/FIXME" 4 | :license {:name "Eclipse Public License" 5 | :url "http://www.eclipse.org/legal/epl-v10.html"} 6 | :dependencies [[org.clojure/clojure "1.9.0"] 7 | [org.clojure/clojurescript "1.10.238"] 8 | [irresponsible/tentacles "0.6.2"] 9 | [thi.ng/geom "1.0.0-RC3"]]) 10 | -------------------------------------------------------------------------------- /ws-bln-1/day1/src/day1/core.clj: -------------------------------------------------------------------------------- 1 | (ns day1.core 2 | (:require 3 | [hiccup.core :refer [html]] 4 | [hiccup.page :refer [html5]] 5 | [thi.ng.geom.svg.core :as svg])) 6 | 7 | (defn export-svg 8 | [& body] 9 | (println (count body) "elements") 10 | (->> body 11 | (svg/svg {:width 200 :height 200}) 12 | (svg/serialize) 13 | (spit "out/berlin.svg"))) 14 | 15 | (export-svg 16 | (svg/circle [100 100] 100 {:fill "red"}) 17 | (svg/circle [100 100] 50 {:fill "yellow"})) -------------------------------------------------------------------------------- /ws-bln-1/day2-reagent/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /classes 3 | /checkouts 4 | pom.xml 5 | pom.xml.asc 6 | *.jar 7 | *.class 8 | /.lein-* 9 | /.nrepl-port 10 | .hgignore 11 | .hg/ 12 | /bin/ 13 | -------------------------------------------------------------------------------- /ws-bln-1/day2-reagent/project.clj: -------------------------------------------------------------------------------- 1 | (defproject thi.ng/ws-bln-1 "0.1.0-SNAPSHOT" 2 | :description "thi.ng x Studio NAND Berlin workshop #1" 3 | :url "http://thi.ng/ws-bln-1" 4 | :license {:name "Apache Software License 2.0" 5 | :url "http://www.apache.org/licenses/LICENSE-2.0"} 6 | :dependencies [[org.clojure/clojure "1.9.0"] 7 | [org.clojure/clojurescript "1.10.238"] 8 | ; [org.clojure/core.async "0.4.474"] 9 | [thi.ng/geom "1.0.0-RC3"] 10 | [reagent "0.5.1"] 11 | [cljs-log "0.2.2"]] 12 | 13 | :plugins [[lein-figwheel "0.5.16"] 14 | [lein-cljsbuild "1.1.7"] 15 | [lein-environ "1.0.0"]] 16 | 17 | :clean-targets ^{:protect false} ["target" "resources/public/js"] 18 | 19 | :profiles {:prod {:env {:log-level 4}}} 20 | 21 | :cljsbuild { 22 | :builds [ { :id "dev" 23 | :source-paths ["src"] 24 | :figwheel true 25 | :compiler { :main "day2.core" 26 | :asset-path "js/out" 27 | :output-to "resources/public/js/app.js" 28 | :output-dir "resources/public/js/out" } } ] 29 | } 30 | 31 | :figwheel {:http-server-root "public" ;; default and assumes "resources" 32 | :server-port 3449 ;; default 33 | :css-dirs ["resources/public/css"] ;; watch and update CSS 34 | }) 35 | -------------------------------------------------------------------------------- /ws-bln-1/day2-reagent/resources/public/css/site.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thi-ng/demos/048cd131099a7db29be56b965c053908acad4166/ws-bln-1/day2-reagent/resources/public/css/site.css -------------------------------------------------------------------------------- /ws-bln-1/day2-reagent/resources/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /ws-bln-1/day2-reagent/src/day2/core.cljs: -------------------------------------------------------------------------------- 1 | (ns day2.core 2 | (:require-macros 3 | [reagent.ratom :refer [reaction]] 4 | [cljs-log.core :refer [debug info warn]]) 5 | (:require 6 | [reagent.core :as reagent] 7 | [thi.ng.color.core :as col] 8 | [thi.ng.geom.vector :as v] 9 | [thi.ng.geom.svg.core :as svg])) 10 | 11 | (defonce app 12 | (reagent/atom 13 | {:color [1 0 0]})) 14 | 15 | (defn input 16 | [] 17 | [:input 18 | {:type "text" 19 | :on-change (fn [e] 20 | (swap! app assoc :name 21 | (-> e .-target .-value)))}]) 22 | 23 | (defn triangle 24 | [a b c col] 25 | (svg/polygon [a b c] {:fill (col/as-hsva (col/rgba (:color @app))) :stroke "black"})) 26 | 27 | (defn ^:export app-component 28 | [] 29 | (let [name (reaction (:name @app)) 30 | mpos (reaction (v/vec2 (:mouseX @app) (:mouseY @app)))] 31 | (fn [] 32 | [:div 33 | [:h1 "hello " @name] 34 | [:div [input]] 35 | [svg/svg 36 | {:width 600 37 | :height 600 38 | :on-mouse-move 39 | (fn [e] 40 | (swap! app 41 | (fn [state] 42 | (-> state 43 | (assoc-in [:color 0] (* (.-clientX e) 0.002)) 44 | (assoc-in [:color 2] (* (.-clientY e) 0.002)))))) 45 | } 46 | ^{:key "t1"} [triangle [0 0] [300 0] @mpos "red"] 47 | ]]))) 48 | 49 | (defn init-listeners 50 | [] 51 | (.addEventListener js/window "mousemove" 52 | (fn [e] 53 | (swap! app assoc 54 | :mouseX (-> e .-clientX) 55 | :mouseY (-> e .-clientY)) 56 | (debug (select-keys @app [:mouseX :mouseY])))) 57 | (swap! app assoc :inited true) 58 | (debug :inited)) 59 | 60 | (defn main 61 | [] 62 | (when (not (:inited @app)) 63 | (init-listeners)) 64 | (reagent/render-component 65 | [app-component] 66 | (.-body js/document))) 67 | 68 | (main) -------------------------------------------------------------------------------- /ws-bln-1/day2-webgl/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /ws-bln-1/day2-webgl/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /classes 3 | /checkouts 4 | pom.xml 5 | pom.xml.asc 6 | *.jar 7 | *.class 8 | /.lein-* 9 | /.nrepl-port 10 | .hgignore 11 | .hg/ 12 | /bin/ 13 | -------------------------------------------------------------------------------- /ws-bln-1/day2-webgl/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | day2-webgl 4 | 5 | 6 | 7 | 8 | 9 | ccw.builder 10 | 11 | 12 | 13 | 14 | ccw.leiningen.builder 15 | 16 | 17 | 18 | 19 | org.eclipse.jdt.core.javabuilder 20 | 21 | 22 | 23 | 24 | 25 | org.eclipse.jdt.core.javanature 26 | ccw.leiningen.nature 27 | ccw.nature 28 | 29 | 30 | -------------------------------------------------------------------------------- /ws-bln-1/day2-webgl/resources/public/css/cm-material.css: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Name: material 4 | Author: Michael Kaminsky (http://github.com/mkaminsky11) 5 | 6 | Original material color scheme by Mattia Astorino (https://github.com/equinusocio/material-theme) 7 | 8 | */ 9 | 10 | .cm-s-material { 11 | background-color: #263238; 12 | color: rgba(233, 237, 237, 1); 13 | } 14 | .cm-s-material .CodeMirror-gutters { 15 | background: #263238; 16 | color: rgb(83,127,126); 17 | border: none; 18 | } 19 | .cm-s-material .CodeMirror-guttermarker, .cm-s-material .CodeMirror-guttermarker-subtle, .cm-s-material .CodeMirror-linenumber { color: rgb(83,127,126); } 20 | .cm-s-material .CodeMirror-cursor { border-left: 1px solid #f8f8f0; } 21 | .cm-s-material div.CodeMirror-selected { background: rgba(255, 255, 255, 0.15); } 22 | .cm-s-material.CodeMirror-focused div.CodeMirror-selected { background: rgba(255, 255, 255, 0.10); } 23 | .cm-s-material .CodeMirror-line::selection, .cm-s-material .CodeMirror-line > span::selection, .cm-s-material .CodeMirror-line > span > span::selection { background: rgba(255, 255, 255, 0.10); } 24 | .cm-s-material .CodeMirror-line::-moz-selection, .cm-s-material .CodeMirror-line > span::-moz-selection, .cm-s-material .CodeMirror-line > span > span::-moz-selection { background: rgba(255, 255, 255, 0.10); } 25 | 26 | .cm-s-material .CodeMirror-activeline-background { background: rgba(0, 0, 0, 0); } 27 | .cm-s-material .cm-keyword { color: rgba(199, 146, 234, 1); } 28 | .cm-s-material .cm-operator { color: rgba(233, 237, 237, 1); } 29 | .cm-s-material .cm-variable-2 { color: #80CBC4; } 30 | .cm-s-material .cm-variable-3 { color: #82B1FF; } 31 | .cm-s-material .cm-builtin { color: #DECB6B; } 32 | .cm-s-material .cm-atom { color: #F77669; } 33 | .cm-s-material .cm-number { color: #F77669; } 34 | .cm-s-material .cm-def { color: rgba(233, 237, 237, 1); } 35 | .cm-s-material .cm-error { 36 | color: rgba(255, 255, 255, 1.0); 37 | background-color: #EC5F67; 38 | } 39 | .cm-s-material .cm-string { color: #C3E88D; } 40 | .cm-s-material .cm-string-2 { color: #80CBC4; } 41 | .cm-s-material .cm-comment { color: #546E7A; } 42 | .cm-s-material .cm-variable { color: #82B1FF; } 43 | .cm-s-material .cm-tag { color: #80CBC4; } 44 | .cm-s-material .cm-meta { color: #80CBC4; } 45 | .cm-s-material .cm-attribute { color: #FFCB6B; } 46 | .cm-s-material .cm-property { color: #80CBAE; } 47 | .cm-s-material .cm-qualifier { color: #DECB6B; } 48 | .cm-s-material .cm-variable-3 { color: #DECB6B; } 49 | .cm-s-material .cm-tag { color: rgba(255, 83, 112, 1); } 50 | .cm-s-material .CodeMirror-matchingbracket { 51 | text-decoration: underline; 52 | color: white !important; 53 | } 54 | -------------------------------------------------------------------------------- /ws-bln-1/day2-webgl/resources/public/css/site.css: -------------------------------------------------------------------------------- 1 | .CodeMirror { 2 | font-family: "Inconsolata",Menlo,monospace !important; 3 | margin-bottom: 1em; 4 | height: 400px; 5 | } 6 | 7 | .fullwidth { 8 | max-width: 100%; 9 | } 10 | 11 | .form-align { 12 | margin-top: 24px; 13 | } 14 | 15 | table.query-results { 16 | font-size: 11px; 17 | } -------------------------------------------------------------------------------- /ws-bln-1/day2-webgl/resources/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /ws-bln-1/day3/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /ws-bln-1/day3/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /classes 3 | /checkouts 4 | pom.xml 5 | pom.xml.asc 6 | *.jar 7 | *.class 8 | /.lein-* 9 | /.nrepl-port 10 | .hgignore 11 | .hg/ 12 | /bin/ 13 | -------------------------------------------------------------------------------- /ws-bln-1/day3/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | day3 4 | 5 | 6 | 7 | 8 | 9 | ccw.builder 10 | 11 | 12 | 13 | 14 | ccw.leiningen.builder 15 | 16 | 17 | 18 | 19 | org.eclipse.jdt.core.javabuilder 20 | 21 | 22 | 23 | 24 | 25 | org.eclipse.jdt.core.javanature 26 | ccw.leiningen.nature 27 | ccw.nature 28 | 29 | 30 | -------------------------------------------------------------------------------- /ws-bln-1/day3/resources/public/css/cm-material.css: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Name: material 4 | Author: Michael Kaminsky (http://github.com/mkaminsky11) 5 | 6 | Original material color scheme by Mattia Astorino (https://github.com/equinusocio/material-theme) 7 | 8 | */ 9 | 10 | .cm-s-material { 11 | background-color: #263238; 12 | color: rgba(233, 237, 237, 1); 13 | } 14 | .cm-s-material .CodeMirror-gutters { 15 | background: #263238; 16 | color: rgb(83,127,126); 17 | border: none; 18 | } 19 | .cm-s-material .CodeMirror-guttermarker, .cm-s-material .CodeMirror-guttermarker-subtle, .cm-s-material .CodeMirror-linenumber { color: rgb(83,127,126); } 20 | .cm-s-material .CodeMirror-cursor { border-left: 1px solid #f8f8f0; } 21 | .cm-s-material div.CodeMirror-selected { background: rgba(255, 255, 255, 0.15); } 22 | .cm-s-material.CodeMirror-focused div.CodeMirror-selected { background: rgba(255, 255, 255, 0.10); } 23 | .cm-s-material .CodeMirror-line::selection, .cm-s-material .CodeMirror-line > span::selection, .cm-s-material .CodeMirror-line > span > span::selection { background: rgba(255, 255, 255, 0.10); } 24 | .cm-s-material .CodeMirror-line::-moz-selection, .cm-s-material .CodeMirror-line > span::-moz-selection, .cm-s-material .CodeMirror-line > span > span::-moz-selection { background: rgba(255, 255, 255, 0.10); } 25 | 26 | .cm-s-material .CodeMirror-activeline-background { background: rgba(0, 0, 0, 0); } 27 | .cm-s-material .cm-keyword { color: rgba(199, 146, 234, 1); } 28 | .cm-s-material .cm-operator { color: rgba(233, 237, 237, 1); } 29 | .cm-s-material .cm-variable-2 { color: #80CBC4; } 30 | .cm-s-material .cm-variable-3 { color: #82B1FF; } 31 | .cm-s-material .cm-builtin { color: #DECB6B; } 32 | .cm-s-material .cm-atom { color: #F77669; } 33 | .cm-s-material .cm-number { color: #F77669; } 34 | .cm-s-material .cm-def { color: rgba(233, 237, 237, 1); } 35 | .cm-s-material .cm-error { 36 | color: rgba(255, 255, 255, 1.0); 37 | background-color: #EC5F67; 38 | } 39 | .cm-s-material .cm-string { color: #C3E88D; } 40 | .cm-s-material .cm-string-2 { color: #80CBC4; } 41 | .cm-s-material .cm-comment { color: #546E7A; } 42 | .cm-s-material .cm-variable { color: #82B1FF; } 43 | .cm-s-material .cm-tag { color: #80CBC4; } 44 | .cm-s-material .cm-meta { color: #80CBC4; } 45 | .cm-s-material .cm-attribute { color: #FFCB6B; } 46 | .cm-s-material .cm-property { color: #80CBAE; } 47 | .cm-s-material .cm-qualifier { color: #DECB6B; } 48 | .cm-s-material .cm-variable-3 { color: #DECB6B; } 49 | .cm-s-material .cm-tag { color: rgba(255, 83, 112, 1); } 50 | .cm-s-material .CodeMirror-matchingbracket { 51 | text-decoration: underline; 52 | color: white !important; 53 | } 54 | -------------------------------------------------------------------------------- /ws-bln-1/day3/resources/public/css/site.css: -------------------------------------------------------------------------------- 1 | .CodeMirror { 2 | font-family: "Inconsolata",Menlo,monospace !important; 3 | margin-bottom: 1em; 4 | height: 400px; 5 | } 6 | 7 | .fullwidth { 8 | max-width: 100%; 9 | } 10 | 11 | .form-align { 12 | margin-top: 24px; 13 | } 14 | 15 | table.query-results { 16 | font-size: 11px; 17 | } -------------------------------------------------------------------------------- /ws-bln-1/day3/resources/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /ws-bln-1/day3/src/day3/core.clj: -------------------------------------------------------------------------------- 1 | (ns day3.core 2 | (:require 3 | [day3.csv :as csv])) 4 | 5 | -------------------------------------------------------------------------------- /ws-bra-1/README.org: -------------------------------------------------------------------------------- 1 | * Sensorium Digital Fabrication workshop 2 | 3 | ** Overview 4 | 5 | ** Tools for today 6 | *** Git client 7 | 8 | http://sourcetreeapp.com 9 | 10 | *** Java 11 | 12 | http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 13 | 14 | *** Clojure 15 | 16 | http://clojure.org 17 | 18 | *** Leiningen 19 | 20 | http://leiningen.org 21 | 22 | *** Inkscape 23 | 24 | http://inkscape.org 25 | 26 | *** XQuartz 27 | 28 | http://xquartz.org 29 | 30 | ** thi.ng libraries 31 | *** Overview 32 | 33 | - 23+ projects 34 | - In constant development since 2011 35 | - Successor to toxiclibs.org 36 | 37 | - Today only use http://thi.ng/geom 38 | 39 | 40 | * Running the code 41 | 42 | #+BEGIN_SRC shell 43 | cd ws-bra-1 44 | lein repl 45 | #+END_SRC 46 | 47 | #+BEGIN_SRC clojure 48 | (require 'ws-bra-1.core :reload) 49 | (in-ns 'ws-bra-1.core) 50 | (ring-cluster "rings.svg" [100 200 75 80]) 51 | #+END_SRC 52 | -------------------------------------------------------------------------------- /ws-bra-1/project.clj: -------------------------------------------------------------------------------- 1 | (defproject ws-bra-1 "0.1.0-SNAPSHOT" 2 | :description "Digital fabrication workshop @ Sensorium, Bratislava 2016" 3 | :url "http://thi.ng/ws-bra-1" 4 | :license {:name "Apache Software License" 5 | :url "http://www.apache.org/licenses/LICENSE-2.0"} 6 | :dependencies [[org.clojure/clojure "1.8.0"] 7 | [thi.ng/geom "0.0.1151-SNAPSHOT"]]) 8 | -------------------------------------------------------------------------------- /ws-bra-1/src/ws_bra_1/utils.clj: -------------------------------------------------------------------------------- 1 | (ns ws-bra-1.utils 2 | (:require 3 | [thi.ng.math.core :as m] 4 | [thi.ng.geom.core :as g] 5 | [thi.ng.geom.vector :as v :refer [vec2 vec3]] 6 | [thi.ng.geom.matrix :as mat] 7 | [thi.ng.geom.circle :refer [circle]] 8 | [thi.ng.geom.polygon :refer [polygon2]] 9 | [thi.ng.geom.line :as l] 10 | [thi.ng.geom.bezier :as b] 11 | [thi.ng.geom.path :as path] 12 | [thi.ng.dstruct.core :as d])) 13 | 14 | (defn smooth-polygon 15 | ([poly base amount] 16 | (let [c (g/centroid poly) 17 | points (g/vertices poly) 18 | points (d/wrap-seq points [(last points)] [(first points)])] 19 | (->> points 20 | (partition 3 1) 21 | (map 22 | (fn [[p q r]] 23 | (-> (m/- p q) 24 | (m/+ (m/- r q)) 25 | (m/+ (m/* (m/- q c) base)) 26 | (m/* amount) 27 | (m/+ q)))) 28 | (polygon2)))) 29 | ([poly base amount iter] 30 | (d/iterate-n iter #(smooth-polygon % base amount) poly))) 31 | 32 | (defn poly-as-linestrip 33 | [poly] 34 | (let [verts (g/vertices poly)] 35 | (l/linestrip2 (conj verts (first verts))))) 36 | 37 | (defn shape-vertices-as-circles 38 | [shape r] (map (fn [v] (circle v r)) (g/vertices shape))) 39 | -------------------------------------------------------------------------------- /ws-ldn-1/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /ws-ldn-1/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | ws-ldn-1 4 | 5 | 6 | 7 | 8 | 9 | ccw.builder 10 | 11 | 12 | 13 | 14 | ccw.leiningen.builder 15 | 16 | 17 | 18 | 19 | org.eclipse.jdt.core.javabuilder 20 | 21 | 22 | 23 | 24 | 25 | org.eclipse.jdt.core.javanature 26 | ccw.leiningen.nature 27 | ccw.nature 28 | 29 | 30 | -------------------------------------------------------------------------------- /ws-ldn-1/README.md: -------------------------------------------------------------------------------- 1 | # Clojure/Clojurescript workshop 2 | 3 | (WS-LDN-1) 4 | 5 | This repo contains a subset of commented examples created during the workshop. 6 | 7 | ## Day 1 namespaces 8 | 9 | - [day1.csv](src/ws_ldn_1/day1/csv.clj) - CSV parsing & column extraction 10 | - [day1.people](src/ws_ldn_1/day1/people.clj) - EDN parsing & transformation 11 | 12 | Airport dataset from: http://ourairports.com/data/ 13 | 14 | ## Day 2 namespaces 15 | 16 | ### Clojure SVG airport visualization 17 | 18 | - [day2.mercator](src/ws_ldn_1/day2/mercator.clj) - Mercator projection 19 | - [day2.svgmap](src/ws_ldn_1/day2/svgmap.clj) - SVG mercator map 20 | 21 | ![47k airports](http://workshop.thi.ng/ws-ldn-1/airports.svg) 22 | 23 | 47k airports mapped, data from [ourairports.com](http://ourairports.com/data/) 24 | 25 | Github doesn't display the map background image, see original viz [here](http://workshop.thi.ng/ws-ldn-1/airports.svg)... 26 | 27 | ### Clojurescript, Reagent / React example 28 | 29 | - [ui.day2.core](src-cljs-day2/ws_ldn_1/ui/day2/core.cljs) - basic [Reagent](http://reagent-project.github.io) concepts & undo demo 30 | 31 | To launch: 32 | 33 | ```bash 34 | lein figwheel day2 35 | ``` 36 | 37 | ## Day 3 namespaces 38 | 39 | ### Clojure 40 | 41 | - [ui.day3.threedee](src/ws_ldn_1/day3/threedee.clj) - thi.ng/geom mesh examples 42 | 43 | Exported meshes are located in [assets](assets/) folder. 44 | 45 | ### Clojurescript 46 | 47 | - [ui.day3.core](src-cljs-day3-1/ws_ldn_1/ui/day3/viz.cljs) - thi.ng/geom vizualization examples (using Reagent) 48 | 49 | To launch: 50 | 51 | ```bash 52 | lein figwheel day3-viz 53 | ``` 54 | 55 | ![heatmap example](assets/heatmap-example.jpg) 56 | 57 | [Live demo](http://demo.thi.ng/ws-ldn-1/geom-viz/index.html) 58 | 59 | - [ui.day3.webgl](src-cljs-day3-2/ws_ldn_1/ui/day3/webgl.cljs) - thi.ng/geom WebGL & in-browser STL mesh export example 60 | 61 | To launch: 62 | 63 | ```bash 64 | lein figwheel day3-webgl 65 | ``` 66 | 67 | ![webgl example](assets/webgl-example.jpg) 68 | 69 | [Live demo](http://demo.thi.ng/ws-ldn-1/webgl/index.html) 70 | 71 | ## CLJS build w/ advanced optimizations 72 | 73 | To build the CLJS examples with advanced optimizations, uncomment the lines with `:optimizations` & `:pretty-print` from the `project.clj` file for the relevant build profile(s). Then compile the source with: 74 | 75 | ```bash 76 | lein do clean, cljsbuild once 77 | ``` 78 | 79 | ## License 80 | 81 | Copyright © 2015 Karsten Schmidt 82 | 83 | Distributed under the Apache Software License either version 1.0 or (at 84 | your option) any later version. 85 | -------------------------------------------------------------------------------- /ws-ldn-1/assets/csg-mesh.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thi-ng/demos/048cd131099a7db29be56b965c053908acad4166/ws-ldn-1/assets/csg-mesh.stl -------------------------------------------------------------------------------- /ws-ldn-1/assets/heatmap-example.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thi-ng/demos/048cd131099a7db29be56b965c053908acad4166/ws-ldn-1/assets/heatmap-example.jpg -------------------------------------------------------------------------------- /ws-ldn-1/assets/mesh.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thi-ng/demos/048cd131099a7db29be56b965c053908acad4166/ws-ldn-1/assets/mesh.stl -------------------------------------------------------------------------------- /ws-ldn-1/assets/webgl-example.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thi-ng/demos/048cd131099a7db29be56b965c053908acad4166/ws-ldn-1/assets/webgl-example.jpg -------------------------------------------------------------------------------- /ws-ldn-1/project.clj: -------------------------------------------------------------------------------- 1 | (defproject thi.ng/ws-ldn-1 "0.1.0-SNAPSHOT" 2 | :description "thi.ng workshop #1" 3 | :url "http://thi.ng" 4 | :license {:name "Apache Software License 2.0" 5 | :url "http://www.apache.org/licenses/LICENSE-2.0"} 6 | :dependencies [[org.clojure/clojure "1.7.0"] 7 | [org.clojure/clojurescript "1.7.170"] 8 | [org.clojure/data.csv "0.1.3"] 9 | [reagent "0.5.1"] 10 | [thi.ng/geom "0.0.908"] 11 | [thi.ng/strf "0.2.1"]] 12 | 13 | :plugins [[lein-figwheel "0.5.0-SNAPSHOT"] 14 | [lein-cljsbuild "1.1.1"]] 15 | 16 | :clean-targets ^{:protect false} ["resources/public/js" "target"] 17 | 18 | :cljsbuild {:builds [{:id "day2" 19 | :source-paths ["src-cljs-day2"] 20 | :figwheel true 21 | :compiler {:main "ws-ldn-1.ui.day2.core" 22 | :asset-path "js/day2" 23 | ;;:optimizations :advanced 24 | ;;:pretty-print false 25 | :output-to "resources/public/js/app.js" 26 | :output-dir "resources/public/js/day2"}} 27 | {:id "day3-viz" 28 | :source-paths ["src-cljs-day3-1"] 29 | :figwheel true 30 | :compiler {:main "ws-ldn-1.ui.day3.viz" 31 | :asset-path "js/day3-viz" 32 | ;;:optimizations :advanced 33 | ;;:pretty-print false 34 | :output-to "resources/public/js/app.js" 35 | :output-dir "resources/public/js/day3-viz"}} 36 | {:id "day3-webgl" 37 | :source-paths ["src-cljs-day3-2"] 38 | :figwheel true 39 | :compiler {:main "ws-ldn-1.ui.day3.webgl" 40 | :asset-path "js/day3-webgl" 41 | ;;:optimizations :advanced 42 | ;;:pretty-print false 43 | :output-to "resources/public/js/app.js" 44 | :output-dir "resources/public/js/day3-webgl"}}]}) -------------------------------------------------------------------------------- /ws-ldn-1/resources/day1/people.edn: -------------------------------------------------------------------------------- 1 | [["ks" ["js" "clj"] "London"] 2 | ["ns" ["js" "clj"] "London"] 3 | ["dh" ["js" "clj"] "London"] 4 | ["pg" ["js" "clj"] "Sydney"] 5 | ["ra" ["js" "clj"] "Boston"] 6 | ["di" ["js" "clj"] "St.Albans"] 7 | ["dg" ["js" "clj"] "Warsaw"] 8 | ["ms" ["js" "clj"] "Bratislava"]] -------------------------------------------------------------------------------- /ws-ldn-1/resources/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |

Loading...

7 |
8 | 9 |
10 | 11 | 12 | -------------------------------------------------------------------------------- /ws-ldn-1/src/ws_ldn_1/day1/people.clj: -------------------------------------------------------------------------------- 1 | (ns ws-ldn-1.day1.people 2 | "Basic I/O using EDN format and data transformation example 3 | with thread-last macro (->>)." 4 | (:require 5 | [clojure.java.io :as io] ;; require namespaces with alias 6 | [clojure.edn :as edn] 7 | [clojure.pprint :refer [pprint]])) ;; import ns & allow referring to pprint directly 8 | 9 | ;; load people specs from resource file 10 | 11 | (def people-raw 12 | (->> "day1/people.edn" 13 | (io/resource) ;; convert to resource URI 14 | (slurp) ;; read as string 15 | (edn/read-string))) ;; parse EDN format 16 | 17 | ;; or alternatively directly parse from input stream 18 | ;; better when loading larger data 19 | 20 | (def people-raw 21 | (->> "day1/people.edn" 22 | (io/resource) 23 | (io/reader) ;; create java.io.Reader instance from URI 24 | (java.io.PushbackReader.) ;; wrap in PushbackReader 25 | (edn/read))) ;; read from stream 26 | 27 | (defn person-map 28 | "Converts single person spec (vector) into hash-map. 29 | Uses vector destructuring for function arguments" 30 | [[name langs city]] 31 | {:name name :langs (set langs) :city city}) 32 | 33 | ;; transform vector of raw specs into vector of person maps 34 | 35 | (def people (mapv person-map people-raw)) 36 | 37 | ;; alternatively use zipmap to achieve same effect 38 | ;; without need for person-map fn 39 | ;; (requires extra step to convert :langs into a set) 40 | 41 | (def people 42 | (->> people-raw 43 | (map (fn [p] (zipmap [:name :langs :city] p))) ;; combine key & val seq into hash-map 44 | (map (fn [p] (update p :langs set))) ;; apply (set) fn to :langs value for each item 45 | (vec))) ;; convert final lazy seq to vector 46 | 47 | ;; instead of (vec) we could also have used (mapv ...) for the previous step... 48 | ;; http://conj.io/store/v1/org.clojure/clojure/1.7.0/clj/clojure.core/mapv 49 | 50 | ;; use Clojure's pretty printer to show any nested data 51 | 52 | (pprint people) 53 | 54 | ;; write converted data to file in project root dir 55 | 56 | (spit "people-converted.edn" people) -------------------------------------------------------------------------------- /ws-ldn-1/src/ws_ldn_1/day2/mercator.clj: -------------------------------------------------------------------------------- 1 | (ns ws-ldn-1.day2.mercator 2 | (:require 3 | [thi.ng.geom.core :as g] 4 | [thi.ng.geom.core.vector :refer [vec2 vec3]] 5 | [thi.ng.math.core :as m])) 6 | 7 | (def ^:const EARTH_RADIUS_MINOR 6356752.3142) 8 | (def ^:const EARTH_RADIUS_MAJOR 6378137.0) 9 | 10 | (defn mercator 11 | "Takes a longitude and latitude coordinate and returns mapped point." 12 | [lon lat] 13 | (let [lat (m/clamp lat -89.5 89.5) 14 | rt (/ EARTH_RADIUS_MINOR EARTH_RADIUS_MAJOR) 15 | es (- 1.0 rt) 16 | ec (Math/sqrt es) 17 | phi (m/radians lat) 18 | sinphi (Math/sin phi) 19 | con (* ec sinphi) 20 | con (Math/pow (/ (- 1.0 con) (+ 1.0 con)) (* ec 0.5)) 21 | ts (/ (Math/tan (/ (- m/HALF_PI phi) 2)) con)] 22 | (vec2 23 | (* EARTH_RADIUS_MAJOR (m/radians lon)) 24 | (* (- EARTH_RADIUS_MAJOR) (Math/log ts))))) 25 | 26 | (defn lat-log 27 | [lat] (Math/log (Math/tan (+ (/ (m/radians lat) 2) m/QUARTER_PI)))) 28 | 29 | (defn mercator-in-rect 30 | [[lon lat] [left right top bottom] w h] 31 | (let [lon (m/radians lon) 32 | left (m/radians left) 33 | [lat top bottom] (map lat-log [lat top bottom])] 34 | (vec2 35 | (* w (/ (- lon left) (- (m/radians right) left))) 36 | (* h (/ (- lat top) (- bottom top)))))) -------------------------------------------------------------------------------- /ws-ldn-1/src/ws_ldn_1/day2/svgmap.clj: -------------------------------------------------------------------------------- 1 | (ns ws-ldn-1.day2.svgmap 2 | (:require 3 | [thi.ng.geom.core :as g] 4 | [thi.ng.geom.svg.core :as svg] 5 | [ws-ldn-1.day2.mercator :as proj] 6 | [ws-ldn-1.day1.csv :as data])) 7 | 8 | ;; map image size 9 | (def map-width 1029) 10 | (def map-height 873) 11 | 12 | (def latlon-bounds 13 | "Angular bounds for mercator map projection" 14 | [-180 180 82 -82]) 15 | 16 | (defn svg-image 17 | "Produces an SVG bitmap image element in hiccup format" 18 | [x y w h src] 19 | [:image {:x x :y y :width w :height h "xlink:href" src}]) 20 | 21 | (defn map-airports 22 | "Takes a coll of airports, maps their location using mercator projection 23 | and returns lazyseq of SVG circles (as hiccup)" 24 | [color w h r airports] 25 | (svg/group 26 | {:fill color} 27 | (->> airports 28 | (map #(proj/mercator-in-rect (:lonlat-point %) latlon-bounds w h)) 29 | (map #(svg/circle % r))))) 30 | 31 | (defn airport-map 32 | "Takes an output filepath, image width, height and arbitrary number of SVG elements. 33 | Exports SVG map w/ Wikipedia earth map as background. Returns nil" 34 | [path w h & body] 35 | (->> (svg/svg 36 | {:width w :height h} 37 | (svg-image 0 0 w h "https://upload.wikimedia.org/wikipedia/commons/f/f4/Mercator_projection_SW.jpg") 38 | body) 39 | (svg/serialize) 40 | (spit path))) 41 | 42 | (airport-map 43 | "airports.svg" map-width map-height 44 | (map-airports "rgba(0,255,255,0.5)" map-width map-height 0.8 (filter (complement :iata_code) data/airports)) 45 | (map-airports "rgba(255,0,255,0.5)" map-width map-height 0.8 (filter :iata_code data/airports))) -------------------------------------------------------------------------------- /ws-ldn-1/src/ws_ldn_1/day3/threedee.clj: -------------------------------------------------------------------------------- 1 | (ns ws-ldn-1.threedee 2 | "3D mesh examples & export" 3 | (:require 4 | [thi.ng.geom.core :as g] 5 | [thi.ng.geom.core.vector :as v] 6 | [thi.ng.geom.circle :as c] 7 | [thi.ng.geom.polygon :as poly] 8 | [thi.ng.geom.sphere :as s] 9 | [thi.ng.geom.gmesh :as gm] 10 | [thi.ng.geom.mesh.io :as mio] 11 | [thi.ng.geom.mesh.subdivision :as sd] 12 | [thi.ng.geom.mesh.csg :as csg] 13 | [clojure.java.io :as io])) 14 | 15 | (defn save-stl 16 | "Takes file path and mesh instance, saves mesh as STL." 17 | [path mesh] 18 | (with-open [out (io/output-stream path)] 19 | (mio/write-stl 20 | (mio/wrapped-output-stream out) 21 | (g/tessellate mesh)))) 22 | 23 | (def mesh 24 | "Generates 3x subdivided, hexagon cylinder mesh from 2D circle" 25 | (-> (c/circle 10) 26 | (g/extrude {:depth 20 :res 6 :wall 2 :mesh (gm/gmesh)}) 27 | (sd/catmull-clark) 28 | (sd/catmull-clark) 29 | (sd/catmull-clark))) 30 | 31 | (def csg-mesh 32 | "Generates mesh from 3 intersecting spheres, uses CSG module 33 | to subtract the outer ones from the center sphere." 34 | (let [s (g/as-mesh (s/sphere 10) {:res 20}) 35 | a (csg/mesh->csg s) 36 | b (csg/mesh->csg (g/translate s (v/vec3 -10 0 0))) 37 | c (csg/mesh->csg (g/translate s (v/vec3 10 0 0)))] 38 | (csg/csg->mesh 39 | (reduce csg/subtract [a b c])))) 40 | 41 | (save-stl "mesh.stl" mesh) 42 | (save-stl "csg-mesh.stl" csg-mesh) 43 | -------------------------------------------------------------------------------- /ws-ldn-10/README.org: -------------------------------------------------------------------------------- 1 | * Workshop: Generative design w/ Clojure & thi.ng 2 | 3 | ** Examples 4 | 5 | *** Namespace: ws-ldn-10.ex01 6 | 7 | - Repetition & parameterization of basic processes 8 | - Coordinate systems (cartesian vs polar) 9 | - Custom shape generation 10 | - Shape sampling 11 | 12 | | [[./assets/ex03.png]] | [[./assets/ex04.png]] | 13 | 14 | *** Namespace: ws-ldn-10.ex02 15 | 16 | - Iterative systems #1 17 | - SVG vs bitmap outputs 18 | - Mapping parameters to colors 19 | 20 | [[./assets/dejong.png]] 21 | 22 | *** Namespace: ws-ldn-10.ex03 23 | 24 | - Noise & octaves 25 | - Turbulence 26 | - Tonemapping noise values 27 | - Using noise to drive design parameters 28 | 29 | [[./assets/noise-lines.png]] 30 | 31 | *** Namespace: ws-ldn-10.ex04 32 | 33 | - Agent systems 34 | - Di-pole field lines 35 | - =deftype= & =defprotocol= 36 | - SVG image sequence output & MP4 conversion 37 | 38 | [[./assets/agents.png]] 39 | 40 | *** Namespace: ws-ldn-10.ex06 41 | 42 | - L-Systems 43 | - Recursive rule expansions 44 | - Writing simple interpreter (using =defmulti=) 45 | - Implementing branching (state stacks) 46 | - Visualizing recursion depth 47 | 48 | | [[./assets/lsys-gasket.png]] | [[./assets/lsys-penrose.png]] | 49 | | [[./assets/lsys-tree.png]] | [[./assets/lsys-dragon.png]] | 50 | 51 | ** License 52 | 53 | This project is open source and licensed under the [[http://www.apache.org/licenses/LICENSE-2.0][Apache Software License 2.0]]. 54 | -------------------------------------------------------------------------------- /ws-ldn-10/assets/agents.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thi-ng/demos/048cd131099a7db29be56b965c053908acad4166/ws-ldn-10/assets/agents.png -------------------------------------------------------------------------------- /ws-ldn-10/assets/dejong.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thi-ng/demos/048cd131099a7db29be56b965c053908acad4166/ws-ldn-10/assets/dejong.png -------------------------------------------------------------------------------- /ws-ldn-10/assets/ex03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thi-ng/demos/048cd131099a7db29be56b965c053908acad4166/ws-ldn-10/assets/ex03.png -------------------------------------------------------------------------------- /ws-ldn-10/assets/ex04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thi-ng/demos/048cd131099a7db29be56b965c053908acad4166/ws-ldn-10/assets/ex04.png -------------------------------------------------------------------------------- /ws-ldn-10/assets/lsys-dragon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thi-ng/demos/048cd131099a7db29be56b965c053908acad4166/ws-ldn-10/assets/lsys-dragon.png -------------------------------------------------------------------------------- /ws-ldn-10/assets/lsys-gasket.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thi-ng/demos/048cd131099a7db29be56b965c053908acad4166/ws-ldn-10/assets/lsys-gasket.png -------------------------------------------------------------------------------- /ws-ldn-10/assets/lsys-penrose.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thi-ng/demos/048cd131099a7db29be56b965c053908acad4166/ws-ldn-10/assets/lsys-penrose.png -------------------------------------------------------------------------------- /ws-ldn-10/assets/lsys-tree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thi-ng/demos/048cd131099a7db29be56b965c053908acad4166/ws-ldn-10/assets/lsys-tree.png -------------------------------------------------------------------------------- /ws-ldn-10/assets/noise-lines.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thi-ng/demos/048cd131099a7db29be56b965c053908acad4166/ws-ldn-10/assets/noise-lines.png -------------------------------------------------------------------------------- /ws-ldn-10/makevideo: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | for i in `ls assets/$1*.svg`; do 3 | echo "converting $i" 4 | rsvg-convert -b "#fff" -f png -o $i.png $i 5 | done 6 | ffmpeg \ 7 | -framerate 30 \ 8 | -i assets/$1-%04d.svg.png \ 9 | -s:v 600x600 \ 10 | -c:v libx264 \ 11 | -profile:v high \ 12 | -crf 23 \ 13 | -pix_fmt yuv420p \ 14 | -y \ 15 | out.mp4 16 | -------------------------------------------------------------------------------- /ws-ldn-10/project.clj: -------------------------------------------------------------------------------- 1 | (defproject ws-ldn-10 "0.1.0-SNAPSHOT" 2 | :description "thi.ng workshop WS-LDN-10" 3 | :url "http://workshop.thi.ng" 4 | :license {:name "Apache Software License" 5 | :url "http://www.apache.org/licenses/"} 6 | 7 | :dependencies [[org.clojure/clojure "1.8.0"] 8 | [org.clojure/clojurescript "1.8.51"] 9 | [org.clojure/core.async "0.2.374" 10 | :exclusions [org.clojure/tools.reader]] 11 | [thi.ng/geom "0.0.1173-SNAPSHOT"] 12 | [reagent "0.6.0-alpha2"]] 13 | 14 | :plugins [[lein-figwheel "0.5.4-3"] 15 | [lein-cljsbuild "1.1.3" :exclusions [[org.clojure/clojure]]]] 16 | 17 | :source-paths ["src/clj"] 18 | 19 | :clean-targets ^{:protect false} ["resources/public/js/compiled" "target"] 20 | 21 | :cljsbuild {:builds 22 | [{:id "dev" 23 | :source-paths ["src/cljs"] 24 | :figwheel true 25 | :compiler {:main ws-ldn-10.speech 26 | :asset-path "js/compiled/out" 27 | :output-to "resources/public/js/compiled/app.js" 28 | :output-dir "resources/public/js/compiled/out" 29 | :source-map-timestamp true}} 30 | {:id "min" 31 | :source-paths ["src/cljs"] 32 | :compiler {:output-to "resources/public/js/compiled/app.js" 33 | :optimizations :advanced 34 | :pretty-print false}}]} 35 | 36 | :figwheel {:css-dirs ["resources/public/css"] 37 | ;; :ring-handler hello_world.server/handler 38 | }) 39 | -------------------------------------------------------------------------------- /ws-ldn-10/resources/public/css/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: Helvetica,Arial,sans-serif; 3 | font-size: 14px; 4 | background: #f0f0f0; 5 | } 6 | 7 | div.transcript, div.interim { 8 | font-size: 200%; 9 | font-family: Inconsolata, Menlo, monospace; 10 | background: #f8f0e0; 11 | padding: 10px; 12 | min-height: 2em; 13 | } 14 | 15 | div.ann-expr { 16 | border-top: 1px solid #e8e0d0; 17 | padding: 5px 0; 18 | } 19 | 20 | .ann-type, .ann-number, .ann-keyword, .ann-color, .ann-unknown { 21 | margin-right: 0.25em; 22 | } 23 | 24 | .ann-type { 25 | color: #f06; 26 | } 27 | 28 | .ann-number { 29 | color: #90f; 30 | } 31 | 32 | .ann-keyword { 33 | color: #3cf; 34 | } 35 | 36 | .ann-unknown { 37 | color: #999; 38 | font-weight: 100; 39 | text-decoration: line-through; 40 | } 41 | 42 | .ann-color { 43 | padding: 5px; 44 | } 45 | 46 | .ann-color-blue { 47 | background: #00f; 48 | color: white; 49 | } 50 | 51 | .ann-color-red { 52 | background: #f00; 53 | color: white; 54 | } 55 | 56 | .ann-color-green { 57 | background: #0f0; 58 | color: black; 59 | } 60 | 61 | .ann-color-yellow { 62 | background: #ff0; 63 | color: black; 64 | } 65 | 66 | .ann-color-orange { 67 | background: #f50; 68 | color: white; 69 | } 70 | 71 | .ann-color-pink { 72 | background: #f0f; 73 | color: white; 74 | } 75 | 76 | .ann-color-cyan { 77 | background: #0ff; 78 | color: black; 79 | } 80 | 81 | .ann-color-purple { 82 | background: #808; 83 | color: white; 84 | } 85 | 86 | .ann-color-white { 87 | background: white; 88 | color: black; 89 | } 90 | 91 | .ann-color-black { 92 | background: black; 93 | color: white; 94 | } -------------------------------------------------------------------------------- /ws-ldn-10/resources/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | WS-LDN-10 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /ws-ldn-10/src/clj/ws_ldn_10/ex05.clj: -------------------------------------------------------------------------------- 1 | (ns ws-ldn-10.ex05 2 | (:require 3 | [thi.ng.math.core :as m] 4 | [thi.ng.geom.core :as g] 5 | [thi.ng.geom.vector :as v] 6 | [thi.ng.geom.aabb :as a] 7 | [thi.ng.geom.sphere :as s] 8 | [thi.ng.geom.gmesh :as gm] 9 | [thi.ng.geom.circle :as c] 10 | [thi.ng.geom.ptf :as ptf] 11 | [thi.ng.geom.mesh.io :as mio] 12 | [thi.ng.geom.mesh.csg :as csg] 13 | [thi.ng.geom.mesh.subdivision :as sd] 14 | [clojure.java.io :as io])) 15 | 16 | (def box (a/aabb (v/vec3 1000 -200 300) 100)) 17 | 18 | (g/center box) 19 | 20 | (defn subdivide 21 | [mesh n subdiv-fn] 22 | (->> mesh 23 | (iterate subdiv-fn) 24 | (drop 1) 25 | (take n) 26 | last)) 27 | 28 | (def box-mesh 29 | (-> box 30 | (g/translate [10 20 30]) 31 | (g/rotate-y m/QUARTER_PI) 32 | (g/scale 2) 33 | (g/as-mesh {:mesh (gm/gmesh)}) 34 | ;;(g/compute-face-normals) 35 | (g/tessellate) 36 | (subdivide 1 sd/catmull-clark))) 37 | 38 | (with-open [out (io/output-stream "box.ply")] 39 | (mio/write-ply (mio/wrapped-output-stream out) box-mesh)) 40 | 41 | (def a (-> (a/aabb 1) 42 | (g/as-mesh) 43 | (csg/mesh->csg))) 44 | 45 | (def b (-> (s/sphere (v/vec3 1) 1) 46 | (g/as-mesh {:res 40}) 47 | (csg/mesh->csg))) 48 | 49 | (def result (csg/csg->mesh (csg/union a b))) 50 | 51 | (with-open [out (io/output-stream "csg.obj")] 52 | (mio/write-obj (mio/wrapped-output-stream out) result)) 53 | 54 | (defn cinquefoil 55 | [t] 56 | (let [t (* t m/TWO_PI) 57 | pt (* 2.0 t) 58 | qt (* 7.0 t) 59 | qc (+ 3.0 (Math/cos qt))] 60 | (v/vec3 61 | (* qc (Math/cos pt)) 62 | (* qc (Math/sin pt)) 63 | (Math/sin qt)))) 64 | 65 | (def ptf-mesh 66 | (ptf/sweep-mesh 67 | (mapv cinquefoil (m/norm-range 400)) 68 | (g/vertices (c/circle 0.5) 3) 69 | {:align? true :loop? true})) 70 | 71 | (with-open [out (io/output-stream "ptf.obj")] 72 | (mio/write-obj (mio/wrapped-output-stream out) ptf-mesh)) 73 | -------------------------------------------------------------------------------- /ws-ldn-11/day1/ex01/project.clj: -------------------------------------------------------------------------------- 1 | (defproject ws-ldn-11-ex01 "0.1.0-SNAPSHOT" 2 | :description "thi.ng Clojurescript workshop WS-LDN-11" 3 | :url "http://workshop.thi.ng" 4 | 5 | :min-lein-version "2.5.3" 6 | 7 | :dependencies [[org.clojure/clojure "1.8.0"] 8 | [org.clojure/clojurescript "1.8.51"] 9 | [org.clojure/core.async "0.2.374" 10 | :exclusions [org.clojure/tools.reader]] 11 | [thi.ng/geom "0.0.1178-SNAPSHOT"] 12 | [thi.ng/domus "0.3.0-SNAPSHOT"]] 13 | 14 | :plugins [[lein-figwheel "0.5.4-3"] 15 | [lein-cljsbuild "1.1.3" :exclusions [[org.clojure/clojure]]]] 16 | 17 | :source-paths ["src"] 18 | 19 | :clean-targets ^{:protect false} ["resources/public/js/compiled" "target"] 20 | 21 | :cljsbuild {:builds 22 | [{:id "dev" 23 | :source-paths ["src"] 24 | :figwheel true 25 | :compiler {:main ex01.core 26 | :asset-path "js/compiled/out" 27 | :output-to "resources/public/js/compiled/app.js" 28 | :output-dir "resources/public/js/compiled/out" 29 | :source-map-timestamp true}} 30 | {:id "min" 31 | :source-paths ["src"] 32 | :compiler {:output-to "resources/public/js/compiled/app.js" 33 | :main ex01.core 34 | :optimizations :advanced 35 | :pretty-print false}}]} 36 | 37 | :figwheel {:css-dirs ["resources/public/css"]}) 38 | -------------------------------------------------------------------------------- /ws-ldn-11/day1/ex01/resources/public/css/style.css: -------------------------------------------------------------------------------- 1 | /* some style */ 2 | 3 | -------------------------------------------------------------------------------- /ws-ldn-11/day1/ex01/resources/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 |

WS-LDN-5

11 |
12 |
13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /ws-ldn-11/day1/ex01/src/ex01/shapes01.cljs: -------------------------------------------------------------------------------- 1 | (ns ex01.shapes01 2 | (:require 3 | [thi.ng.geom.core :as g] 4 | [thi.ng.geom.polygon :as poly] 5 | [thi.ng.geom.svg.core :as svg] 6 | [thi.ng.domus.core :as dom])) 7 | 8 | (enable-console-print!) 9 | 10 | (defn ^:export main 11 | [] 12 | (dom/create-dom! 13 | (svg/svg 14 | {:width 640 :height 480} 15 | (-> (poly/cog 0.5 20 [0.9 1 1 0.9 0.3]) 16 | (g/scale 480) 17 | (g/translate [320 240]) 18 | (g/vertices) 19 | (svg/polygon {:fill "black" :stroke "#0ff"}))) 20 | (dom/by-id "app"))) 21 | 22 | ;;(main) 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /ws-ldn-11/day1/ex01/src/ex01/utils.cljs: -------------------------------------------------------------------------------- 1 | (ns ex01.utils 2 | (:require 3 | [thi.ng.strf.core :as f])) 4 | 5 | (defn timed 6 | "Executes function f and returns its execution time in ms." 7 | [f] (let [t0 (f/now)] (f) (- (f/now) t0))) 8 | 9 | (defn conj-max 10 | "Takes a vector, size limit and value x. Appends x to vector and 11 | ensures vector does not grow beyond limit." 12 | [vec limit x] 13 | (let [n (count vec)] 14 | (if (>= n limit) 15 | (conj (subvec vec (inc (- n limit))) x) 16 | (conj vec x)))) 17 | 18 | (defn run-with-timer 19 | "Takes a volatile containing vector of timing samples, window size 20 | and function f. Executes f and measures and records execution time, 21 | returns avg. exec time of whole time window." 22 | [samples window f] 23 | (let [samples (vswap! samples conj-max window (timed f))] 24 | (/ (reduce + samples) (count samples)))) 25 | -------------------------------------------------------------------------------- /ws-ldn-11/day1/ex02/project.clj: -------------------------------------------------------------------------------- 1 | (defproject ws-ldn-11-ex02 "0.1.0-SNAPSHOT" 2 | :description "thi.ng Clojurescript workshop WS-LDN-11" 3 | :url "http://workshop.thi.ng" 4 | 5 | :min-lein-version "2.5.3" 6 | 7 | :dependencies [[org.clojure/clojure "1.8.0"] 8 | [org.clojure/clojurescript "1.8.51"] 9 | [org.clojure/core.async "0.2.374" :exclusions [org.clojure/tools.reader]] 10 | [thi.ng/geom "0.0.1178-SNAPSHOT"] 11 | [thi.ng/domus "0.3.0-SNAPSHOT"] 12 | [reagent "0.5.1"]] 13 | 14 | :plugins [[lein-figwheel "0.5.4-3"] 15 | [lein-cljsbuild "1.1.3" :exclusions [[org.clojure/clojure]]]] 16 | 17 | :source-paths ["src"] 18 | 19 | :clean-targets ^{:protect false} ["resources/public/js/compiled" "target"] 20 | 21 | :cljsbuild {:builds 22 | [{:id "dev" 23 | :source-paths ["src"] 24 | :figwheel true 25 | :compiler {:main ex02.core 26 | :asset-path "js/compiled/out" 27 | :output-to "resources/public/js/compiled/app.js" 28 | :output-dir "resources/public/js/compiled/out" 29 | :source-map-timestamp true}} 30 | {:id "min" 31 | :source-paths ["src"] 32 | :compiler {:output-to "resources/public/js/compiled/app.js" 33 | :main ex02.core 34 | :optimizations :advanced 35 | :pretty-print false}}]} 36 | 37 | :figwheel {:css-dirs ["resources/public/css"]}) 38 | -------------------------------------------------------------------------------- /ws-ldn-11/day1/ex02/resources/public/css/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: Helvetica, Arial, sans-serif; 3 | } 4 | 5 | div { 6 | margin-bottom: 1em; 7 | } 8 | select { 9 | margin-right: 2em; 10 | } 11 | 12 | -------------------------------------------------------------------------------- /ws-ldn-11/day1/ex02/resources/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |

WS-LDN-8: Hi-perf Clojurescript workshop

10 |
Workshop repo
11 |
12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /ws-ldn-11/day1/ex02/src/ex02/faster.cljs: -------------------------------------------------------------------------------- 1 | (ns ex02.faster 2 | (:require-macros 3 | [thi.ng.math.macros :as mm]) 4 | (:require 5 | [ex02.state :as state] 6 | [ex02.utils :as utils] 7 | [thi.ng.typedarrays.core :as ta] 8 | [reagent.core :as r])) 9 | 10 | (defn sum-neighbors 11 | "Returns number of active neighbours for a cell at x;y using 12 | thi.ng.math macro to compute sum." 13 | [grid idx stride] 14 | (let [t (- idx stride) 15 | b (+ idx stride)] 16 | (mm/add 17 | (nth grid (- t 1)) 18 | (nth grid t) 19 | (nth grid (+ t 1)) 20 | (nth grid (- idx 1)) 21 | (nth grid (+ idx 1)) 22 | (nth grid (- b 1)) 23 | (nth grid b) 24 | (nth grid (+ b 1))))) 25 | 26 | (defn life-step 27 | "Computes new state for a single cell." 28 | [grid idx stride] 29 | (let [neighbors (sum-neighbors grid idx stride)] 30 | (if (pos? (nth grid idx)) 31 | (if (or (== neighbors 2) (== neighbors 3)) 1 0) 32 | (if (== 3 neighbors) 1 0)))) 33 | 34 | (defn life 35 | "Computes next generation of entire cell grid." 36 | [w h grid] 37 | (let [w' (- w 1) 38 | h' (- h 2)] 39 | (loop [grid' grid, idx (+ w 1), x 1, y 1] 40 | (if (< x w') 41 | (recur (assoc grid' idx (life-step grid idx w)) (inc idx) (inc x) y) 42 | (if (< y h') 43 | (recur grid' (+ idx 2) 1 (inc y)) 44 | grid'))))) 45 | 46 | (defn draw 47 | "Visualizes grid state in given canvas context." 48 | [ctx w h grid] 49 | (let [w' (- w 1) 50 | h' (- h 2)] 51 | (set! (.-fillStyle ctx) "#000") 52 | (.fillRect ctx 0 0 w h) 53 | (set! (.-fillStyle ctx) "#0ff") 54 | (loop [i 0, x 1, y 1] 55 | (if (< x w') 56 | (do (when (pos? (nth grid i)) 57 | (.fillRect ctx x y 1 1)) 58 | (recur (inc i) (inc x) y)) 59 | (if (< y h') 60 | (recur (+ i 2) 1 (inc y)) 61 | grid))))) 62 | 63 | (defn init 64 | [this props] 65 | (swap! state/app merge 66 | {:grid (->> #(if (< (rand) 0.25) 1 0) 67 | (repeatedly (* (:width props) (:height props))) 68 | vec)})) 69 | 70 | (defn redraw 71 | [this props] 72 | (let [{:keys [width height]} props 73 | ctx (.getContext (r/dom-node this) "2d")] 74 | (let [[avg grid] (utils/run-with-timer 75 | #(->> (:grid @state/app) 76 | (life width height) 77 | (draw ctx width height)))] 78 | (swap! state/app assoc :grid grid :avg avg)))) 79 | -------------------------------------------------------------------------------- /ws-ldn-11/day1/ex02/src/ex02/state.cljs: -------------------------------------------------------------------------------- 1 | (ns ex02.state 2 | (:require-macros 3 | [reagent.ratom :refer [reaction]] 4 | [cljs-log.core :refer [debug info warn severe]]) 5 | (:require 6 | [thi.ng.strf.core :as f] 7 | [reagent.core :as r])) 8 | 9 | (defonce app 10 | (r/atom 11 | {:size 256 12 | :samples [] 13 | :num-samples 30 14 | :avg 0 15 | :mode :naive})) 16 | 17 | (defn set-mode! 18 | [e] 19 | (let [id (-> e .-target .-value keyword)] 20 | (debug :set-mode id) 21 | (swap! app assoc :mode id :samples [] :reset true))) 22 | 23 | (defn set-size! 24 | [e] 25 | (let [size (-> e .-target .-value (f/parse-int 10))] 26 | (debug :set-size size) 27 | (swap! app assoc :size size :samples [] :reset true))) 28 | -------------------------------------------------------------------------------- /ws-ldn-11/day1/ex02/src/ex02/utils.cljs: -------------------------------------------------------------------------------- 1 | (ns ex02.utils 2 | (:require 3 | [ex02.state :as state] 4 | [thi.ng.strf.core :as f])) 5 | 6 | (defn timed 7 | "Executes function f and returns vector of [execution-time result-of-f]" 8 | [f] (let [t0 (f/now) res (f)] [(- (f/now) t0) res])) 9 | 10 | (defn conj-max 11 | "Takes a vector, size limit and value x. Appends x to vector and 12 | ensures vector does not grow beyond limit." 13 | [vec limit x] 14 | (let [n (count vec)] 15 | (if (>= n limit) 16 | (conj (subvec vec (inc (- n limit))) x) 17 | (conj vec x)))) 18 | 19 | (defn run-with-timer 20 | "Executes f, measures and records execution time, 21 | returns vector of avg. exec time of whole time window and result of f." 22 | [f] 23 | (let [[t res] (timed f) 24 | _ (swap! state/app update :samples conj-max (:num-samples @state/app) t) 25 | samples (get @state/app :samples)] 26 | [(/ (reduce + samples) (count samples)) res])) 27 | -------------------------------------------------------------------------------- /ws-ldn-11/day1/ex03/project.clj: -------------------------------------------------------------------------------- 1 | (defproject ws-ldn-11-ex03 "0.1.0-SNAPSHOT" 2 | :description "thi.ng Clojurescript workshop WS-LDN-8" 3 | :url "http://workshop.thi.ng" 4 | 5 | :min-lein-version "2.5.3" 6 | 7 | :dependencies [[org.clojure/clojure "1.8.0"] 8 | [org.clojure/clojurescript "1.8.51"] 9 | [org.clojure/core.async "0.2.374" 10 | :exclusions [org.clojure/tools.reader]] 11 | [thi.ng/geom "0.0.1178-SNAPSHOT"] 12 | [thi.ng/domus "0.3.0-SNAPSHOT"]] 13 | 14 | :plugins [[lein-figwheel "0.5.4-3"] 15 | [lein-cljsbuild "1.1.3" :exclusions [[org.clojure/clojure]]]] 16 | 17 | :source-paths ["src"] 18 | 19 | :clean-targets ^{:protect false} ["resources/public/js/compiled" "target"] 20 | 21 | :cljsbuild {:builds 22 | [{:id "dev" 23 | :source-paths ["src"] 24 | :compiler {:asset-path "js/compiled/out" 25 | :output-to "resources/public/js/compiled/app.js" 26 | :output-dir "resources/public/js/compiled/out" 27 | :optimizations :simple 28 | :pretty-print true}} 29 | {:id "min" 30 | :source-paths ["src"] 31 | :compiler {:output-to "resources/public/js/compiled/app.js" 32 | :optimizations :advanced 33 | :pretty-print false}}]} 34 | 35 | :figwheel {:css-dirs ["resources/public/css"]}) 36 | -------------------------------------------------------------------------------- /ws-ldn-11/day1/ex03/resources/public/css/style.css: -------------------------------------------------------------------------------- 1 | .stats { position: fixed; top: 0px; left: 0px; } -------------------------------------------------------------------------------- /ws-ldn-11/day1/ex03/resources/public/img/cubev.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thi-ng/demos/048cd131099a7db29be56b965c053908acad4166/ws-ldn-11/day1/ex03/resources/public/img/cubev.png -------------------------------------------------------------------------------- /ws-ldn-11/day1/ex03/resources/public/img/dione.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thi-ng/demos/048cd131099a7db29be56b965c053908acad4166/ws-ldn-11/day1/ex03/resources/public/img/dione.jpg -------------------------------------------------------------------------------- /ws-ldn-11/day1/ex03/resources/public/img/earth.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thi-ng/demos/048cd131099a7db29be56b965c053908acad4166/ws-ldn-11/day1/ex03/resources/public/img/earth.jpg -------------------------------------------------------------------------------- /ws-ldn-11/day1/ex03/resources/public/img/moon.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thi-ng/demos/048cd131099a7db29be56b965c053908acad4166/ws-ldn-11/day1/ex03/resources/public/img/moon.jpg -------------------------------------------------------------------------------- /ws-ldn-11/day1/ex03/resources/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 |
12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /ws-ldn-11/day1/ex03/resources/public/suzanne.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thi-ng/demos/048cd131099a7db29be56b965c053908acad4166/ws-ldn-11/day1/ex03/resources/public/suzanne.stl -------------------------------------------------------------------------------- /ws-ldn-11/day1/ex03/src/ex03/webgl01.cljs: -------------------------------------------------------------------------------- 1 | (ns ex03.webgl01 2 | (:require 3 | [thi.ng.math.core :as m :refer [PI HALF_PI TWO_PI]] 4 | [thi.ng.geom.gl.core :as gl] 5 | [thi.ng.geom.gl.webgl.constants :as glc] 6 | [thi.ng.geom.gl.webgl.animator :as anim] 7 | [thi.ng.geom.gl.glmesh :as glm] 8 | [thi.ng.geom.gl.shaders :as sh] 9 | [thi.ng.geom.core :as g] 10 | [thi.ng.geom.vector :as v :refer [vec2 vec3]] 11 | [thi.ng.geom.matrix :as mat :refer [M44]] 12 | [thi.ng.geom.circle :as c] 13 | [thi.ng.geom.polygon :as poly])) 14 | 15 | (enable-console-print!) 16 | 17 | (def shader-spec 18 | {:vs "void main() { gl_Position = proj * view * model * vec4(position, 0.0, 1.0); }" 19 | :fs "void main() { gl_FragColor = color; }" 20 | :uniforms {:proj :mat4 21 | :model [:mat4 M44] 22 | :view [:mat4 M44] 23 | :color [:vec4 [0 0 0 1]]} 24 | :attribs {:position :vec2} 25 | :state {:depth false}}) 26 | 27 | (defn ^:export demo 28 | [] 29 | (let [teeth 20 30 | gl (gl/gl-context "main") 31 | view-rect (gl/get-viewport-rect gl) 32 | model (-> (poly/cog 0.5 teeth [0.9 1 1 0.9]) 33 | (gl/as-gl-buffer-spec {:normals false}) 34 | (gl/make-buffers-in-spec gl glc/static-draw) 35 | (assoc-in [:uniforms :proj] (gl/ortho view-rect)) 36 | (assoc :shader (sh/make-shader-from-spec gl shader-spec)))] 37 | (anim/animate 38 | (fn [t frame] 39 | (doto gl 40 | (gl/set-viewport view-rect) 41 | (gl/clear-color-and-depth-buffer 0.9 0.9 0.92 1 1) 42 | ;; draw left polygon 43 | (gl/draw-with-shader 44 | (update model :uniforms merge 45 | {:model (-> M44 (g/translate -0.48 0 0) (g/rotate t)) 46 | :color [0 1 1 1]})) 47 | ;; draw right polygon 48 | (gl/draw-with-shader 49 | (update model :uniforms merge 50 | {:model (-> M44 (g/translate 0.48 0 0) (g/rotate (- (+ t (/ HALF_PI teeth))))) 51 | :color [0 1 0 1]}))) 52 | true)))) 53 | -------------------------------------------------------------------------------- /ws-ldn-11/day1/ex03/src/ex03/webgl02.cljs: -------------------------------------------------------------------------------- 1 | (ns ex03.webgl02 2 | (:require 3 | [thi.ng.math.core :as m :refer [PI HALF_PI TWO_PI]] 4 | [thi.ng.geom.gl.core :as gl] 5 | [thi.ng.geom.gl.webgl.constants :as glc] 6 | [thi.ng.geom.gl.webgl.animator :as anim] 7 | [thi.ng.geom.gl.glmesh :as glm] 8 | [thi.ng.geom.gl.camera :as cam] 9 | [thi.ng.geom.gl.shaders :as sh] 10 | [thi.ng.geom.gl.shaders.basic :as basic] 11 | [thi.ng.geom.core :as g] 12 | [thi.ng.geom.vector :as v :refer [vec2 vec3]] 13 | [thi.ng.geom.matrix :as mat :refer [M44]] 14 | [thi.ng.geom.aabb :as a] 15 | [thi.ng.geom.attribs :as attr] 16 | [thi.ng.color.core :as col])) 17 | 18 | (defn ^:export demo 19 | [] 20 | (let [gl (gl/gl-context "main") 21 | view-rect (gl/get-viewport-rect gl) 22 | model (-> (a/aabb 1) 23 | (g/center) 24 | (g/as-mesh 25 | {:mesh (glm/indexed-gl-mesh 12 #{:col}) 26 | ;;:flags :ewfb 27 | :attribs {:col (->> [[1 0 0] [0 1 0] [0 0 1] [0 1 1] [1 0 1] [1 1 0]] 28 | (map col/rgba) 29 | (attr/const-face-attribs))}}) 30 | (gl/as-gl-buffer-spec {}) 31 | (cam/apply (cam/perspective-camera {:aspect view-rect})) 32 | (assoc :shader (sh/make-shader-from-spec gl (basic/make-shader-spec-3d true))) 33 | (gl/make-buffers-in-spec gl glc/static-draw))] 34 | (anim/animate 35 | (fn [t frame] 36 | (doto gl 37 | (gl/set-viewport view-rect) 38 | (gl/clear-color-and-depth-buffer col/WHITE 1) 39 | (gl/enable glc/depth-test) 40 | (gl/draw-with-shader 41 | (assoc-in model [:uniforms :model] (-> M44 (g/rotate-x t) (g/rotate-y (* t 2)))))) 42 | true)))) 43 | -------------------------------------------------------------------------------- /ws-ldn-11/day1/ex03/src/ex03/webgl03.cljs: -------------------------------------------------------------------------------- 1 | (ns ex03.webgl03 2 | (:require 3 | [thi.ng.math.core :as m :refer [PI HALF_PI TWO_PI]] 4 | [thi.ng.geom.gl.core :as gl] 5 | [thi.ng.geom.gl.webgl.constants :as glc] 6 | [thi.ng.geom.gl.webgl.animator :as anim] 7 | [thi.ng.geom.gl.glmesh :as glm] 8 | [thi.ng.geom.gl.camera :as cam] 9 | [thi.ng.geom.gl.shaders :as sh] 10 | [thi.ng.geom.gl.shaders.lambert :as lambert] 11 | [thi.ng.geom.core :as g] 12 | [thi.ng.geom.vector :as v :refer [vec2 vec3]] 13 | [thi.ng.geom.matrix :as mat :refer [M44]] 14 | [thi.ng.geom.aabb :as a] 15 | [thi.ng.geom.attribs :as attr] 16 | [thi.ng.color.core :as col])) 17 | 18 | (defn ^:export demo 19 | [] 20 | (let [gl (gl/gl-context "main") 21 | view-rect (gl/get-viewport-rect gl) 22 | model (-> (a/aabb 0.8) 23 | (g/center) 24 | (g/as-mesh 25 | {:mesh (glm/indexed-gl-mesh 12 #{:col :fnorm}) 26 | ;;:flags :ewfbs 27 | :attribs {:col (->> [[1 0 0] [0 1 0] [0 0 1] [0 1 1] [1 0 1] [1 1 0]] 28 | (map col/rgba) 29 | (attr/const-face-attribs))}}) 30 | (gl/as-gl-buffer-spec {}) 31 | (cam/apply (cam/perspective-camera {:aspect view-rect})) 32 | (assoc :shader (sh/make-shader-from-spec gl lambert/shader-spec-two-sided-attrib)) 33 | (gl/make-buffers-in-spec gl glc/static-draw))] 34 | (anim/animate 35 | (fn [t frame] 36 | (doto gl 37 | (gl/set-viewport view-rect) 38 | (gl/clear-color-and-depth-buffer col/GRAY 1) 39 | (gl/draw-with-shader 40 | (assoc-in model [:uniforms :model] (-> M44 (g/rotate-x t) (g/rotate-y (* t 2)))))) 41 | true)))) 42 | -------------------------------------------------------------------------------- /ws-ldn-11/day2/ex04/project.clj: -------------------------------------------------------------------------------- 1 | (defproject ws-ldn-11-ex04 "0.1.0-SNAPSHOT" 2 | :description "thi.ng Clojurescript workshop WS-LDN-11" 3 | :url "http://workshop.thi.ng" 4 | 5 | :min-lein-version "2.5.3" 6 | 7 | :dependencies [[org.clojure/clojure "1.8.0"] 8 | [org.clojure/clojurescript "1.8.51"] 9 | [org.clojure/core.async "0.2.374" 10 | :exclusions [org.clojure/tools.reader]] 11 | [thi.ng/geom "0.0.1178-SNAPSHOT"] 12 | [thi.ng/domus "0.3.0-SNAPSHOT"] 13 | [reagent "0.5.1"]] 14 | 15 | :plugins [[lein-figwheel "0.5.4-3"] 16 | [lein-cljsbuild "1.1.3" :exclusions [[org.clojure/clojure]]]] 17 | 18 | :source-paths ["src"] 19 | 20 | :clean-targets ^{:protect false} ["resources/public/js/compiled" "target"] 21 | 22 | :cljsbuild {:builds 23 | [{:id "dev" 24 | :source-paths ["src"] 25 | :figwheel true 26 | :compiler {:main ex04.core 27 | :asset-path "js/compiled/out" 28 | :output-to "resources/public/js/compiled/app.js" 29 | :output-dir "resources/public/js/compiled/out" 30 | :source-map-timestamp true}} 31 | {:id "min" 32 | :source-paths ["src"] 33 | :compiler {:output-to "resources/public/js/compiled/app.js" 34 | :optimizations :advanced 35 | :pretty-print false}}]} 36 | 37 | :figwheel {:css-dirs ["resources/public/css"] 38 | ;; :ring-handler hello_world.server/handler 39 | }) 40 | -------------------------------------------------------------------------------- /ws-ldn-11/day2/ex04/resources/public/css/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | padding: 0; 4 | overflow: hidden; 5 | background-color: black; 6 | } -------------------------------------------------------------------------------- /ws-ldn-11/day2/ex04/resources/public/img/cubev.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thi-ng/demos/048cd131099a7db29be56b965c053908acad4166/ws-ldn-11/day2/ex04/resources/public/img/cubev.png -------------------------------------------------------------------------------- /ws-ldn-11/day2/ex04/resources/public/img/sjo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thi-ng/demos/048cd131099a7db29be56b965c053908acad4166/ws-ldn-11/day2/ex04/resources/public/img/sjo512.png -------------------------------------------------------------------------------- /ws-ldn-11/day2/ex04/resources/public/img/sjo512_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thi-ng/demos/048cd131099a7db29be56b965c053908acad4166/ws-ldn-11/day2/ex04/resources/public/img/sjo512_2.png -------------------------------------------------------------------------------- /ws-ldn-11/day2/ex04/resources/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 |
12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /ws-ldn-11/day2/ex04/src/ex04/cache.cljs: -------------------------------------------------------------------------------- 1 | (ns ex04.cache 2 | (:require 3 | )) 4 | 5 | ;; localforage.config({ 6 | ;; driver: localforage.LOCALSTORAGE, 7 | ;; name: 'I-<3-localStorage' 8 | ;; }); 9 | -------------------------------------------------------------------------------- /ws-ldn-11/day2/ex04/src/ex04/camera.cljs: -------------------------------------------------------------------------------- 1 | (ns ex04.camera 2 | (:require 3 | [thi.ng.math.core :as m :refer [PI HALF_PI TWO_PI]] 4 | [thi.ng.geom.gl.camera :as cam] 5 | [thi.ng.geom.utils :as gu])) 6 | 7 | (defn camera-path 8 | [points frames] 9 | (let [up (nth frames 2)] 10 | {:pos points 11 | :pos-index (gu/arc-length-index points) 12 | :up up 13 | :up-index (gu/arc-length-index up)})) 14 | 15 | (defn camera-at-path-pos 16 | [{:keys [pos pos-index up up-index]} t delta view-rect] 17 | (let [t (mod t 1.0) 18 | t (if (neg? t) (inc t) t) 19 | t' (mod (+ t delta) 1.0) 20 | eye (gu/point-at t pos pos-index) 21 | target (gu/point-at t' pos pos-index) 22 | up (m/normalize (gu/point-at t up up-index))] 23 | (cam/perspective-camera 24 | {:eye eye 25 | :target target 26 | :up up 27 | :fov 90 28 | :aspect view-rect 29 | :far 10}))) 30 | -------------------------------------------------------------------------------- /ws-ldn-11/day2/ex04/src/ex04/config.cljs: -------------------------------------------------------------------------------- 1 | (ns ex04.config) 2 | 3 | (def config 4 | {:player-speed 0.0004 5 | :player-max-speed 0.0012 6 | :accel 0.025 7 | :steer-accel 0.05 8 | :tunnel-path-res 0.2 9 | :cam-distance 0.005 10 | :cam-dist-factor 20 11 | :cam-speed-factor 50}) 12 | -------------------------------------------------------------------------------- /ws-ldn-11/day2/ex04/src/ex04/core.cljs: -------------------------------------------------------------------------------- 1 | (ns ex04.core 2 | (:require-macros 3 | [reagent.ratom :refer [reaction]] 4 | [cljs-log.core :refer [debug info warn severe]]) 5 | (:require 6 | [ex04.game :as game] 7 | [thi.ng.geom.gl.webgl.animator :as anim] 8 | [thi.ng.domus.core :as dom] 9 | [reagent.core :as reagent])) 10 | 11 | (enable-console-print!) 12 | 13 | (defn gl-component 14 | [props] 15 | (reagent/create-class 16 | {:component-did-mount 17 | (fn [this] 18 | (reagent/set-state this {:active true}) 19 | ((:init props) this) 20 | (anim/animate ((:loop props) this))) 21 | :component-will-unmount 22 | (fn [this] 23 | (debug "unmount GL") 24 | (reagent/set-state this {:active false})) 25 | :reagent-render 26 | (fn [_] 27 | [:canvas 28 | (merge 29 | {:width (.-innerWidth js/window) 30 | :height (.-innerHeight js/window)} 31 | props)])})) 32 | 33 | (defn main 34 | [] 35 | (.initializeTouchEvents js/React) 36 | (let [root [gl-component 37 | {:init game/init-game 38 | :loop game/game-loop 39 | :on-mouse-move (fn [e] (game/update-player-pos! (.-clientX e))) 40 | :on-mouse-down (fn [e] (game/player-max-speed!)) 41 | :on-mouse-up (fn [e] (game/player-normal-speed!)) 42 | :on-touch-move (fn [e] 43 | (game/update-player-pos! (.-clientX (aget (.-touches e) 0))) 44 | (game/player-max-speed!)) 45 | :on-touch-end (fn [e] (game/player-normal-speed!))}]] 46 | (reagent/render-component root (dom/by-id "app")))) 47 | 48 | (main) 49 | -------------------------------------------------------------------------------- /ws-ldn-11/day2/ex04/src/ex04/mesh.cljs: -------------------------------------------------------------------------------- 1 | (ns ex04.mesh 2 | (:require 3 | [ex04.config :refer [config]] 4 | [thi.ng.math.core :as m :refer [PI HALF_PI TWO_PI]] 5 | [thi.ng.geom.core :as g] 6 | [thi.ng.geom.vector :as v :refer [vec3]] 7 | [thi.ng.geom.attribs :as attr] 8 | [thi.ng.geom.aabb :as a] 9 | [thi.ng.geom.circle :refer [circle]] 10 | [thi.ng.geom.utils :as gu] 11 | [thi.ng.geom.gl.glmesh :refer [gl-mesh]] 12 | [thi.ng.geom.ptf :as ptf])) 13 | 14 | (defn cinquefoil 15 | [t] 16 | (let [t (* t TWO_PI) 17 | pt (* 2.0 t) 18 | qt (* 5.0 t) 19 | qc (+ 3.0 (Math/cos qt))] 20 | (v/vec3 (* qc (Math/cos pt)) (* qc (Math/sin pt)) (Math/sin qt)))) 21 | 22 | (def path-points 23 | "Evaluated points of cinquefoil knot" 24 | (gu/sample-uniform 25 | (:tunnel-path-res config) 26 | false 27 | (map cinquefoil (m/norm-range 400)))) 28 | 29 | (def path-frames 30 | "Precompute Parallel Transport Frames for each path point" 31 | (-> path-points ptf/compute-frames ptf/align-frames)) 32 | 33 | (defn solidify-segment 34 | [res seg] 35 | (let [off (- (count seg) 2) 36 | front (loop [acc [], i 0, j off] 37 | (if (< i (dec res)) 38 | (let [[averts aattr] (nth seg i) 39 | [bverts battr] (nth seg j) 40 | auv (:uv aattr) 41 | buv (:uv battr) 42 | f1 [[(nth averts 1) (nth averts 0) (nth bverts 1) (nth bverts 0)] 43 | {:uv [(nth auv 1) (nth auv 0) (nth buv 1) (nth buv 0)]}]] 44 | (recur (conj acc f1) (inc i) (dec j))) 45 | acc))] 46 | (concat seg front))) 47 | 48 | (defn knot-simple 49 | [] 50 | (let [res 7 51 | profile (concat (reverse (g/vertices (circle 0.5) res)) 52 | (g/vertices (circle 0.55) res)) 53 | attribs {:uv attr/uv-tube} 54 | opts {:loop? false :close? true} 55 | size (* (inc (bit-shift-right (count path-points) 1)) (+ (* 2 res) (dec res)) 2)] 56 | (->> path-frames 57 | (ptf/sweep-profile profile attribs opts) 58 | (partition (* res 2)) 59 | (take-nth 2) 60 | (mapcat #(solidify-segment res %)) 61 | (g/into (gl-mesh size #{:fnorm :uv})) 62 | (time)))) 63 | 64 | (defn player 65 | [] 66 | (-> (a/aabb 0.15 0.05 0.3) 67 | (g/center) 68 | (g/as-mesh {:mesh (gl-mesh 12 #{:fnorm})}))) 69 | -------------------------------------------------------------------------------- /ws-ldn-11/day2/ex04/src/ex04/shaders.cljs: -------------------------------------------------------------------------------- 1 | (ns ex04.shaders 2 | (:require 3 | [thi.ng.geom.matrix :as mat :refer [M44]] 4 | [thi.ng.geom.gl.shaders.phong :as phong] 5 | [thi.ng.glsl.core :as glsl :include-macros true] 6 | [thi.ng.glsl.vertex :as vertex] 7 | [thi.ng.glsl.lighting :as light] 8 | [thi.ng.glsl.fog :as fog])) 9 | 10 | (glsl/defglsl tunnel-vs 11 | [vertex/surface-normal] 12 | "void main() { 13 | vUV = uv; 14 | vPos = (view * model * vec4(position, 1.0)).xyz; 15 | vNormal = surfaceNormal(normal, normalMat); 16 | vLightDir = (view * vec4(lightPos, 1.0)).xyz - vPos; 17 | gl_Position = proj * vec4(vPos, 1.0); 18 | }") 19 | 20 | (glsl/defglsl tunnel-fs 21 | [fog/fog-linear light/beckmann-specular] 22 | "void main() { 23 | vec3 n = normalize(vNormal); 24 | vec3 v = normalize(-vPos); 25 | vec3 l = normalize(vLightDir); 26 | float NdotL = max(0.0, dot(n, l)); 27 | vec3 specular = Ks * beckmannSpecular(l, v, n, m); 28 | vec3 att = lightCol / pow(length(vLightDir), lightAtt); 29 | vec3 diff = texture2D(tex, vUV).xyz; 30 | vec3 col = att * NdotL * ((1.0 - s) * diff + s * specular) + Ka * diff; 31 | float fog = fogLinear(length(vPos), fogDist.x, fogDist.y); 32 | col = mix(col, Kf, fog); 33 | gl_FragColor = vec4(col, 1.0); 34 | }") 35 | 36 | (def tunnel-shader 37 | {:vs (glsl/assemble tunnel-vs) 38 | :fs (glsl/assemble tunnel-fs) 39 | :uniforms {:model [:mat4 M44] 40 | :view :mat4 41 | :proj :mat4 42 | :normalMat :mat4 43 | :tex :sampler2D 44 | :Ks [:vec3 [1 1 1]] 45 | :Ka [:vec3 [0.0 0.0 0.3]] 46 | :Kf [:vec3 [0.0 0.0 0.1]] 47 | :m [:float 0.5] 48 | :s [:float 0.5] 49 | :lightCol [:vec3 [1 1 1]] 50 | :lightPos [:vec3 [0 0 5]] 51 | :lightAtt [:float 3.0] 52 | :fogDist [:vec2 [1 4.5]] 53 | :time :float} 54 | :attribs {:position :vec3 55 | :normal :vec3 56 | :uv :vec2} 57 | :varying {:vUV :vec2 58 | :vPos :vec3 59 | :vNormal :vec3 60 | :vLightDir :vec3} 61 | :state {:depth-test true}}) 62 | 63 | (def player-shader phong/shader-spec) 64 | -------------------------------------------------------------------------------- /ws-ldn-11/day2/ex04/src/ex04/texture.cljs: -------------------------------------------------------------------------------- 1 | (ns ex04.texture 2 | (:require 3 | [thi.ng.geom.gl.buffers :as buf] 4 | [thi.ng.color.core :as col] 5 | [thi.ng.color.gradients :as grad])) 6 | 7 | (defn gradient-texture 8 | [gl w h opts] 9 | (let [canv (.createElement js/document "canvas") 10 | ctx (.getContext canv "2d") 11 | cols (reverse (grad/cosine-gradient h (:rainbow1 grad/cosine-schemes)))] 12 | (set! (.-width canv) w) 13 | (set! (.-height canv) h) 14 | (set! (.-strokeStyle ctx) "none") 15 | (loop [y 0, cols cols] 16 | (if cols 17 | (do 18 | (set! (.-fillStyle ctx) @(col/as-css (first cols))) 19 | (.fillRect ctx 0 y w 1) 20 | (recur (inc y) (next cols))) 21 | (buf/make-canvas-texture gl canv opts))))) 22 | -------------------------------------------------------------------------------- /ws-ldn-11/day2/ex05/project.clj: -------------------------------------------------------------------------------- 1 | (defproject ws-ldn-11-ex05 "0.1.0-SNAPSHOT" 2 | :description "FIXME: write description" 3 | :url "http://example.com/FIXME" 4 | 5 | :dependencies [[org.clojure/clojure "1.8.0"] 6 | [org.clojure/clojurescript "1.8.51"] 7 | [thi.ng/strf "0.2.2"] 8 | [reagent "0.5.1"]] 9 | 10 | :plugins [[lein-figwheel "0.5.4-3"] 11 | [lein-cljsbuild "1.1.3" :exclusions [[org.clojure/clojure]]]] 12 | 13 | :clean-targets ^{:protect false} ["resources/public/js" "target"] 14 | 15 | :cljsbuild {:builds 16 | [{:source-paths ["src"] 17 | :id "dev" 18 | :compiler {:optimizations :simple 19 | :pretty-print true 20 | :output-to "resources/public/js/main.js" 21 | :modules {:cljs-base {:output-to "resources/public/js/base.js"} 22 | :app {:output-to "resources/public/js/app.js" 23 | :entries #{"ex05.core"}} 24 | :worker {:output-to "resources/public/js/worker.js" 25 | :entries #{"worker"} 26 | ;;:depends-on #{} 27 | }}}} 28 | {:source-paths ["src"] 29 | :id "prod" 30 | :compiler {:optimizations :advanced 31 | :output-to "resources/public/js/main.js" 32 | :modules {:cljs-base {:output-to "resources/public/js/base.js"} 33 | :app {:output-to "resources/public/js/app.js" 34 | :entries #{"ex05.core"}} 35 | :worker {:output-to "resources/public/js/worker.js" 36 | :entries #{"worker"}}}}} 37 | ]}) 38 | -------------------------------------------------------------------------------- /ws-ldn-11/day2/ex05/resources/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 |
11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /ws-ldn-11/day2/ex05/resources/public/js/main.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thi-ng/demos/048cd131099a7db29be56b965c053908acad4166/ws-ldn-11/day2/ex05/resources/public/js/main.js -------------------------------------------------------------------------------- /ws-ldn-11/day2/ex05/resources/public/js/worker.js: -------------------------------------------------------------------------------- 1 | var worker = {}; 2 | self.importScripts("base.js"); 3 | worker.state = cljs.core.atom.call(null, cljs.core.PersistentArrayMap.EMPTY); 4 | worker.start_ping = function worker$start_ping(b) { 5 | setTimeout(function() { 6 | var c = (new Uint8Array(1E7)).buffer, d = thi.ng.strf.core.timestamp.call(null); 7 | self.postMessage([d, c, [cljs.core.str("Worker running ("), cljs.core.str(thi.ng.strf.core.now.call(null)), cljs.core.str(")")].join("")], [c]); 8 | return cljs.core.truth_((new cljs.core.Keyword(null, "active?", "active?", 459499776)).cljs$core$IFn$_invoke$arity$1(cljs.core.deref.call(null, worker.state))) ? worker$start_ping.call(null, b) : null; 9 | }, b); 10 | return cljs.core.swap_BANG_.call(null, worker.state, cljs.core.assoc, new cljs.core.Keyword(null, "active?", "active?", 459499776), !0); 11 | }; 12 | worker.stop_ping = function() { 13 | return cljs.core.swap_BANG_.call(null, worker.state, cljs.core.assoc, new cljs.core.Keyword(null, "active?", "active?", 459499776), !1); 14 | }; 15 | worker.dispatch_command = function(a) { 16 | a = cljs.reader.read_string.call(null, a.data); 17 | switch(cljs.core.keyword.call(null, (new cljs.core.Keyword(null, "command", "command", -894540724)).cljs$core$IFn$_invoke$arity$1(a)) instanceof cljs.core.Keyword ? cljs.core.keyword.call(null, (new cljs.core.Keyword(null, "command", "command", -894540724)).cljs$core$IFn$_invoke$arity$1(a)).fqn : null) { 18 | case "start": 19 | return worker.start_ping.call(null, (new cljs.core.Keyword(null, "interval", "interval", 1708495417)).cljs$core$IFn$_invoke$arity$1(a)); 20 | case "stop": 21 | return worker.stop_ping.call(null); 22 | default: 23 | return console.warn([cljs.core.str("unknown worker command: "), cljs.core.str((new cljs.core.Keyword(null, "command", "command", -894540724)).cljs$core$IFn$_invoke$arity$1(a))].join("")); 24 | } 25 | }; 26 | self.onmessage = worker.dispatch_command; 27 | -------------------------------------------------------------------------------- /ws-ldn-11/day2/ex05/src/ex05/core.cljs: -------------------------------------------------------------------------------- 1 | (ns ex05.core 2 | (:require-macros 3 | [reagent.ratom :refer [reaction]]) 4 | (:require 5 | [reagent.core :as r] 6 | [thi.ng.strf.core :as f])) 7 | 8 | (def app (r/atom {})) 9 | 10 | (enable-console-print!) 11 | 12 | (defn update-worker-state 13 | "Callback handler for worker messages." 14 | [msg] 15 | (let [[t0 buf msg] (.-data msg) 16 | t (f/timestamp) 17 | delta (- t t0) 18 | buf (js/Uint8Array. buf) 19 | data {:delta delta :buf-len (.-length buf) :msg msg}] 20 | (swap! app assoc :worker-msg data))) 21 | 22 | (defn start-worker 23 | "Handler to send :start command to worker, enables 24 | :worker-active key in app state." 25 | [] 26 | (.postMessage 27 | (:worker @app) 28 | (pr-str {:command :start :interval 1000})) 29 | (swap! app assoc :worker-msg nil :worker-active true)) 30 | 31 | (defn stop-worker 32 | "Handler to send :stop command to worker, disables :worker-active 33 | key in app state atom." 34 | [] 35 | (.postMessage 36 | (:worker @app) 37 | (pr-str {:command :stop})) 38 | (swap! app assoc :worker-active false)) 39 | 40 | (defn app-component 41 | "Main reagent app component" 42 | [] 43 | (let [msg (reaction (:worker-msg @app)) 44 | active? (reaction (:worker-active @app))] 45 | (fn [] 46 | [:div 47 | [:h1 "Worker example"] 48 | (if @active? 49 | [:div 50 | [:p "Latest message from worker:"] 51 | [:p (if @msg 52 | [:textarea 53 | {:cols 60 54 | :rows 5 55 | :value (pr-str @msg)}] 56 | "Waiting...")] 57 | [:p [:button {:on-click stop-worker} "Stop"]]] 58 | [:div 59 | [:p "Worker idle..."] 60 | [:button {:on-click start-worker} "Start"]])]))) 61 | 62 | (defn init-app 63 | "Initializes worker & stores handle in app state atom." 64 | [] 65 | (let [worker (js/Worker. "js/worker.js")] 66 | (set! (.-onmessage worker) update-worker-state) 67 | (reset! app {:worker worker}))) 68 | 69 | (defn main 70 | [] 71 | (init-app) 72 | (r/render-component [app-component] (.-body js/document))) 73 | 74 | (main) 75 | -------------------------------------------------------------------------------- /ws-ldn-11/day2/ex05/src/ex05/worker.cljs: -------------------------------------------------------------------------------- 1 | (ns worker 2 | (:require 3 | [thi.ng.strf.core :as f] 4 | [cljs.reader :refer [read-string]])) 5 | 6 | ;; base.js contains all of cljs.core etc. 7 | (.importScripts js/self "base.js") 8 | 9 | ;; worker's app state 10 | (def state (atom {})) 11 | 12 | (defn start-ping 13 | "Command handler to start (and keep) pinging main app with given 14 | interval. Pinging stops when :active? key is false." 15 | [delay] 16 | (js/setTimeout 17 | (fn [] 18 | (let [buf (.-buffer (js/Uint8Array. 1e7)) 19 | t (f/timestamp)] 20 | (.postMessage 21 | js/self 22 | #js [t buf (str "Worker running (" (f/now) ")")] 23 | #js [buf])) 24 | (when (:active? @state) 25 | (start-ping delay))) 26 | delay) 27 | (swap! state assoc :active? true)) 28 | 29 | (defn stop-ping 30 | "Command handler to stop pinging main app." 31 | [] (swap! state assoc :active? false)) 32 | 33 | (defn dispatch-command 34 | "Worker's onmessage handler. Decodes message as EDN and dispatches 35 | to command handlers based on :command key in message." 36 | [msg] 37 | (let [msg (read-string (.-data msg))] 38 | (case (keyword (:command msg)) 39 | :start (start-ping (:interval msg)) 40 | :stop (stop-ping) 41 | (.warn js/console (str "unknown worker command: " (:command msg)))))) 42 | 43 | (set! (.-onmessage js/self) dispatch-command) 44 | -------------------------------------------------------------------------------- /ws-ldn-11/day2/ex05b/README.org: -------------------------------------------------------------------------------- 1 | * WebWorker example 2 | 3 | ** Building 4 | 5 | #+BEGIN_SRC shell 6 | lein do clean, cljsbuild once min && node postprocess.js 7 | 8 | python -m SimpleHTTPServer 9 | #+END_SRC 10 | 11 | Then go to: http://localhost:8000/resources/public/ 12 | -------------------------------------------------------------------------------- /ws-ldn-11/day2/ex05b/postprocess.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs'); 2 | var path = 'resources/public/js/meshworker.js'; 3 | var include = 'self.importScripts("base.js");'; 4 | src = include + fs.readFileSync(path,'utf8').replace(include, ''); 5 | fs.writeFileSync(path, src, 'utf8'); 6 | -------------------------------------------------------------------------------- /ws-ldn-11/day2/ex05b/project.clj: -------------------------------------------------------------------------------- 1 | (defproject ws-ldn-11-ex05b "0.1.0-SNAPSHOT" 2 | :description "FIXME: write description" 3 | :url "http://example.com/FIXME" 4 | 5 | :dependencies [[org.clojure/clojure "1.8.0"] 6 | [org.clojure/clojurescript "1.8.51"] 7 | [thi.ng/geom "0.0.1178-SNAPSHOT"] 8 | [reagent "0.5.1"]] 9 | 10 | :plugins [[lein-figwheel "0.5.4-3"] 11 | [lein-cljsbuild "1.1.3" :exclusions [[org.clojure/clojure]]]] 12 | 13 | :clean-targets ^{:protect false} ["resources/public/js/compiled/" "target"] 14 | 15 | :cljsbuild {:builds 16 | [{:id "fig-gl" 17 | :source-paths ["src"] 18 | :figwheel true 19 | :compiler {:main ex05b.core 20 | :asset-path "js/compiled/out" 21 | :output-to "resources/public/js/compiled/app.js" 22 | :output-dir "resources/public/js/compiled/out" 23 | :source-map-timestamp true}} 24 | {:source-paths ["src"] 25 | :id "dev" 26 | :compiler {:optimizations :simple 27 | :pretty-print true 28 | :output-to "resources/public/js/dummy.js" 29 | :modules {:cljs-base {:output-to "resources/public/js/base.js"} 30 | :app {:output-to "resources/public/js/compiled/app.js" 31 | :entries #{"ex05b.core"}} 32 | :meshworker {:output-to "resources/public/js/meshworker.js" 33 | :entries #{"meshworker"}}}}} 34 | {:source-paths ["src"] 35 | :id "min" 36 | :compiler {:optimizations :advanced 37 | :pretty-print false 38 | :output-to "resources/public/js/dummy.js" 39 | :modules {:cljs-base {:output-to "resources/public/js/base.js"} 40 | :app {:output-to "resources/public/js/compiled/app.js" 41 | :entries #{"ex05b.core"}} 42 | :meshworker {:output-to "resources/public/js/meshworker.js" 43 | :entries #{"meshworker"}}}}}]}) 44 | -------------------------------------------------------------------------------- /ws-ldn-11/day2/ex05b/resources/public/assets/deadpool.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thi-ng/demos/048cd131099a7db29be56b965c053908acad4166/ws-ldn-11/day2/ex05b/resources/public/assets/deadpool.stl -------------------------------------------------------------------------------- /ws-ldn-11/day2/ex05b/resources/public/assets/suzanne.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thi-ng/demos/048cd131099a7db29be56b965c053908acad4166/ws-ldn-11/day2/ex05b/resources/public/assets/suzanne.stl -------------------------------------------------------------------------------- /ws-ldn-11/day2/ex05b/resources/public/assets/voxel.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thi-ng/demos/048cd131099a7db29be56b965c053908acad4166/ws-ldn-11/day2/ex05b/resources/public/assets/voxel.stl -------------------------------------------------------------------------------- /ws-ldn-11/day2/ex05b/resources/public/css/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | padding: 0; 4 | overflow: hidden; 5 | background-color: black; 6 | } -------------------------------------------------------------------------------- /ws-ldn-11/day2/ex05b/resources/public/figwheel.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /ws-ldn-11/day2/ex05b/resources/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 |
11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /ws-ldn-11/day2/ex05b/src/ex05b/meshworker.cljs: -------------------------------------------------------------------------------- 1 | (.importScripts js/self "base.js") 2 | 3 | (ns meshworker 4 | (:require-macros 5 | [cljs-log.core :refer [debug info warn]]) 6 | (:require 7 | [thi.ng.math.core :as m] 8 | [thi.ng.geom.core :as g] 9 | [thi.ng.geom.matrix :as mat] 10 | [thi.ng.geom.mesh.io :as mio] 11 | [thi.ng.geom.gl.glmesh :as glm] 12 | [thi.ng.strf.core :as f])) 13 | 14 | (defn load-binary 15 | [uri onload onerror] 16 | (let [xhr (js/XMLHttpRequest.)] 17 | (.open xhr "GET" uri true) 18 | (set! (.-responseType xhr) "arraybuffer") 19 | (set! (.-onload xhr) 20 | (fn [e] 21 | (if-let [buf (.-response xhr)] 22 | (onload buf) 23 | (when onerror (onerror xhr e))))) 24 | (.send xhr))) 25 | 26 | (defn build-mesh 27 | [buf] 28 | (let [t0 (f/timestamp) 29 | mesh (mio/read-stl 30 | (mio/wrapped-input-stream buf) 31 | #(glm/gl-mesh % #{:fnorm})) 32 | bounds (g/bounds mesh) 33 | tx (-> mat/M44 34 | (g/scale (/ 1.0 (-> bounds :size :y))) 35 | (g/translate (m/- (g/centroid bounds)))) 36 | vertices (-> mesh .-vertices .-buffer) 37 | fnormals (-> mesh .-fnormals .-buffer) 38 | num (.-id mesh)] 39 | (debug (- (f/timestamp) t0) "ms," num "triangles") 40 | (.postMessage 41 | js/self 42 | #js [vertices fnormals num tx] 43 | #js [vertices fnormals]))) 44 | 45 | (defn load-mesh 46 | [msg] 47 | (load-binary 48 | (.-data msg) 49 | build-mesh 50 | #(warn "error loading mesh: " (.-data msg)))) 51 | 52 | (set! (.-onmessage js/self) load-mesh) 53 | -------------------------------------------------------------------------------- /ws-ldn-11/day2/ex06/project.clj: -------------------------------------------------------------------------------- 1 | (defproject ws-ldn-11-ex06 "0.1.0-SNAPSHOT" 2 | :description "thi.ng Clojurescript workshop WS-LDN-11" 3 | :url "http://workshop.thi.ng" 4 | 5 | :min-lein-version "2.5.3" 6 | 7 | :dependencies [[org.clojure/clojure "1.8.0"] 8 | [org.clojure/clojurescript "1.8.51"] 9 | [org.clojure/core.async "0.2.374" 10 | :exclusions [org.clojure/tools.reader]] 11 | [thi.ng/geom "0.0.1178-SNAPSHOT"] 12 | [thi.ng/domus "0.3.0-SNAPSHOT"] 13 | [reagent "0.5.1"]] 14 | 15 | :plugins [[lein-figwheel "0.5.4-3"] 16 | [lein-cljsbuild "1.1.3" :exclusions [[org.clojure/clojure]]]] 17 | 18 | :source-paths ["src"] 19 | 20 | :clean-targets ^{:protect false} ["resources/public/js/compiled" "target"] 21 | 22 | :cljsbuild {:builds 23 | [{:id "dev" 24 | :source-paths ["src"] 25 | :figwheel true 26 | :compiler {:main ex06.core 27 | :asset-path "js/compiled/out" 28 | :output-to "resources/public/js/compiled/app.js" 29 | :output-dir "resources/public/js/compiled/out" 30 | :source-map-timestamp true}} 31 | {:id "min" 32 | :source-paths ["src"] 33 | :compiler {:output-to "resources/public/js/compiled/app.js" 34 | :optimizations :advanced 35 | :pretty-print false}}]} 36 | 37 | :figwheel {:css-dirs ["resources/public/css"] 38 | ;; :ring-handler hello_world.server/handler 39 | }) 40 | -------------------------------------------------------------------------------- /ws-ldn-11/day2/ex06/resources/public/css/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: Helvetica,Arial,sans-serif; 3 | margin: 0; 4 | padding: 0; 5 | overflow: hidden; 6 | background-color: black; 7 | color: white; 8 | } 9 | 10 | #ui { 11 | position: fixed; 12 | top: 10px; 13 | left: 10px; 14 | z-index: 1; 15 | } -------------------------------------------------------------------------------- /ws-ldn-11/day2/ex06/resources/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 |
12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /ws-ldn-11/day2/ex06/src/ex06/core.cljs: -------------------------------------------------------------------------------- 1 | (ns ex06.core 2 | (:require-macros 3 | [reagent.ratom :refer [reaction]] 4 | [cljs-log.core :refer [debug info warn severe]]) 5 | (:require 6 | [ex06.main :as main] 7 | [thi.ng.geom.gl.webgl.animator :as anim] 8 | [thi.ng.domus.core :as dom] 9 | [reagent.core :as reagent])) 10 | 11 | (enable-console-print!) 12 | 13 | (defn canvas-component 14 | [props] 15 | (reagent/create-class 16 | {:component-did-mount 17 | (fn [this] 18 | (reagent/set-state this {:active true}) 19 | ((:init props) this) 20 | (anim/animate ((:loop props) this))) 21 | :component-will-unmount 22 | (fn [this] 23 | (debug "unmount GL") 24 | (reagent/set-state this {:active false})) 25 | :reagent-render 26 | (fn [_] 27 | [:canvas 28 | (merge 29 | {:width (.-innerWidth js/window) 30 | :height (.-innerHeight js/window)} 31 | props)])})) 32 | 33 | (defn rtc-status 34 | [] 35 | (let [status (reaction (-> @main/app :stream :state))] 36 | (fn [] 37 | [:div#rtc-status "Stream status: " (name @status)]))) 38 | 39 | (defn shader-selector 40 | [] 41 | (let [shaders (reaction (-> @main/app :shaders)) 42 | curr (reaction (-> @main/app :curr-shader))] 43 | (fn [] 44 | (when @shaders 45 | [:select {:default-value (name @curr) 46 | :on-change #(main/set-shader! (-> % .-target .-value))} 47 | (for [s (sort (keys @shaders)) :let [s (name s)]] 48 | [:option {:key s :value s} s])])))) 49 | 50 | (defn controls 51 | [] 52 | [:div#ui 53 | [rtc-status] 54 | [shader-selector]]) 55 | 56 | (defn app-component 57 | [] 58 | [:div 59 | [canvas-component {:init main/init-app :loop main/update-app}] 60 | [controls]]) 61 | 62 | (defn main 63 | [] 64 | (.initializeTouchEvents js/React) 65 | (reagent/render-component [app-component] (dom/by-id "app"))) 66 | 67 | (main) 68 | -------------------------------------------------------------------------------- /ws-ldn-11/day3/ex07/compile.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # This compiles the file particles.c with optimizations, 4 | # declares a number of exported function names, 5 | # post-processes the resulting JS with Closure compiler and 6 | # wraps all within a global 'Particles' module/object 7 | # This module MUST be initialized by calling 'Particles();' 8 | # before first use (in our example this is done from CLJS in ex07.core/main) 9 | 10 | emcc -O2 -s ASM_JS=1 -s INVOKE_RUN=0 \ 11 | -s EXPORTED_FUNCTIONS="['_main','_initParticleSystem','_updateParticleSystem','_getNumParticles','_getParticleComponent','_getParticlesPointer']" \ 12 | -s "EXPORT_NAME='Particles'" \ 13 | -s MODULARIZE=1 \ 14 | --memory-init-file 0 \ 15 | --closure 1 \ 16 | -o resources/public/js/native.js \ 17 | particles.c 18 | 19 | # copy memory initialization file to main webroot dir 20 | # cp resources/public/js/native.js.mem resources/public/ 21 | -------------------------------------------------------------------------------- /ws-ldn-11/day3/ex07/externs.js: -------------------------------------------------------------------------------- 1 | var Module = {}; 2 | 3 | Module.ccall = function() {}; 4 | Module.cwrap = function() {}; 5 | -------------------------------------------------------------------------------- /ws-ldn-11/day3/ex07/memory.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thi-ng/demos/048cd131099a7db29be56b965c053908acad4166/ws-ldn-11/day3/ex07/memory.png -------------------------------------------------------------------------------- /ws-ldn-11/day3/ex07/project.clj: -------------------------------------------------------------------------------- 1 | (defproject ws-ldn-8-ex07 "0.1.0-SNAPSHOT" 2 | :description "thi.ng Clojurescript workshop WS-LDN-8" 3 | :url "http://workshop.thi.ng" 4 | :license {:name "Eclipse Public License" 5 | :url "http://www.eclipse.org/legal/epl-v10.html"} 6 | 7 | :min-lein-version "2.5.3" 8 | 9 | :dependencies [[org.clojure/clojure "1.8.0"] 10 | [org.clojure/clojurescript "1.8.51"] 11 | [org.clojure/core.async "0.2.374" 12 | :exclusions [org.clojure/tools.reader]] 13 | [thi.ng/geom "0.0.1178-SNAPSHOT"] 14 | [thi.ng/domus "0.3.0-SNAPSHOT"] 15 | [reagent "0.5.1"]] 16 | 17 | :plugins [[lein-figwheel "0.5.4-3"] 18 | [lein-cljsbuild "1.1.3" :exclusions [[org.clojure/clojure]]]] 19 | 20 | :source-paths ["src"] 21 | 22 | :clean-targets ^{:protect false} ["resources/public/js/compiled" "target"] 23 | 24 | :cljsbuild {:builds 25 | [{:id "dev" 26 | :source-paths ["src"] 27 | :figwheel true 28 | :compiler {:main ex07.core 29 | :asset-path "js/compiled/out" 30 | :output-to "resources/public/js/compiled/app.js" 31 | :output-dir "resources/public/js/compiled/out" 32 | :source-map-timestamp true}} 33 | {:id "min" 34 | :source-paths ["src"] 35 | :compiler {:output-to "resources/public/js/compiled/app.js" 36 | :optimizations :advanced 37 | :externs ["externs.js"]}}]} 38 | 39 | :figwheel {:css-dirs ["resources/public/css"] 40 | ;; :ring-handler hello_world.server/handler 41 | }) 42 | -------------------------------------------------------------------------------- /ws-ldn-11/day3/ex07/resources/public/css/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: Helvetica,Arial,sans-serif; 3 | margin: 0; 4 | padding: 0; 5 | overflow: hidden; 6 | background-color: black; 7 | color: white; 8 | } 9 | 10 | #ui { 11 | position: fixed; 12 | top: 10px; 13 | left: 10px; 14 | z-index: 1; 15 | } -------------------------------------------------------------------------------- /ws-ldn-11/day3/ex07/resources/public/img/tex32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thi-ng/demos/048cd131099a7db29be56b965c053908acad4166/ws-ldn-11/day3/ex07/resources/public/img/tex32.png -------------------------------------------------------------------------------- /ws-ldn-11/day3/ex07/resources/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 |
12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /ws-ldn-11/day3/ex07/resources/public/js/empty: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thi-ng/demos/048cd131099a7db29be56b965c053908acad4166/ws-ldn-11/day3/ex07/resources/public/js/empty -------------------------------------------------------------------------------- /ws-ldn-2/README.md: -------------------------------------------------------------------------------- 1 | # Clojure/Clojurescript workshop 2 | 3 | (WS-LDN-2) 4 | 5 | This repo contains a subset of commented examples created during the workshop. 6 | 7 | ## Report 8 | 9 | - [workshop report](https://medium.com/@thi.ng/workshop-report-building-linked-data-heatmaps-with-clojurescript-thi-ng-102e0581225c) - a slightly wordy (3k) report with lots of references 10 | - [notes & further reading links](workshop.org) 11 | 12 | ## Example app 13 | 14 | We used geographic data from the 15 | [ONS linked data portal](http://statistics.data.gov.uk/) and sampled & 16 | converted housing datasets from the 17 | [London Data Store](http://data.london.gov.uk/dataset/average-house-prices-borough) 18 | to RDF in order to build heatmap visualizations of the London housing 19 | situation. 20 | 21 | The project also is a nice demo combining features of several 22 | libraries of the thi.ng collection, incl. 23 | [thi.ng/fabric](http://thi.ng/fabric), [thi.ng/geom](thi.ng/geom), 24 | [thi.ng/color](http://thi.ng/color)... 25 | 26 | This heatmap shows average property sale prices per borough in 2013/14: 27 | 28 | ![London house prices 2013/14](assets/ldn-heatmap.jpg) 29 | 30 | This heatmap is based on the number of property sales, showing a clear bias in the south east: 31 | 32 | ![London house sales (count) 2013/14](assets/ldn-heatmap-count.jpg) 33 | 34 | The example app also includes an in-browser query editor (using 35 | [CodeMirror](http://codemirror.net)) with result table display and 36 | query structure visualization. 37 | 38 | ## Running the project 39 | 40 | ``` 41 | git clone https://github.com/thi-ng/ws-ldn-2.git 42 | cd ws-ldn-2 43 | lein trampoline run 44 | 45 | # open another terminal using same directory 46 | lein figwheel dev 47 | 48 | # once fabric server is running CLJS compilation is complete... 49 | # open http://localhost:8000 in your browser 50 | ``` 51 | 52 | ## CLJS build w/ advanced optimizations 53 | 54 | Run the following command to build the CLJS sources with advanced 55 | optimizations. The `with-profile prod` ensures that all logging 56 | messages are elided from the source at compile time. 57 | 58 | ``` 59 | lein with-profile prod do clean, cljsbuild once min 60 | ``` 61 | 62 | ## License 63 | 64 | Copyright © 2015 Karsten Schmidt 65 | 66 | Distributed under the Apache Software License either version 1.0 or (at your option) any later version. 67 | -------------------------------------------------------------------------------- /ws-ldn-2/assets/ldn-heatmap-count.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thi-ng/demos/048cd131099a7db29be56b965c053908acad4166/ws-ldn-2/assets/ldn-heatmap-count.jpg -------------------------------------------------------------------------------- /ws-ldn-2/assets/ldn-heatmap.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thi-ng/demos/048cd131099a7db29be56b965c053908acad4166/ws-ldn-2/assets/ldn-heatmap.jpg -------------------------------------------------------------------------------- /ws-ldn-2/resources/data/london-boroughs.nt.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thi-ng/demos/048cd131099a7db29be56b965c053908acad4166/ws-ldn-2/resources/data/london-boroughs.nt.gz -------------------------------------------------------------------------------- /ws-ldn-2/resources/data/london-sales-2013-2014.csv.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thi-ng/demos/048cd131099a7db29be56b965c053908acad4166/ws-ldn-2/resources/data/london-sales-2013-2014.csv.gz -------------------------------------------------------------------------------- /ws-ldn-2/resources/data/queries.edn: -------------------------------------------------------------------------------- 1 | ;; queries added to compute graph on system start 2 | ;; results for these queries are automatically updating whenever their 3 | ;; matching fact sets are changing... 4 | {"boroughs" 5 | {:prefixes {"sg" "http://statistics.data.gov.uk/def/statistical-geography#"} 6 | :q [{:where [[?s "rdf:type" "schema:SellAction"] 7 | [?s "schema:price" ?price] 8 | ;;[?s "schema:purchaseDate" ?date] 9 | ;;[?s "schema:postalCode" ?zip] 10 | [?s "ws:onsID" ?boroughID] 11 | [?borough "rdfs:label" ?boroughID] 12 | [?borough "sg:officialName" ?name] 13 | [?borough "sg:hasExteriorLatLongPolygon" ?poly]]}] 14 | :aggregate {?num (agg-count ?s) 15 | ?avg (agg-avg ?price) 16 | ?min (agg-min ?price) 17 | ?max (agg-max ?price) 18 | ?apoly (agg-collect ?poly) 19 | ?aname (agg-collect ?name)} 20 | :group-by ?boroughID 21 | :select [?boroughID ?apoly ?avg ?min ?max ?num ?aname]} 22 | 23 | "borough-prices" 24 | {:prefixes {"sg" "http://statistics.data.gov.uk/def/statistical-geography#"} 25 | :q [{:where [[?s "rdf:type" "schema:SellAction"] 26 | [?s "schema:price" ?price] 27 | [?s "schema:purchaseDate" ?date] 28 | [?s "ws:onsID" ?boroughID] 29 | [?borough "rdfs:label" ?boroughID]]}] 30 | :group-by ?boroughID 31 | :order ?date 32 | :select [?price ?date]}} 33 | -------------------------------------------------------------------------------- /ws-ldn-2/resources/data/sales-2013.edn.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thi-ng/demos/048cd131099a7db29be56b965c053908acad4166/ws-ldn-2/resources/data/sales-2013.edn.gz -------------------------------------------------------------------------------- /ws-ldn-2/resources/public/css/cm-material.css: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Name: material 4 | Author: Michael Kaminsky (http://github.com/mkaminsky11) 5 | 6 | Original material color scheme by Mattia Astorino (https://github.com/equinusocio/material-theme) 7 | 8 | */ 9 | 10 | .cm-s-material { 11 | background-color: #263238; 12 | color: rgba(233, 237, 237, 1); 13 | } 14 | .cm-s-material .CodeMirror-gutters { 15 | background: #263238; 16 | color: rgb(83,127,126); 17 | border: none; 18 | } 19 | .cm-s-material .CodeMirror-guttermarker, .cm-s-material .CodeMirror-guttermarker-subtle, .cm-s-material .CodeMirror-linenumber { color: rgb(83,127,126); } 20 | .cm-s-material .CodeMirror-cursor { border-left: 1px solid #f8f8f0; } 21 | .cm-s-material div.CodeMirror-selected { background: rgba(255, 255, 255, 0.15); } 22 | .cm-s-material.CodeMirror-focused div.CodeMirror-selected { background: rgba(255, 255, 255, 0.10); } 23 | .cm-s-material .CodeMirror-line::selection, .cm-s-material .CodeMirror-line > span::selection, .cm-s-material .CodeMirror-line > span > span::selection { background: rgba(255, 255, 255, 0.10); } 24 | .cm-s-material .CodeMirror-line::-moz-selection, .cm-s-material .CodeMirror-line > span::-moz-selection, .cm-s-material .CodeMirror-line > span > span::-moz-selection { background: rgba(255, 255, 255, 0.10); } 25 | 26 | .cm-s-material .CodeMirror-activeline-background { background: rgba(0, 0, 0, 0); } 27 | .cm-s-material .cm-keyword { color: rgba(199, 146, 234, 1); } 28 | .cm-s-material .cm-operator { color: rgba(233, 237, 237, 1); } 29 | .cm-s-material .cm-variable-2 { color: #80CBC4; } 30 | .cm-s-material .cm-variable-3 { color: #82B1FF; } 31 | .cm-s-material .cm-builtin { color: #DECB6B; } 32 | .cm-s-material .cm-atom { color: #F77669; } 33 | .cm-s-material .cm-number { color: #F77669; } 34 | .cm-s-material .cm-def { color: rgba(233, 237, 237, 1); } 35 | .cm-s-material .cm-error { 36 | color: rgba(255, 255, 255, 1.0); 37 | background-color: #EC5F67; 38 | } 39 | .cm-s-material .cm-string { color: #C3E88D; } 40 | .cm-s-material .cm-string-2 { color: #80CBC4; } 41 | .cm-s-material .cm-comment { color: #546E7A; } 42 | .cm-s-material .cm-variable { color: #82B1FF; } 43 | .cm-s-material .cm-tag { color: #80CBC4; } 44 | .cm-s-material .cm-meta { color: #80CBC4; } 45 | .cm-s-material .cm-attribute { color: #FFCB6B; } 46 | .cm-s-material .cm-property { color: #80CBAE; } 47 | .cm-s-material .cm-qualifier { color: #DECB6B; } 48 | .cm-s-material .cm-variable-3 { color: #DECB6B; } 49 | .cm-s-material .cm-tag { color: rgba(255, 83, 112, 1); } 50 | .cm-s-material .CodeMirror-matchingbracket { 51 | text-decoration: underline; 52 | color: white !important; 53 | } 54 | -------------------------------------------------------------------------------- /ws-ldn-2/resources/public/css/site.css: -------------------------------------------------------------------------------- 1 | .CodeMirror { 2 | font-family: "Inconsolata",Menlo,monospace !important; 3 | margin-bottom: 1em; 4 | height: 400px; 5 | } 6 | 7 | .fullwidth { 8 | max-width: 100%; 9 | } 10 | 11 | .form-align { 12 | margin-top: 24px; 13 | } 14 | 15 | table.query-results { 16 | font-size: 11px; 17 | } -------------------------------------------------------------------------------- /ws-ldn-2/resources/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

Loading...

15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /ws-ldn-2/src/clj/ws_ldn_2/async.clj: -------------------------------------------------------------------------------- 1 | (ns ws-ldn-2.async 2 | (:require 3 | [clojure.core.async :as a :refer [go go-loop ! timeout]])) 4 | 5 | (defn topology1 6 | "Basic mult example" 7 | [] 8 | (let [in (a/chan) 9 | m (a/mult in) 10 | t-chans (repeatedly 5 #(a/chan))] 11 | (doseq [[id c] (zipmap (range) t-chans)] 12 | (a/tap m c) 13 | (go-loop [] 14 | (let [x (! o (f x)) 39 | (recur)) 40 | (prn :done))))) 41 | {:in in 42 | :mult m 43 | :taps t-chans 44 | :outs o-chans})) 45 | 46 | 47 | ;; (zipmap (range) (take (count fns) (repeatedly ...))) 48 | ;; (partition 3 (interleave (range) (repeatedly a/chan) [f1 f2 f3])) 49 | -------------------------------------------------------------------------------- /ws-ldn-2/src/clj/ws_ldn_2/utils.clj: -------------------------------------------------------------------------------- 1 | (ns ws-ldn-2.utils) 2 | 3 | (defn deep-merge 4 | "Merge fn to be used with `merge-with`. Recursively merges map 5 | values which are maps or seqs (for the latter `into` is used). If 6 | the RHS value has the metadata key :replace set, it is used as new 7 | value without merging." 8 | [l r] 9 | (cond 10 | (:replace (meta r)) r 11 | (or (sequential? l) (set? l)) (into l r) 12 | (map? l) (merge-with deep-merge l r) 13 | :else r)) 14 | 15 | (comment 16 | ;; example usage 17 | (merge-with deep-merge 18 | {:a 23 :b {"c" 42} :d ["e"] :f ["f"]} 19 | {:a2 42 :b {"c2" 66} :d ["e2"] :f ^:replace ["f2"]}) 20 | 21 | ;; {:a 23 22 | ;; :b {"c" 42, "c2" 66} ;; merged 23 | ;; :d ["e" "e2"] ;; merged 24 | ;; :f ["f2"] ;; replaced 25 | ;; :a2 42} 26 | ) 27 | -------------------------------------------------------------------------------- /ws-ldn-2/src/cljs/ws_ldn_2/components/dropdown.cljs: -------------------------------------------------------------------------------- 1 | (ns ws-ldn-2.components.dropdown) 2 | 3 | (defn dropdown 4 | "Dropdown component. Takes a react component key, currently selected 5 | value, on-change handler and a map of menu items, where keys are 6 | used as the