Merge branch 'path-drawing'

This commit is contained in:
Andrey Antukh 2016-08-12 20:40:34 +03:00
commit 5e8a3f2bfc
No known key found for this signature in database
GPG Key ID: 4DFEBCB8316A8B95
13 changed files with 284 additions and 40 deletions

View File

@ -29,6 +29,7 @@
;; --- Relative Movement ;; --- Relative Movement
(declare move-rect) (declare move-rect)
(declare move-path)
(declare move-circle) (declare move-circle)
(declare move-group) (declare move-group)
@ -41,6 +42,8 @@
:rect (move-rect shape dpoint) :rect (move-rect shape dpoint)
:text (move-rect shape dpoint) :text (move-rect shape dpoint)
:line (move-rect shape dpoint) :line (move-rect shape dpoint)
;; :path (move-path shape dpoint)
:path (move-rect shape dpoint)
:circle (move-circle shape dpoint) :circle (move-circle shape dpoint)
:group (move-group shape dpoint))) :group (move-group shape dpoint)))
@ -70,6 +73,16 @@
:dx (mth/round (+ (:dx shape 0) dx)) :dx (mth/round (+ (:dx shape 0) dx))
:dy (mth/round (+ (:dy shape 0) dy)))) :dy (mth/round (+ (:dy shape 0) dy))))
(defn- move-path
"A specialized function for relative movement
for path shapes."
[shape {dx :x dy :y}]
(let [points (:points shape)
xf (comp
(map #(update % :x + dx))
(map #(update % :y + dy)))]
(assoc shape :points (into [] xf points))))
;; --- Absolute Movement ;; --- Absolute Movement
(declare absolute-move-rect) (declare absolute-move-rect)
@ -129,7 +142,8 @@
:text (rect-size shape) :text (rect-size shape)
:rect (rect-size shape) :rect (rect-size shape)
:icon (rect-size shape) :icon (rect-size shape)
:line (rect-size shape))) :line (rect-size shape)
:path (rect-size shape)))
(defn- rect-size (defn- rect-size
"A specialized function for calculate size "A specialized function for calculate size
@ -164,7 +178,6 @@
:bottom (gpt/point (/ (+ x1 x2) 2) :bottom (gpt/point (/ (+ x1 x2) 2)
(/ (+ y1 y2) 2)))) (/ (+ y1 y2) 2))))
(defn- get-circle-vertext-point (defn- get-circle-vertext-point
[{:keys [rx ry]} id] [{:keys [rx ry]} id]
(gpt/point rx ry)) (gpt/point rx ry))
@ -182,6 +195,7 @@
:rect (move-rect-vertex shape vid dpoint) :rect (move-rect-vertex shape vid dpoint)
:text (move-rect-vertex shape vid dpoint) :text (move-rect-vertex shape vid dpoint)
:icon (move-rect-vertex shape vid dpoint) :icon (move-rect-vertex shape vid dpoint)
:path (move-rect-vertex shape vid dpoint)
:circle (move-circle-vertex shape vid dpoint))) :circle (move-circle-vertex shape vid dpoint)))
(defn- move-rect-vertex (defn- move-rect-vertex
@ -248,6 +262,7 @@
:icon (resize-rect shape point) :icon (resize-rect shape point)
:text (resize-rect shape point) :text (resize-rect shape point)
:line (resize-line shape point) :line (resize-line shape point)
:path (resize-rect shape point)
:circle (resize-circle shape point))) :circle (resize-circle shape point)))
(defn- resize-rect (defn- resize-rect
@ -353,6 +368,7 @@
(declare apply-rotation-transformation) (declare apply-rotation-transformation)
(declare generic-inner-rect) (declare generic-inner-rect)
(declare path-inner-rect)
(declare circle-inner-rect) (declare circle-inner-rect)
(declare group-inner-rect) (declare group-inner-rect)
@ -364,6 +380,7 @@
:rect (generic-inner-rect state shape) :rect (generic-inner-rect state shape)
:text (generic-inner-rect shape shape) :text (generic-inner-rect shape shape)
:line (generic-inner-rect state shape) :line (generic-inner-rect state shape)
:path (path-inner-rect state shape)
:circle (circle-inner-rect state shape) :circle (circle-inner-rect state shape)
:group (group-inner-rect state shape)))) :group (group-inner-rect state shape))))
@ -373,6 +390,19 @@
(merge (size shape)) (merge (size shape))
(apply-rotation-transformation))) (apply-rotation-transformation)))
(defn- path-inner-rect
[state {:keys [points] :as shape}]
(let [minx (apply min (map :x points))
miny (apply min (map :y points))
maxx (apply max (map :x points))
maxy (apply max (map :y points))
props {:x minx
:y miny
:width (- maxx minx)
:height (- maxy miny)}]
(-> (merge shape props)
(apply-rotation-transformation))))
(defn- circle-inner-rect (defn- circle-inner-rect
[state {:keys [cx cy rx ry group] :as shape}] [state {:keys [cx cy rx ry group] :as shape}]
(let [props {:x (- cx rx) (let [props {:x (- cx rx)
@ -402,6 +432,7 @@
(declare generic-outer-rect) (declare generic-outer-rect)
(declare circle-outer-rect) (declare circle-outer-rect)
(declare path-outer-rect)
(declare group-outer-rect) (declare group-outer-rect)
(declare apply-rotation-transformation) (declare apply-rotation-transformation)
(declare apply-parent-deltas) (declare apply-parent-deltas)
@ -415,6 +446,8 @@
:text (generic-outer-rect state shape) :text (generic-outer-rect state shape)
:icon (generic-outer-rect state shape) :icon (generic-outer-rect state shape)
:line (generic-outer-rect state shape) :line (generic-outer-rect state shape)
:path (generic-outer-rect state shape)
;; :path (path-outer-rect state shape)
:circle (circle-outer-rect state shape) :circle (circle-outer-rect state shape)
:group (group-outer-rect state shape))] :group (group-outer-rect state shape))]
(if (:group shape) (if (:group shape)
@ -450,6 +483,22 @@
(-> (merge shape props) (-> (merge shape props)
(apply-rotation-transformation)))) (apply-rotation-transformation))))
(defn- path-outer-rect
[state {:keys [points group] :as shape}]
(let [group (get-in state [:shapes-by-id group])
minx (apply min (map :x points))
miny (apply min (map :y points))
maxx (apply max (map :x points))
maxy (apply max (map :y points))
props {:x (+ minx (:dx group 0))
:y (+ miny (:dy group 0))
:width (- maxx minx)
:height (- maxy miny)}]
(-> (merge shape props)
(apply-rotation-transformation))))
(defn- group-outer-rect (defn- group-outer-rect
[state {:keys [id group rotation dx dy] :as shape}] [state {:keys [id group rotation dx dy] :as shape}]
(let [shapes (->> (:items shape) (let [shapes (->> (:items shape)
@ -534,6 +583,7 @@
(declare text-transformation-matrix) (declare text-transformation-matrix)
(declare circle-transformation-matrix) (declare circle-transformation-matrix)
(declare icon-transformation-matrix) (declare icon-transformation-matrix)
(declare path-transformation-matrix)
(declare group-transformation-matrix) (declare group-transformation-matrix)
(defn transformation-matrix (defn transformation-matrix
@ -545,6 +595,7 @@
:text (text-transformation-matrix state shape) :text (text-transformation-matrix state shape)
:circle (circle-transformation-matrix state shape) :circle (circle-transformation-matrix state shape)
:icon (icon-transformation-matrix state shape) :icon (icon-transformation-matrix state shape)
:path (path-transformation-matrix state shape)
:group (group-transformation-matrix state shape)))) :group (group-transformation-matrix state shape))))
(defn- rect-transformation-matrix (defn- rect-transformation-matrix
@ -583,6 +634,22 @@
(gmt/translate (- center-x) (- center-y)) (gmt/translate (- center-x) (- center-y))
(gmt/scale scale-x scale-y)))) (gmt/scale scale-x scale-y))))
(defn- path-transformation-matrix
[state {:keys [x1 y1 rotation view-box] :or {rotation 0} :as shape}]
(let [{:keys [width height]} (size shape)
orig-width (nth view-box 2)
orig-height (nth view-box 3)
scale-x (/ width orig-width)
scale-y (/ height orig-height)
center-x (- width (/ width 2))
center-y (- height (/ height 2))]
(-> (gmt/matrix)
(gmt/translate x1 y1)
(gmt/translate center-x center-y)
(gmt/rotate rotation)
(gmt/translate (- center-x) (- center-y))
(gmt/scale scale-x scale-y))))
(defn- circle-transformation-matrix (defn- circle-transformation-matrix
[state {:keys [cx cy rx ry rotation] :or {rotation 0} :as shape}] [state {:keys [cx cy rx ry rotation] :or {rotation 0} :as shape}]
(-> (gmt/matrix) (-> (gmt/matrix)

View File

@ -44,7 +44,7 @@
(let [[a b c d tx ty] v] (let [[a b c d tx ty] v]
(Matrix. a b c d tx ty)))) (Matrix. a b c d tx ty))))
(defn matrix? (defn ^boolean matrix?
"Return true if `v` is Matrix instance." "Return true if `v` is Matrix instance."
[v] [v]
(instance? Matrix v)) (instance? Matrix v))
@ -123,3 +123,21 @@
(+ ty1 (* tx2 c1) (* ty2 d1))))) (+ ty1 (* tx2 c1) (* ty2 d1)))))
([m om & others] ([m om & others]
(reduce append (append m om) others))) (reduce append (append m om) others)))
(defn ^boolean invertible?
[{:keys [a b c d tx ty] :as m}]
(let [det (- (* a d) (* c b))]
(and (not (mth/nan? det))
(mth/finite? tx)
(mth/finite? ty))))
(defn invert
[{:keys [a b c d tx ty] :as m}]
(when (invertible? m)
(let [det (- (* a d) (* c b))]
(Matrix. (/ d det)
(/ (- b) det)
(/ (- c) det)
(/ a det)
(/ (- (* c ty) (* d tx)) det)
(/ (- (* b tx) (* a ty)) det)))))

View File

@ -35,7 +35,7 @@
(-point [v] (-point [v]
(Point. (first v) (second v)))) (Point. (first v) (second v))))
(defn point? (defn ^boolean point?
"Return true if `v` is Point instance." "Return true if `v` is Point instance."
[v] [v]
(instance? Point v)) (instance? Point v))
@ -158,3 +158,11 @@
[{:keys [x y]} decimanls] [{:keys [x y]} decimanls]
(Point. (mth/precision x decimanls) (Point. (mth/precision x decimanls)
(mth/precision y decimanls))) (mth/precision y decimanls)))
(defn transform
"Transform a point applying a matrix transfomation."
[{:keys [x y] :as p} {:keys [a b c d tx ty] :as m}]
(Point. (+ (* x a) (* y c) tx)
(+ (* x b) (* y d) ty)))

View File

@ -26,7 +26,7 @@
(defn render-component (defn render-component
[{:keys [type] :as shape}] [{:keys [type] :as shape}]
;; (println "render-component" shape) ;; (println "render-component" (pr-str shape))
(case type (case type
:group (group-component shape) :group (group-component shape)
:text (text/text-component shape) :text (text/text-component shape)

View File

@ -0,0 +1,47 @@
;; This Source Code Form is subject to the terms of the Mozilla Public
;; License, v. 2.0. If a copy of the MPL was not distributed with this
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;;
;; Copyright (c) 2016 Andrey Antukh <niwi@niwi.nz>
(ns uxbox.main.ui.shapes.path
(:require [uxbox.util.mixins :as mx :include-macros true]
[uxbox.main.ui.shapes.common :as common]
[uxbox.main.ui.shapes.attrs :as attrs]
[uxbox.main.geom :as geom]))
;; --- Path Component
(declare path-shape)
(mx/defc path-component
{:mixins [mx/static mx/reactive]}
[{:keys [id] :as shape}]
(let [selected (mx/react common/selected-shapes-ref)
selected? (contains? selected id)
on-mouse-down #(common/on-mouse-down % shape selected)]
[:g.shape {:class (when selected? "selected")
:on-mouse-down on-mouse-down}
(path-shape shape identity)]))
;; --- Path Shape
(defn- render-path
[{:keys [points close?] :as shape}]
{:pre [(pos? (count points))]}
(let [start (first points)
init (str "M " (:x start) " " (:y start))
path (reduce #(str %1 " L" (:x %2) " " (:y %2)) init points)]
(cond-> path
close? (str " Z"))))
(mx/defc path-shape
{:mixins [mx/static]}
[{:keys [id drawing?] :as shape}]
(let [key (str "shape-" id)
rfm (geom/transformation-matrix shape)
attrs (-> (attrs/extract-style-attrs shape)
(merge {:id key :key key :d (render-path shape)})
(merge (when-not drawing?
{:transform (str rfm)})))]
[:path attrs]))

View File

@ -80,9 +80,16 @@
;; --- Events ;; --- Events
;; TODO: this should replace mouse-events-s and keyboard-events-b
(defonce events-b (rx/bus))
(defonce events-s (rx/dedupe events-b))
(defonce mouse-events-b (rx/bus)) (defonce mouse-events-b (rx/bus))
(defonce mouse-events-s (rx/dedupe mouse-events-b)) (defonce mouse-events-s (rx/dedupe mouse-events-b))
;; (defonce kaka
;; (rx/subscribe mouse-events-s #(println "event:" %)))
(defonce keyboard-events-b (rx/bus)) (defonce keyboard-events-b (rx/bus))
(defonce keyboard-events-s (rx/dedupe keyboard-events-b)) (defonce keyboard-events-s (rx/dedupe keyboard-events-b))

View File

@ -19,7 +19,6 @@
[uxbox.util.data :refer (parse-int)] [uxbox.util.data :refer (parse-int)]
[uxbox.main.ui.keyboard :as kbd] [uxbox.main.ui.keyboard :as kbd]
[uxbox.main.ui.shapes :as uus] [uxbox.main.ui.shapes :as uus]
;; [uxbox.main.ui.shapes.path :as spath]
[uxbox.util.mixins :as mx :include-macros true] [uxbox.util.mixins :as mx :include-macros true]
[uxbox.main.ui.workspace.base :as wb] [uxbox.main.ui.workspace.base :as wb]
[uxbox.main.ui.workspace.rlocks :as rlocks] [uxbox.main.ui.workspace.rlocks :as rlocks]
@ -42,19 +41,6 @@
;; --- Canvas ;; --- Canvas
;; (def ^:private test-path-shape
;; {:type :path
;; :id #uuid "042951a0-804a-4cf1-b606-3e97157f55b5"
;; :stroke-type :solid
;; :stroke "#000000"
;; :stroke-width 2
;; :fill "transparent"
;; :close? true
;; :points [(gpt/point 100 100)
;; (gpt/point 300 100)
;; (gpt/point 200 300)
;; ]})
(mx/defc canvas (mx/defc canvas
{:mixins [mx/reactive]} {:mixins [mx/reactive]}
[{:keys [width height id] :as page}] [{:keys [width height id] :as page}]
@ -71,7 +57,6 @@
(for [item (reverse (:shapes page))] (for [item (reverse (:shapes page))]
(-> (uus/shape item) (-> (uus/shape item)
(mx/with-key (str item)))) (mx/with-key (str item))))
;; (spath/path-component test-path-shape)
(selection-handlers) (selection-handlers)
(draw-area)]]])) (draw-area)]]]))
@ -150,17 +135,25 @@
zoom (or (:zoom workspace) 1)] zoom (or (:zoom workspace) 1)]
(letfn [(on-mouse-down [event] (letfn [(on-mouse-down [event]
(dom/stop-propagation event) (dom/stop-propagation event)
(rx/push! wb/mouse-events-b :mouse/down) (rx/push! wb/events-b [:mouse/down])
(if (:drawing workspace) (if (:drawing workspace)
(rlocks/acquire! :ui/draw) (rlocks/acquire! :ui/draw)
(rlocks/acquire! :ui/selrect))) (rlocks/acquire! :ui/selrect)))
(on-mouse-up [event] (on-mouse-up [event]
(rx/push! wb/mouse-events-b :mouse/up) (dom/stop-propagation event)
(dom/stop-propagation event))] (rx/push! wb/events-b [:mouse/up]))
(on-click [event]
(dom/stop-propagation event)
(rx/push! wb/events-b [:mouse/click]))
(on-double-click [event]
(dom/stop-propagation event)
(rx/push! wb/events-b [:mouse/double-click]))]
[:svg.viewport {:width (* c/viewport-width zoom) [:svg.viewport {:width (* c/viewport-width zoom)
:height (* c/viewport-height zoom) :height (* c/viewport-height zoom)
:ref "viewport" :ref "viewport"
:class (when drawing? "drawing") :class (when drawing? "drawing")
:on-click on-click
:on-double-click on-double-click
:on-mouse-down on-mouse-down :on-mouse-down on-mouse-down
:on-mouse-up on-mouse-up} :on-mouse-up on-mouse-up}
[:g.zoom {:transform (str "scale(" zoom ", " zoom ")")} [:g.zoom {:transform (str "scale(" zoom ", " zoom ")")}

View File

@ -49,15 +49,19 @@
[own] [own]
(let [shape (mx/react drawing-shape) (let [shape (mx/react drawing-shape)
position (mx/react drawing-position)] position (mx/react drawing-position)]
(when (and shape position) (when shape
(-> (assoc shape :drawing? true) (if position
(geom/resize position) (-> (assoc shape :drawing? true)
(shapes/render-component))))) (geom/resize position)
(shapes/render-component))
(-> (assoc shape :drawing? true)
(shapes/render-component))))))
;; --- Drawing Initialization ;; --- Drawing Initialization
(declare on-init) (declare on-init)
(declare on-init-draw-icon) (declare on-init-draw-icon)
(declare on-init-draw-path)
(declare on-init-draw-generic) (declare on-init-draw-generic)
(declare on-draw-start) (declare on-draw-start)
(declare on-draw) (declare on-draw)
@ -76,6 +80,7 @@
(when-let [shape (:drawing @wb/workspace-ref)] (when-let [shape (:drawing @wb/workspace-ref)]
(case (:type shape) (case (:type shape)
:icon (on-init-draw-icon shape) :icon (on-init-draw-icon shape)
:path (on-init-draw-path shape)
(on-init-draw-generic shape)))) (on-init-draw-generic shape))))
(defn- on-init-draw-icon (defn- on-init-draw-icon
@ -88,6 +93,87 @@
(uds/select-first-shape)) (uds/select-first-shape))
(rlocks/release! :ui/draw))) (rlocks/release! :ui/draw)))
(defn- on-init-draw-path
[shape]
(let [mouse (->> (rx/sample 10 wb/mouse-viewport-s)
(rx/mapcat (fn [point]
(if @wb/alignment-ref
(uds/align-point point)
(rx/of point))))
(rx/map #(gpt/subtract % canvas-coords)))
stoper (->> wb/events-s
(rx/map first)
(rx/filter #(= % :mouse/double-click))
(rx/take 1))
firstpos (rx/take 1 mouse)
stream (->> (rx/take-until stoper mouse)
(rx/skip-while #(nil? @drawing-shape))
(rx/with-latest-from vector wb/mouse-ctrl-s))
ptstream (->> (rx/take-until stoper wb/events-s)
(rx/map first)
(rx/filter #(= % :mouse/click))
(rx/with-latest-from vector mouse)
(rx/map second))
counter (atom 0)]
(letfn [(append-point [{:keys [type] :as shape} point]
(let [point (gpt/point point)]
(update shape :points conj point)))
(update-point [{:keys [type] :as shape} point index]
(let [point (gpt/point point)
points (:points shape)]
(if (= (count points) index)
(append-point shape point)
(assoc-in shape [:points index] point))))
(normalize-shape [{:keys [points] :as shape}]
(let [minx (apply min (map :x points))
miny (apply min (map :y points))
maxx (apply max (map :x points))
maxy (apply max (map :y points))
dx (- 0 minx)
dy (- 0 miny)
points (mapv #(gpt/add % [dx dy]) points)
width (- maxx minx)
height (- maxy miny)]
(assoc shape
:x1 minx
:y1 miny
:x2 maxx
:y2 maxy
:view-box [0 0 width height]
:points points)))
(on-first-point [point]
(let [shape (append-point shape point)]
(swap! counter inc)
(reset! drawing-shape shape)))
(on-click [point]
(let [shape (append-point @drawing-shape point)]
(swap! counter inc)
(reset! drawing-shape shape)))
(on-draw [[point ctrl?]]
(let [shape (update-point @drawing-shape point @counter)]
(reset! drawing-shape shape)))
(on-end []
(let [shape (normalize-shape @drawing-shape)]
(println "on-end" shape)
(rs/emit! (uds/add-shape shape)
(udw/select-for-drawing nil)
(uds/select-first-shape))
(reset! drawing-shape nil)
(reset! drawing-position nil)
(rlocks/release! :ui/draw)))]
(rx/subscribe firstpos on-first-point)
(rx/subscribe ptstream on-click)
(rx/subscribe stream on-draw nil on-end))))
(defn- on-init-draw-generic (defn- on-init-draw-generic
[shape] [shape]
(let [mouse (->> (rx/sample 10 wb/mouse-viewport-s) (let [mouse (->> (rx/sample 10 wb/mouse-viewport-s)
@ -97,23 +183,25 @@
(rx/of point)))) (rx/of point))))
(rx/map #(gpt/subtract % canvas-coords))) (rx/map #(gpt/subtract % canvas-coords)))
stoper (->> wb/mouse-events-s stoper (->> wb/events-s
(rx/map first)
(rx/filter #(= % :mouse/up)) (rx/filter #(= % :mouse/up))
(rx/pr-log "mouse-events-s")
(rx/take 1)) (rx/take 1))
firstpos (rx/take 1 mouse) firstpos (rx/take 1 mouse)
stream (->> (rx/take-until stoper mouse) stream (->> (rx/take-until stoper mouse)
(rx/skip-while #(nil? @drawing-shape)) (rx/skip-while #(nil? @drawing-shape))
(rx/with-latest-from vector wb/mouse-ctrl-s))] (rx/with-latest-from vector wb/mouse-ctrl-s))]
(rx/subscribe firstpos #(on-draw-start shape %)) (rx/subscribe firstpos (fn [{:keys [x y] :as pt}]
(let [shape (geom/setup shape {:x1 x :y1 y
:x2 x :y2 y})]
(reset! drawing-shape shape))))
(rx/subscribe stream on-draw nil on-draw-complete))) (rx/subscribe stream on-draw nil on-draw-complete)))
(defn- on-draw-start ;; (defn- on-draw-start
[shape {:keys [x y] :as pt}] ;; [shape {:keys [x y] :as pt}]
(let [shape (geom/setup shape {:x1 x :y1 y :x2 x :y2 y})] ;; (let [shape (geom/setup shape {:x1 x :y1 y :x2 x :y2 y})]
(reset! drawing-shape shape))) ;; (reset! drawing-shape shape)))
(defn- on-draw (defn- on-draw
[[pt ctrl?]] [[pt ctrl?]]
@ -124,7 +212,7 @@
[] []
(let [shape @drawing-shape (let [shape @drawing-shape
shpos @drawing-position shpos @drawing-position
shape (geom/resize shape shpos)] shape (geom/resize shape shpos)]
(rs/emit! (uds/add-shape shape) (rs/emit! (uds/add-shape shape)
(udw/select-for-drawing nil) (udw/select-for-drawing nil)
(uds/select-first-shape)) (uds/select-first-shape))

View File

@ -60,7 +60,8 @@
(defn- on-resize-start (defn- on-resize-start
[[vid shape]] [[vid shape]]
(let [stoper (->> wb/mouse-events-s (let [stoper (->> wb/events-s
(rx/map first)
(rx/filter #(= % :mouse/up)) (rx/filter #(= % :mouse/up))
(rx/take 1)) (rx/take 1))
stream (->> wb/mouse-delta-s stream (->> wb/mouse-delta-s
@ -81,7 +82,8 @@
(defn- on-move-start (defn- on-move-start
[shape] [shape]
(let [stoper (->> wb/mouse-events-s (let [stoper (->> wb/events-s
(rx/map first)
(rx/filter #(= % :mouse/up)) (rx/filter #(= % :mouse/up))
(rx/take 1)) (rx/take 1))
stream (rx/take-until stoper wb/mouse-delta-s) stream (rx/take-until stoper wb/mouse-delta-s)

View File

@ -101,7 +101,8 @@
(defn- on-start (defn- on-start
"Function execution when selrect action is started." "Function execution when selrect action is started."
[] []
(let [stoper (->> wb/mouse-events-s (let [stoper (->> wb/events-s
(rx/map first)
(rx/filter #(= % :mouse/up)) (rx/filter #(= % :mouse/up))
(rx/take 1)) (rx/take 1))
stream (rx/take-until stoper wb/mouse-viewport-s) stream (rx/take-until stoper wb/mouse-viewport-s)

View File

@ -51,7 +51,11 @@
{:type :path {:type :path
:name "Path" :name "Path"
:stroke-type :solid :stroke-type :solid
:stroke "#000000"}) :stroke "#000000"
:stroke-width 2
:fill "transparent"
;; :close? true
:points []})
(def +draw-tool-text+ (def +draw-tool-text+
{:type :text {:type :text

View File

@ -96,6 +96,7 @@
:icon (icon/icon-svg item) :icon (icon/icon-svg item)
:line i/line :line i/line
:circle i/circle :circle i/circle
:path i/curve
:rect i/box :rect i/box
:text i/text :text i/text
:group i/folder)) :group i/folder))

View File

@ -9,6 +9,14 @@
"A collection of math utils." "A collection of math utils."
(:require [goog.math :as math])) (:require [goog.math :as math]))
(defn ^boolean nan?
[v]
(js/isNaN v))
(defn ^boolean finite?
[v]
(js/isFinite v))
(defn abs (defn abs
[^number v] [^number v]
(js/Math.abs v)) (js/Math.abs v))