Skip to content

Commit

Permalink
Chapter 0, Examples 1 and 2
Browse files Browse the repository at this point in the history
  • Loading branch information
Ramblurr committed May 27, 2024
1 parent edf5e5f commit ccc4e2d
Show file tree
Hide file tree
Showing 10 changed files with 212 additions and 65 deletions.
21 changes: 21 additions & 0 deletions dev/noc/chapter_0_1.cljs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
(ns noc.chapter-0-1
(:require [quil.core :as q]))

(def sketch
{:size [640 240]
:setup (fn []
(q/background 255)
{:walker {:x (quot (q/width) 2)
:y (quot (q/height) 2)}})
:tick (fn [{:keys [walker] :as state}]
(let [choice (Math/floor (q/random 4))
{:keys [x y]} walker]
(assoc state :walker
(condp = choice
0 {:x (inc x) :y y}
1 {:x (dec x) :y y}
2 {:x x :y (inc y)}
3 {:x x :y (dec y)}))))
:draw (fn [{:keys [walker]}]
(q/stroke 0)
(q/point (:x walker) (:y walker)))})
22 changes: 22 additions & 0 deletions dev/noc/chapter_0_2.cljs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
(ns noc.chapter-0-2
(:require [quil.core :as q]))

(def sketch
{:size [640 240]
:setup (fn []
{:counts (into [] (repeat 20 0))})

:tick (fn [{:keys [counts] :as state}]
(let [idx (Math/floor (q/random (count counts)))]
(update-in state [:counts idx] inc)))

:draw (fn [{:keys [counts]}]
(q/background 255)
(q/stroke 0)
(q/fill 127)
(let [w (quot (q/width) (count counts))]
(doseq [[idx v] (map-indexed vector counts)]
(q/rect (* idx w)
(- (q/height) v)
(dec w)
v))))})
32 changes: 0 additions & 32 deletions dev/noc/custom.cljs

This file was deleted.

65 changes: 58 additions & 7 deletions dev/noc/render.cljs
Original file line number Diff line number Diff line change
@@ -1,11 +1,62 @@
(ns noc.render
(:require
[noc.custom]))
[noc.sketch]))

(def icon-reset [:svg
{:stroke "currentColor",
:aria-hidden "true",
:fill "none",
:width "1em",
:xmlns "http://www.w3.org/2000/svg",
:stroke-width "2",
:class "h-[15px] w-[15px]",
:viewBox "0 0 24 24",
:height "1em"}
[:path
{:stroke-linecap "round",
:stroke-linejoin "round",
:d
"M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"}]])

(def icon-pause
[:svg
{:stroke "currentColor",
:aria-hidden "true",
:fill "none",
:width "1em",
:xmlns "http://www.w3.org/2000/svg",
:stroke-width "2",
:class "h-4 w-4",
:viewBox "0 0 24 24",
:height "1em"}
[:path
{:stroke-linecap "round",
:stroke-linejoin "round",
:d "M10 9v6m4-6v6m7-3a9 9 0 11-18 0 9 9 0 0118 0z"}]])

(defn render-quil-sketch [sketch]
(if (noc.custom/has-sketch? sketch)
[:div {:ref (fn [el]
(prn sketch)
(when el
(noc.custom/load-sketch sketch el)))}]
[:div (str "No sketch named " sketch "found")]))
(let [sketch-opts (noc.sketch/load-sketch sketch)
applet* (atom nil)]
[:div {:class "clear-both my-4 overflow-hidden rounded border bg-gray-100"}
[:div {:class "relative overflow-hidden rounded-t bg-white"}
(if sketch-opts
[:div {:class "w-full border-none transition-opacity opacity-100"
:ref (fn [el]
(prn sketch)
(when el
(reset! applet* (noc.sketch/show-sketch sketch-opts el))))}]
[:div (str "No sketch named " sketch " found")])]
[:div {:class "flex items-center justify-between border-t"}
[:div
{:class "flex"}
[:button {:class "flex items-center border-r px-2.5 py-1.5 text-sm hover:bg-gray-200"
:on-click (fn [_]
(noc.sketch/reset applet*))}
icon-reset
[:span {:class "ml-1.5"} "Reset"]]
[:button
{:class "flex items-center border-r px-2.5 py-1.5 text-sm hover:bg-gray-200"
:on-click (fn [_]
(noc.sketch/toggle-pause applet*))}
icon-pause
[:span {:class "ml-1"} "Pause"]]]]]))
8 changes: 4 additions & 4 deletions dev/noc/sci.cljs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
(ns noc.sci
(:require [nextjournal.clerk.sci-env]
noc.custom
noc.sketch
noc.render
quil.core
[sci.ctx-store]
Expand All @@ -9,8 +9,8 @@
;; ## SCI Customization

(def custom-namespaces
{'noc.custom
(sci/copy-ns noc.custom (sci/create-ns 'noc.custom))
{'noc.sketch
(sci/copy-ns noc.sketch (sci/create-ns 'noc.sketch))
'q
(sci/copy-ns quil.core (sci/create-ns 'quil.core))
'noc.render
Expand All @@ -20,7 +20,7 @@
})

(def custom-aliases
{'custom 'noc.custom})
{'sketch 'noc.sketch})

(sci.ctx-store/swap-ctx!
sci/merge-opts
Expand Down
58 changes: 58 additions & 0 deletions dev/noc/sketch.cljs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
(ns noc.sketch
(:require [quil.core :as q]
[quil.sketch :as ap :include-macros true]
[noc.chapter-0-1 :as c0.1]
[noc.chapter-0-2 :as c0.2]
[noc.dots :as dots]))

(def sketches {:dots dots/sketch
:walker c0.1/sketch
:rand-dist c0.2/sketch})

(defn load-sketch [s]
(get sketches s))

(def default-state {:paused? false
:default-frame-rate 60})

(defn setup-state [init-state]
(merge default-state init-state))

(defn reset [sketch*]
(let [{:keys [applet opts]} @sketch*
{:keys [setup]} opts]
(ap/with-sketch applet
(let [state* (q/state :state)
new-state (setup-state (setup))]
(reset! state* new-state)))))

(defn toggle-pause [sketch*]
(let [{:keys [applet]} @sketch*]
(ap/with-sketch applet
(let [state* (q/state :state)
state @state*]
(if (= 0 (.frameRate applet))
(do
(q/frame-rate (:default-frame-rate state))
(swap! state* assoc :paused? false))
(do
(q/frame-rate 0)
(swap! state* assoc :paused? true)))))))

(defn setup-wrapper [setup]
(let [state (setup-state (setup))]
(q/set-state! :state (atom state) :init-state state)))

(defn draw-wrapper [tick draw]
(let [state* (q/state :state)]
(reset! state* (tick @state*))
(draw @state*)))

(defn show-sketch [{:keys [setup tick draw] :as opts} el]
{:applet (apply q/sketch (apply concat
(-> opts
(assoc :host el)
(assoc :setup (partial setup-wrapper setup))
(assoc :draw (partial draw-wrapper tick draw)))))
:opts opts
:el el})
27 changes: 16 additions & 11 deletions dev/user.clj
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
(ns user
(:require [babashka.fs :as fs]
[clojure.java.shell :refer [sh]]
[clojure.string]
[nextjournal.clerk :as clerk]
[nextjournal.clerk.config :as config]
[nextjournal.clerk.viewer :as cv]
[shadow.cljs.devtools.server :as shadow.server]
[shadow.cljs.devtools.server.npm-deps :as npm-deps]
[shadow.cljs.devtools.api :as shadow.api]))
(:require
[babashka.fs :as fs]
[clojure.java.shell :refer [sh]]
[clojure.string]
[nextjournal.clerk :as clerk]
[nextjournal.clerk.config :as config]
[nextjournal.clerk.viewer :as cv]
[shadow.cljs.devtools.server :as shadow.server]
[shadow.cljs.devtools.server.npm-deps :as npm-deps]
[shadow.cljs.devtools.api :as shadow.api]))

(def build-target
{:git/url "https://github.com/ramblurr/nature-of-code"})
Expand All @@ -28,7 +29,7 @@
(clerk/serve!
(merge defaults opts))
(Thread/sleep 1000)
(clerk/show! "notebooks/hello.clj"))))
#_(clerk/show! "notebooks/hello.clj"))))

(defn start-with-shadow!
([] (start-with-shadow! {}))
Expand Down Expand Up @@ -95,7 +96,11 @@

(comment

(start-with-shadow!)
(start-with-shadow!) ;; rcf
(do
(require '[portal.api :as p])
(def p (p/open {:theme :portal.colors/gruvbox}))
(add-tap #'p/submit))

(garden!
{:paths ["src/**"]
Expand Down
20 changes: 20 additions & 0 deletions notebooks/chapter_0.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
;; # Chapter 0

(ns chapter-0
{:nextjournal.clerk/visibility {:code :hide}}
(:require [nextjournal.clerk :as clerk]
[noc.quil-clerk :refer [show-sketch]]))

;; ## [Example 0.1: A Traditional Random Walk](https://natureofcode.com/random/#example-01-a-traditional-random-walk)

^{::clerk/no-cache true ::clerk/viewer clerk/code}
(slurp "dev/noc/chapter_0_1.cljs")

(show-sketch :walker)

;; ## [Example 0.2: A Random-Number Distribution](https://natureofcode.com/random/#example-02-a-random-number-distribution)

^{::clerk/no-cache true ::clerk/viewer clerk/code}
(slurp "dev/noc/chapter_0_2.cljs")

(show-sketch :rand-dist)
13 changes: 2 additions & 11 deletions notebooks/quil_clerk.clj
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,8 @@

(ns quil-clerk
{:nextjournal.clerk/visibility {:code :hide}}
(:require [nextjournal.clerk :as clerk]))
(:require [nextjournal.clerk :as clerk]
[noc.quil-clerk :refer [show-sketch]]))

;; This is a proof of concept on how to embed interactive Quil animations in a Clerk notebook.

^{:nextjournal.clerk/visibility {:result :hide}}
(defn make-sketch-viewer []
{:transform-fn clerk/mark-presented
:render-fn 'noc.render/render-quil-sketch})

^{:nextjournal.clerk/visibility {:result :hide}}
(defn show-sketch [sketch-name]
(clerk/with-viewer (make-sketch-viewer) sketch-name))

(show-sketch :dots)
11 changes: 11 additions & 0 deletions src/noc/quil_clerk.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
(ns noc.quil-clerk
(:require [nextjournal.clerk :as clerk]))

^{:nextjournal.clerk/visibility {:result :hide}}
(defn make-sketch-viewer []
{:transform-fn clerk/mark-presented
:render-fn 'noc.render/render-quil-sketch})

^{:nextjournal.clerk/visibility {:result :hide}}
(defn show-sketch [sketch-name]
(clerk/with-viewer (make-sketch-viewer) sketch-name))

0 comments on commit ccc4e2d

Please sign in to comment.