0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-04-16 00:41:25 -05:00

Add support for line rendering.

This commit is contained in:
Andrey Antukh 2016-01-28 20:27:15 +02:00
parent 32b7bfe383
commit e96eb76d84
5 changed files with 108 additions and 65 deletions

View file

@ -191,21 +191,22 @@
sh/-rotate rotation))))
(defn update-shape-size
[sid {:keys [width height lock] :as opts}]
"A helper event just for update the position
of the shape using the width and heigt attrs
instread final point of coordinates.
WARN: only works with shapes that works
with height and width such are"
[sid {:keys [width height] :as opts}]
(sc/validate! +shape-update-size-schema+ opts)
(reify
rs/UpdateEvent
(-apply-update [_ state]
(let [shape (get-in state [:shapes-by-id sid])
size (select-keys shape [:width :height])
size (merge size
(when width {:width width})
(when height {:height height}))]
(update-in state [:shapes-by-id sid]
shapes/-resize size)))))
(let [size [width height]]
(update-in state [:shapes-by-id sid] sh/-resize' size)))))
(defn update-shape-position
[sid {:keys [x y] :as opts}]
[sid {:keys [x1 y1 x2 y2] :as opts}]
(sc/validate! +shape-update-position-schema+ opts)
(reify
rs/UpdateEvent

View file

@ -45,6 +45,10 @@
dispatch-by-type
:hierarchy #'+hierarchy+)
(defmulti -resize'
dispatch-by-type
:hierarchy #'+hierarchy+)
(defmulti -rotate
dispatch-by-type
:hierarchy #'+hierarchy+)
@ -70,20 +74,56 @@
;; Implementation
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Initialize
(defmethod -initialize ::shape
[shape props]
(merge shape props))
[shape {:keys [x1 y1 x2 y2]}]
(merge shape
(when x1 {:x x1})
(when y1 {:y y1})
(when (and x2 x1) {:width (- x2 x1)})
(when (and y2 y1) {:height (- y2 y1)})))
(defmethod -initialize :builtin/group
[shape {:keys [x y width height]}]
[shape {:keys [x1 y1 x2 y2]}]
shape)
;; (defmethod -initialize :builtin/line
;; [shape {:keys [x y width height]}]
;; (merge shape
;; {:x1 x :y1 y
;; :x2 (+ x width)
;; :y2 (+ y height)}))
(defmethod -initialize :builtin/line
[shape {:keys [x1 y1 x2 y2]}]
(merge shape
(when x1 {:x1 x1})
(when y1 {:y1 y1})
(when x2 {:x2 x2})
(when y2 {:y2 y2})))
;; Resize
(defmethod -resize :builtin/line
[shape [x2 y2]]
(assoc shape
:x2 x2 :y2 y2))
(defmethod -resize :default
[shape _]
(throw (ex-info "Not implemented" (select-keys shape [:type]))))
(defmethod -resize' :builtin/icon
[shape [width height]]
(merge shape
(when width {:width width})
(when height {:height height})))
(defmethod -resize' :builtin/group
[shape [width height]]
(merge shape
(when width {:width width})
(when height {:height height})))
(defmethod -resize' :default
[shape _]
(throw (ex-info "Not implemented" (select-keys shape [:type]))))
;; Move
(defmethod -move ::shape
[shape {:keys [dx dy] :as opts}]
@ -97,23 +137,13 @@
:dx (+ (:dx shape 0) dx)
:dy (+ (:dy shape 0) dy)))
;; (defmethod -move :builtin/line
;; [shape {:keys [dx dy] :as opts}]
;; (assoc shape
;; :x1 (+ (:x1 shape) dx)
;; :y1 (+ (:y1 shape) dy)
;; :x2 (+ (:x2 shape) dx)
;; :y2 (+ (:y2 shape) dy)))
(defmethod -resize ::shape
[shape {:keys [width height] :as opts}]
(defmethod -move :builtin/line
[shape {:keys [dx dy] :as opts}]
(assoc shape
:width width
:height height))
(defmethod -resize :builtin/line
[shape {:keys [width height] :as opts}]
(throw (ex-info "Not implemented" {})))
:x1 (+ (:x1 shape) dx)
:y1 (+ (:y1 shape) dy)
:x2 (+ (:x2 shape) dx)
:y2 (+ (:y2 shape) dy)))
(defmethod -rotate ::shape
[shape rotation]
@ -129,8 +159,15 @@
(assoc $ :y (+ (:y shape) (:dy group 0)))
(container-rect $))))
(defmethod -outer-rect :builtin/line
[shape]
(let [{:keys [x1 y1 x2 y2]} shape
props {:x x1 :y y1 :width (- x2 x1) :height (- y2 y1)}
shape (merge shape props)]
(container-rect shape)))
(defmethod -outer-rect :builtin/group
[{:keys [id group rotation dx dy view-box] :as shape}]
[{:keys [id group rotation dx dy] :as shape}]
(let [shapes (->> (:items shape)
(map #(get-in @st/state [:shapes-by-id %]))
(map -outer-rect))

View file

@ -42,6 +42,12 @@
(html
[:g attrs data])))
(defmethod sh/-render :builtin/line
[{:keys [id x1 y1 x2 y2]}]
(html
[:line {:x1 x1 :y1 y1 :x2 x2 :y2 y2
:stroke "black"
:stroke-width "1"}]))
;; FIXME: the impl should be more clear.

View file

@ -14,11 +14,9 @@
[uxbox.util.data :refer (parse-int parse-float)]))
(def +menus-map+
{:builtin/icon [:menu/measures :menu/fill :menu/stroke]
:builtin/rect [:menu/measures :menu/fill :menu/stroke]
:builtin/circle [:menu/measures :menu/fill :menu/stroke]
{:builtin/icon [:menu/icon-measures :menu/fill :menu/stroke]
:builtin/line [:menu/stroke]
:builtin/group [:menu/measures]})
:builtin/group []})
(def +menus-by-id+
{:menu/measures
@ -44,8 +42,8 @@
[new-x new-y]))
(defn- get-position
[{:keys [page width] :as shape}]
(let [{:keys [x y]} (sh/-outer-rect shape)
[{:keys [page] :as shape}]
(let [{:keys [x y width]} (sh/-outer-rect shape)
vx (+ x width 50)
vy (- y 50)]
(viewportcoord->clientcoord page vx vy)))
@ -162,26 +160,25 @@
:step "0.0001"
:on-change on-opacity-change}]]]])))
(defmethod -render-menu :menu/measures
(defmethod -render-menu :menu/icon-measures
[menu own shape]
(letfn [(on-size-change [attr event]
(let [value (dom/event->value event)
value (parse-int value 0)
sid (:id shape)]
(-> (dw/update-shape-size sid {attr value})
(rs/emit!))))
sid (:id shape)
props {attr value}]
(rs/emit! (dw/update-shape-size sid props))))
(on-rotation-change [event]
(let [value (dom/event->value event)
value (parse-int value 0)
sid (:id shape)]
(-> (dw/update-shape-rotation sid value)
(rs/emit!))))
(rs/emit! (dw/update-shape-rotation sid value))))
(on-pos-change [attr event]
(let [value (dom/event->value event)
value (parse-int value nil)
sid (:id shape)]
(-> (dw/update-shape-position sid {attr value})
(rs/emit!))))]
sid (:id shape)
props {attr value}]
(rs/emit! (dw/update-shape-position sid props))))]
(html
[:div.element-set {:key (str (:id menu))}
[:div.element-set-title (:name menu)]
@ -209,12 +206,12 @@
{:placeholder "x"
:type "number"
:value (:x shape "")
:on-change (partial on-pos-change :x)}]
:on-change (partial on-pos-change :x1)}]
[:input#width.input-text
{:placeholder "y"
:type "number"
:value (:y shape "")
:on-change (partial on-pos-change :y)}]]
:on-change (partial on-pos-change :y1)}]]
[:span "Rotation"]
[:div.row-flex
@ -234,19 +231,20 @@
zoom 1
menus (get +menus-map+ (:type shape))
active-menu (:menu @local (first menus))]
(html
[:div#element-options.element-options
{:style {:left (* popup-x zoom) :top (- (* popup-y zoom) scroll)}}
[:ul.element-icons
(for [menu-id (get +menus-map+ (:type shape))
:let [menu (get +menus-by-id+ menu-id)
selected? (= active-menu menu-id)]]
[:li#e-info {:on-click #(swap! local assoc :menu menu-id)
:key (str "menu-" (:id menu))
:class (when selected? "selected")}
(:icon menu)])]
(let [menu (get +menus-by-id+ active-menu)]
(-render-menu menu own shape))])))
(when (seq menus)
(html
[:div#element-options.element-options
{:style {:left (* popup-x zoom) :top (- (* popup-y zoom) scroll)}}
[:ul.element-icons
(for [menu-id (get +menus-map+ (:type shape))
:let [menu (get +menus-by-id+ menu-id)
selected? (= active-menu menu-id)]]
[:li#e-info {:on-click #(swap! local assoc :menu menu-id)
:key (str "menu-" (:id menu))
:class (when selected? "selected")}
(:icon menu)])]
(let [menu (get +menus-by-id+ active-menu)]
(-render-menu menu own shape))]))))
(def ^:static element-opts
(mx/component

View file

@ -74,6 +74,7 @@
[item]
(case (:type item)
:builtin/icon (shapes/-render-svg item)
:builtin/line i/line
:builtin/rect i/box
:builtin/group i/folder))