From 1bdc8800fb0df9bf8412a257cdd833f84a8df16d Mon Sep 17 00:00:00 2001 From: Juan Facorro Date: Thu, 10 Jan 2019 23:34:27 +0100 Subject: [PATCH] [#15] with-translation, with-fill and with-stroke --- src/doodler/core.clje | 93 ++++++++++++++++++++++++++----- src/doodler/examples/emerald.clje | 41 ++++++++++++++ 2 files changed, 121 insertions(+), 13 deletions(-) create mode 100644 src/doodler/examples/emerald.clje diff --git a/src/doodler/core.clje b/src/doodler/core.clje index 4b2ac6c..3cb500e 100644 --- a/src/doodler/core.clje +++ b/src/doodler/core.clje @@ -8,6 +8,10 @@ (def ^:dynamic *state* nil) +;; Translation coordinates +(def ^:dynamic *translate-x* 0) +(def ^:dynamic *translate-y* 0) + (defn state ([] *state*) ([key] (get *state* key))) @@ -234,6 +238,21 @@ [] (:current-stroke *sketch*)) +(defmacro with-stroke + [stroke & body] + `(let [stroke# ~stroke + previous-stroke# (doodler.core/current-stroke)] + + (cond (sequential? stroke#) (apply doodler.core/stroke stroke#) + true (doodler.core/stroke stroke#)) + + ;;return the value from body, not from the if after it. + (let [return-val# (do ~@body)] + (if (nil? previous-stroke#) + (doodler.core/no-stroke) + (apply doodler.core/stroke previous-stroke#)) + return-val#))) + (defn stroke ([gray] (stroke gray 255)) @@ -266,6 +285,11 @@ (wxPen/setJoin pen (gui/->stroke-join join-mode)) (wxDC/setPen *canvas* pen))) +(defn no-stroke + [] + (wxDC/setPen *canvas* (wxPen/new)) + (save-current-stroke nil)) + (defn background ([gray] (background gray 255)) @@ -288,6 +312,21 @@ [] (:current-fill *sketch*)) +(defmacro with-fill + [fill & body] + `(let [fill# ~fill + previous-fill# (doodler.core/current-fill)] + + (cond (sequential? fill#) (apply doodler.core/fill fill#) + true (doodler.core/fill fill#)) + + ;;return the value from body, not from the if after it. + (let [return-val# (do ~@body)] + (if (nil? previous-fill#) + (doodler.core/no-fill) + (apply doodler.core/fill previous-fill#)) + return-val#))) + (defn fill ([gray] (fill gray 255)) @@ -302,40 +341,68 @@ (wxDC/setBrush *canvas* brush) (save-current-fill color)))) +(defn no-fill + [] + (wxDC/setBrush *canvas* (wxBrush/new)) + (save-current-fill nil)) + +;; Translation + +(defmacro with-translation + [[x y] & body] + `(binding [doodler.core/*translate-x* ~x + doodler.core/*translate-y* ~y] + ~@body)) + +(defn* translate + [#erl[x y]] + #erl[(+ *translate-x* x) (+ *translate-y* y)]) + ;; Drawing (defn arc [x y w h start end] - (wxDC/drawEllipticArc *canvas* - #erl[(- x (erlang/div w 2)) (- y (erlang/div h 2))] - #erl[w h] - start end)) + (wxDC/drawEllipticArc + *canvas* + (translate #erl[(- x (erlang/div w 2)) (- y (erlang/div h 2))]) + #erl[w h] + start end)) (defn ellipse [x y w h] - (wxDC/drawEllipse *canvas* - #erl[(- x (erlang/div w 2)) (- y (erlang/div h 2))] - #erl[w h])) + (wxDC/drawEllipse + *canvas* + (translate #erl[(- x (erlang/div w 2)) (- y (erlang/div h 2))]) + #erl[w h])) (defn line - ([p1 p2] (apply line (concat p1 p2))) - ([x1 y1 x2 y2] (wxDC/drawLine *canvas* #erl[x1 y1] #erl[x2 y2]))) + ([p1 p2] + (apply line (concat p1 p2))) + ([x1 y1 x2 y2] + (wxDC/drawLine *canvas* + (translate #erl[x1 y1]) + (translate #erl[x2 y2])))) (defn point [x y] - (wxDC/drawPoint *canvas* #erl[x y])) + (wxDC/drawPoint *canvas* (translate #erl[x y]))) (defn rect ([x y w h] - (wxDC/drawRectangle *canvas* #erl[x y] #erl[w h])) + (wxDC/drawRectangle *canvas* + (translate #erl[x y]) + #erl[w h])) ([x y w h r] - (wxDC/drawRoundedRectangle *canvas* #erl[x y] #erl[w h] r))) + (wxDC/drawRoundedRectangle *canvas* + (translate #erl[x y]) + #erl[w h] + r))) ;; Text (defn text [s x y] - (wxDC/drawText *canvas* s #erl[x y])) + (wxDC/drawText *canvas* s (translate #erl[x y]))) ;; Dimension diff --git a/src/doodler/examples/emerald.clje b/src/doodler/examples/emerald.clje new file mode 100644 index 0000000..3fe876d --- /dev/null +++ b/src/doodler/examples/emerald.clje @@ -0,0 +1,41 @@ +;; Copied from http://quil.info/examples +(ns doodler.examples.emerald + (:require [doodler.core :as d])) + +(defn pulse [low high rate] + (let [diff (- high low) + half (/ diff 2) + mid (+ low half) + s (/ (d/millis) 1000.0) + x (d/sin (* s (/ 1.0 rate)))] + (int (+ mid (* x half))))) + +(defn setup [] + (d/frame-rate 60)) + +(defn draw [] + (d/no-stroke) + (d/background 255) + (let [w (d/width) + h (d/height) + hw (int (/ w 2)) + hh (int (/ h 2)) + inner-r (* hw 0.5) + outer-r hw] + (d/fill (pulse 20 50 2.0) 230 (pulse 150 200 1.0)) + (d/ellipse hw hh w h) + (d/stroke 255 255 255 100) + (d/with-translation [hw hh] + (doseq [a (range 0 d/TWO-PI (/ d/PI 256.0))] + (let [skew1 (* 0.001 (d/millis) a) + skew2 (* skew1 2.0)] + (d/line (int (* inner-r (d/cos (+ skew1 a)))) + (int (* inner-r (d/sin (+ skew1 a)))) + (int (* outer-r (d/cos (+ skew2 a)))) + (int (* outer-r (d/sin (+ skew2 a)))))))))) + +(d/defsketch sketch + :host "host" + :size [500 500] + :setup setup + :draw draw)