mirror of
https://github.com/penpot/penpot.git
synced 2025-05-30 01:36:11 +02:00
Merge remote-tracking branch 'origin/staging' into develop
This commit is contained in:
commit
a9e8115088
24 changed files with 274 additions and 148 deletions
|
@ -991,19 +991,22 @@
|
|||
[[] [] []]
|
||||
ids)
|
||||
|
||||
[rchanges uchanges] (relocate-shapes-changes objects
|
||||
parents
|
||||
parent-id
|
||||
page-id
|
||||
to-index
|
||||
ids
|
||||
groups-to-delete
|
||||
groups-to-unmask
|
||||
shapes-to-detach
|
||||
shapes-to-reroot
|
||||
shapes-to-deroot)]
|
||||
[rchanges uchanges]
|
||||
(relocate-shapes-changes objects
|
||||
parents
|
||||
parent-id
|
||||
page-id
|
||||
to-index
|
||||
ids
|
||||
groups-to-delete
|
||||
groups-to-unmask
|
||||
shapes-to-detach
|
||||
shapes-to-reroot
|
||||
shapes-to-deroot)
|
||||
|
||||
]
|
||||
(rx/of (dch/commit-changes {:redo-changes rchanges
|
||||
:undo-chanes uchanges
|
||||
:undo-changes uchanges
|
||||
:origin it})
|
||||
(dwc/expand-collapse parent-id))))))
|
||||
|
||||
|
@ -1058,7 +1061,7 @@
|
|||
:id id
|
||||
:index cidx}]
|
||||
(rx/of (dch/commit-changes {:redo-changes [rchg]
|
||||
:undo-chanes [uchg]
|
||||
:undo-changes [uchg]
|
||||
:origin it}))))))
|
||||
|
||||
;; --- Shape / Selection Alignment and Distribution
|
||||
|
|
|
@ -32,31 +32,97 @@
|
|||
(gsh/setup selrect)
|
||||
(assoc :shapes (mapv :id shapes)))))
|
||||
|
||||
(defn get-empty-groups
|
||||
"Retrieve emtpy groups after group creation"
|
||||
[objects parent-id shapes]
|
||||
(let [ids (cp/clean-loops objects (into #{} (map :id) shapes))
|
||||
parents (->> ids
|
||||
(reduce #(conj %1 (cp/get-parent %2 objects))
|
||||
#{}))]
|
||||
(loop [current-id (first parents)
|
||||
to-check (rest parents)
|
||||
removed-id? ids
|
||||
result #{}]
|
||||
|
||||
(if-not current-id
|
||||
;; Base case, no next element
|
||||
result
|
||||
|
||||
(let [group (get objects current-id)]
|
||||
(if (and (not= :frame (:type group))
|
||||
(not= current-id parent-id)
|
||||
(empty? (remove removed-id? (:shapes group))))
|
||||
|
||||
;; Adds group to the remove and check its parent
|
||||
(let [to-check (d/concat [] to-check [(cp/get-parent current-id objects)]) ]
|
||||
(recur (first to-check)
|
||||
(rest to-check)
|
||||
(conj removed-id? current-id)
|
||||
(conj result current-id)))
|
||||
|
||||
;; otherwise recur
|
||||
(recur (first to-check)
|
||||
(rest to-check)
|
||||
removed-id?
|
||||
result)))))))
|
||||
|
||||
(defn prepare-create-group
|
||||
[page-id shapes prefix keep-name]
|
||||
[objects page-id shapes prefix keep-name]
|
||||
(let [group (make-group shapes prefix keep-name)
|
||||
frame-id (:frame-id (first shapes))
|
||||
parent-id (:parent-id (first shapes))
|
||||
rchanges [{:type :add-obj
|
||||
:id (:id group)
|
||||
:page-id page-id
|
||||
:frame-id (:frame-id (first shapes))
|
||||
:parent-id (:parent-id (first shapes))
|
||||
:frame-id frame-id
|
||||
:parent-id parent-id
|
||||
:obj group
|
||||
:index (::index (first shapes))}
|
||||
|
||||
{:type :mov-objects
|
||||
:page-id page-id
|
||||
:parent-id (:id group)
|
||||
:shapes (mapv :id shapes)}]
|
||||
|
||||
uchanges (conj
|
||||
(mapv (fn [obj] {:type :mov-objects
|
||||
:page-id page-id
|
||||
:parent-id (:parent-id obj)
|
||||
:index (::index obj)
|
||||
:shapes [(:id obj)]})
|
||||
shapes)
|
||||
{:type :del-obj
|
||||
:id (:id group)
|
||||
:page-id page-id})]
|
||||
uchanges (-> (mapv
|
||||
(fn [obj]
|
||||
{:type :mov-objects
|
||||
:page-id page-id
|
||||
:parent-id (:parent-id obj)
|
||||
:index (::index obj)
|
||||
:shapes [(:id obj)]}) shapes)
|
||||
(conj
|
||||
{:type :del-obj
|
||||
:id (:id group)
|
||||
:page-id page-id}))
|
||||
|
||||
ids-to-delete (get-empty-groups objects parent-id shapes)
|
||||
|
||||
delete-group
|
||||
(fn [changes id]
|
||||
(-> changes
|
||||
(conj {:type :del-obj
|
||||
:id id
|
||||
:page-id page-id})))
|
||||
|
||||
add-deleted-group
|
||||
(fn [changes id]
|
||||
(let [obj (-> (get objects id)
|
||||
(d/without-keys [:shapes]))]
|
||||
|
||||
(d/concat [{:type :add-obj
|
||||
:id id
|
||||
:page-id page-id
|
||||
:frame-id (:frame-id obj)
|
||||
:parent-id (:parent-id obj)
|
||||
:obj obj
|
||||
:index (::index obj)}] changes)))
|
||||
|
||||
rchanges (->> ids-to-delete
|
||||
(reduce delete-group rchanges))
|
||||
|
||||
uchanges (->> ids-to-delete
|
||||
(reduce add-deleted-group uchanges))]
|
||||
[group rchanges uchanges]))
|
||||
|
||||
(defn prepare-remove-group
|
||||
|
@ -107,7 +173,8 @@
|
|||
selected (cp/clean-loops objects selected)
|
||||
shapes (shapes-for-grouping objects selected)]
|
||||
(when-not (empty? shapes)
|
||||
(let [[group rchanges uchanges] (prepare-create-group page-id shapes "Group-" false)]
|
||||
(let [[group rchanges uchanges]
|
||||
(prepare-create-group objects page-id shapes "Group-" false)]
|
||||
(rx/of (dch/commit-changes {:redo-changes rchanges
|
||||
:undo-changes uchanges
|
||||
:origin it})
|
||||
|
@ -146,7 +213,7 @@
|
|||
(if (and (= (count shapes) 1)
|
||||
(= (:type (first shapes)) :group))
|
||||
[(first shapes) [] []]
|
||||
(prepare-create-group page-id shapes "Group-" true))
|
||||
(prepare-create-group objects page-id shapes "Group-" true))
|
||||
|
||||
rchanges (d/concat rchanges
|
||||
[{:type :mod-obj
|
||||
|
|
|
@ -131,7 +131,7 @@
|
|||
(if (and (= (count shapes) 1)
|
||||
(= (:type (first shapes)) :group))
|
||||
[(first shapes) [] []]
|
||||
(dwg/prepare-create-group page-id shapes "Component-" true))
|
||||
(dwg/prepare-create-group objects page-id shapes "Component-" true))
|
||||
|
||||
[new-shape new-shapes updated-shapes]
|
||||
(make-component-shape group objects file-id)
|
||||
|
|
|
@ -562,7 +562,7 @@
|
|||
|
||||
(defn- extract-frame-changes
|
||||
"Process a changes set in a commit to extract the frames that are channging"
|
||||
[[event objects]]
|
||||
[[event [old-objects new-objects]]]
|
||||
(let [changes (-> event deref :changes)
|
||||
|
||||
extract-ids
|
||||
|
@ -577,8 +577,11 @@
|
|||
|
||||
get-frame-id
|
||||
(fn [id]
|
||||
(or (and (= :frame (get-in objects [id :type])) id)
|
||||
(get-in objects [id :frame-id])))
|
||||
(let [shape (or (get new-objects id)
|
||||
(get old-objects id))]
|
||||
|
||||
(or (and (= :frame (:type shape)) id)
|
||||
(:frame-id shape))))
|
||||
|
||||
;; Extracts the frames and then removes nils and the root frame
|
||||
xform (comp (mapcat extract-ids)
|
||||
|
@ -613,7 +616,12 @@
|
|||
(rx/filter #(or (= :app.main.data.workspace/finalize-page (ptk/type %))
|
||||
(= ::watch-state-changes (ptk/type %)))))
|
||||
|
||||
objects-stream (rx/from-atom refs/workspace-page-objects {:emit-current-value? true})
|
||||
objects-stream (->> (rx/concat
|
||||
(rx/of nil)
|
||||
(rx/from-atom refs/workspace-page-objects {:emit-current-value? true}))
|
||||
;; We need to keep the old-objects so we can check the frame for the
|
||||
;; deleted objects
|
||||
(rx/buffer 2 1))
|
||||
|
||||
frame-changes (->> stream
|
||||
(rx/filter dch/commit-changes?)
|
||||
|
|
|
@ -26,11 +26,18 @@
|
|||
(get-in state [:workspace-data :components component-id :objects])))
|
||||
|
||||
(defn lookup-selected
|
||||
[state]
|
||||
(let [objects (lookup-page-objects state)
|
||||
selected (->> (get-in state [:workspace-local :selected])
|
||||
(cp/clean-loops objects))
|
||||
is-present? (fn [id] (contains? objects id))]
|
||||
(into (d/ordered-set)
|
||||
(filter is-present?)
|
||||
selected)))
|
||||
([state]
|
||||
(lookup-selected state nil))
|
||||
|
||||
([state {:keys [omit-blocked?]
|
||||
:or {omit-blocked? false}}]
|
||||
(let [objects (lookup-page-objects state)
|
||||
selected (->> (get-in state [:workspace-local :selected])
|
||||
(cp/clean-loops objects))
|
||||
selectable? (fn [id]
|
||||
(and (contains? objects id)
|
||||
(or (not omit-blocked?)
|
||||
(not (get-in objects [id :blocked] false)))))]
|
||||
(into (d/ordered-set)
|
||||
(filter selectable?)
|
||||
selected))))
|
||||
|
|
|
@ -242,23 +242,24 @@
|
|||
ptk/WatchEvent
|
||||
(watch [it state stream]
|
||||
(let [initial (deref ms/mouse-position)
|
||||
selected (wsh/lookup-selected state)
|
||||
selected (wsh/lookup-selected state {:omit-blocked? true})
|
||||
stopper (rx/filter ms/mouse-up? stream)]
|
||||
(->> ms/mouse-position
|
||||
(rx/take-until stopper)
|
||||
(rx/map #(gpt/to-vec initial %))
|
||||
(rx/map #(gpt/length %))
|
||||
(rx/filter #(> % 1))
|
||||
(rx/take 1)
|
||||
(rx/with-latest vector ms/mouse-position-alt)
|
||||
(rx/mapcat
|
||||
(fn [[_ alt?]]
|
||||
(if alt?
|
||||
;; When alt is down we start a duplicate+move
|
||||
(rx/of (start-move-duplicate initial)
|
||||
dws/duplicate-selected)
|
||||
;; Otherwise just plain old move
|
||||
(rx/of (start-move initial selected))))))))))
|
||||
(when-not (empty? selected)
|
||||
(->> ms/mouse-position
|
||||
(rx/take-until stopper)
|
||||
(rx/map #(gpt/to-vec initial %))
|
||||
(rx/map #(gpt/length %))
|
||||
(rx/filter #(> % 1))
|
||||
(rx/take 1)
|
||||
(rx/with-latest vector ms/mouse-position-alt)
|
||||
(rx/mapcat
|
||||
(fn [[_ alt?]]
|
||||
(if alt?
|
||||
;; When alt is down we start a duplicate+move
|
||||
(rx/of (start-move-duplicate initial)
|
||||
dws/duplicate-selected)
|
||||
;; Otherwise just plain old move
|
||||
(rx/of (start-move initial selected)))))))))))
|
||||
|
||||
(defn start-move-duplicate [from-position]
|
||||
(ptk/reify ::start-move-selected
|
||||
|
@ -319,7 +320,8 @@
|
|||
(watch [it state stream]
|
||||
(let [page-id (:current-page-id state)
|
||||
objects (wsh/lookup-page-objects state page-id)
|
||||
ids (if (nil? ids) (wsh/lookup-selected state) ids)
|
||||
selected (wsh/lookup-selected state {:omit-blocked? true})
|
||||
ids (if (nil? ids) selected ids)
|
||||
shapes (mapv #(get objects %) ids)
|
||||
stopper (rx/filter ms/mouse-up? stream)
|
||||
layout (get state :workspace-layout)
|
||||
|
@ -398,7 +400,7 @@
|
|||
ptk/WatchEvent
|
||||
(watch [it state stream]
|
||||
(if (= same-event (get-in state [:workspace-local :current-move-selected]))
|
||||
(let [selected (wsh/lookup-selected state)
|
||||
(let [selected (wsh/lookup-selected state {:omit-blocked? true})
|
||||
move-events (->> stream
|
||||
(rx/filter (ptk/type? ::move-selected))
|
||||
(rx/filter #(= direction (deref %))))
|
||||
|
@ -435,6 +437,8 @@
|
|||
page-id (:current-page-id state)
|
||||
objects (wsh/lookup-page-objects state page-id)
|
||||
|
||||
ids (->> ids (into #{} (remove #(get-in objects [% :blocked] false))))
|
||||
|
||||
not-frame-id?
|
||||
(fn [shape-id]
|
||||
(let [shape (get objects shape-id)]
|
||||
|
@ -457,27 +461,28 @@
|
|||
;; shape adjusting their position.
|
||||
|
||||
(defn set-rotation
|
||||
([delta-rotation shapes]
|
||||
(set-rotation delta-rotation shapes (-> shapes gsh/selection-rect gsh/center-selrect)))
|
||||
([angle shapes]
|
||||
(set-rotation angle shapes (-> shapes gsh/selection-rect gsh/center-selrect)))
|
||||
|
||||
([delta-rotation shapes center]
|
||||
(letfn [(rotate-shape [objects angle shape center]
|
||||
(update-in objects [(:id shape) :modifiers] merge (gsh/rotation-modifiers center shape angle)))
|
||||
([angle shapes center]
|
||||
(ptk/reify ::set-rotation
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(let [objects (wsh/lookup-page-objects state)
|
||||
id->obj #(get objects %)
|
||||
get-children (fn [shape] (map id->obj (cp/get-children (:id shape) objects)))
|
||||
|
||||
(rotate-around-center [objects angle center shapes]
|
||||
(reduce #(rotate-shape %1 angle %2 center) objects shapes))
|
||||
shapes (->> shapes (into [] (remove #(get % :blocked false))))
|
||||
|
||||
(set-rotation [objects]
|
||||
(let [id->obj #(get objects %)
|
||||
get-children (fn [shape] (map id->obj (cp/get-children (:id shape) objects)))
|
||||
shapes (concat shapes (mapcat get-children shapes))]
|
||||
(rotate-around-center objects delta-rotation center shapes)))]
|
||||
shapes (->> shapes (mapcat get-children) (concat shapes))
|
||||
|
||||
(ptk/reify ::set-rotation
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(let [page-id (:current-page-id state)]
|
||||
(d/update-in-when state [:workspace-data :pages-index page-id :objects] set-rotation)))))))
|
||||
update-shape
|
||||
(fn [modifiers shape]
|
||||
(let [rotate-modifiers (gsh/rotation-modifiers shape center angle)]
|
||||
(assoc-in modifiers [(:id shape) :modifiers] rotate-modifiers)))]
|
||||
(-> state
|
||||
(update :workspace-modifiers
|
||||
#(reduce update-shape % shapes))))))))
|
||||
|
||||
(defn increase-rotation [ids rotation]
|
||||
(ptk/reify ::increase-rotation
|
||||
|
@ -583,7 +588,7 @@
|
|||
ptk/WatchEvent
|
||||
(watch [it state stream]
|
||||
(let [objects (wsh/lookup-page-objects state)
|
||||
selected (wsh/lookup-selected state)
|
||||
selected (wsh/lookup-selected state {:omit-blocked? true})
|
||||
shapes (map #(get objects %) selected)
|
||||
selrect (gsh/selection-rect (->> shapes (map gsh/transform-shape)))
|
||||
origin (gpt/point (:x selrect) (+ (:y selrect) (/ (:height selrect) 2)))]
|
||||
|
@ -600,7 +605,7 @@
|
|||
ptk/WatchEvent
|
||||
(watch [it state stream]
|
||||
(let [objects (wsh/lookup-page-objects state)
|
||||
selected (wsh/lookup-selected state)
|
||||
selected (wsh/lookup-selected state {:omit-blocked? true})
|
||||
shapes (map #(get objects %) selected)
|
||||
selrect (gsh/selection-rect (->> shapes (map gsh/transform-shape)))
|
||||
origin (gpt/point (+ (:x selrect) (/ (:width selrect) 2)) (:y selrect))]
|
||||
|
@ -633,5 +638,5 @@
|
|||
(ptk/reify ::selected-to-path
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [ids (wsh/lookup-selected state)]
|
||||
(let [ids (wsh/lookup-selected state {:omit-blocked? true})]
|
||||
(rx/of (dch/update-shapes ids ups/convert-to-path))))))
|
||||
|
|
|
@ -22,18 +22,22 @@
|
|||
(hooks/use-effect-ssr
|
||||
(mf/deps embed? urls)
|
||||
(fn []
|
||||
(let [sub (when embed?
|
||||
(->> (rx/from urls)
|
||||
(rx/merge-map http/fetch-data-uri)
|
||||
(rx/reduce conj {})
|
||||
(rx/subs (fn [data]
|
||||
(when-not (= data (mf/ref-val uri-data))
|
||||
(mf/set-ref-val! uri-data data)
|
||||
(reset! state inc))))))]
|
||||
(let [;; When not active the embedding we return the URI
|
||||
url-mapping (fn [obs]
|
||||
(if embed?
|
||||
(rx/merge-map http/fetch-data-uri obs)
|
||||
(rx/map identity obs)))
|
||||
|
||||
sub (->> (rx/from urls)
|
||||
(url-mapping)
|
||||
(rx/reduce conj {})
|
||||
(rx/subs (fn [data]
|
||||
(when-not (= data (mf/ref-val uri-data))
|
||||
(mf/set-ref-val! uri-data data)
|
||||
(reset! state inc)))))]
|
||||
#(when sub
|
||||
(rx/dispose! sub)))))
|
||||
|
||||
;; Use ref so if the urls are cached will return inmediately instead of the
|
||||
;; next render
|
||||
(when embed?
|
||||
(mf/ref-val uri-data))))
|
||||
(mf/ref-val uri-data)))
|
||||
|
|
|
@ -31,7 +31,8 @@
|
|||
:y y
|
||||
:height height
|
||||
:width width
|
||||
:patternTransform transform}
|
||||
:patternTransform transform
|
||||
:data-loading (str (not (contains? embed uri)))}
|
||||
[:image {:xlinkHref (get embed uri uri)
|
||||
:width width
|
||||
:height height}]]))))
|
||||
|
|
|
@ -32,7 +32,9 @@
|
|||
:transform transform
|
||||
:width width
|
||||
:height height
|
||||
:preserveAspectRatio "none"}))
|
||||
:preserveAspectRatio "none"
|
||||
:data-loading (str (not (contains? embed uri)))}))
|
||||
|
||||
on-drag-start (fn [event]
|
||||
;; Prevent browser dragging of the image
|
||||
(dom/prevent-default event))]
|
||||
|
|
|
@ -75,7 +75,8 @@
|
|||
;; (uc/hex->rgba fill-color fill-opacity))
|
||||
|
||||
[r g b a] (uc/hex->rgba fill-color fill-opacity)
|
||||
text-color (str/format "rgba(%s, %s, %s, %s)" r g b a)
|
||||
text-color (when (and (some? fill-color) (some? fill-opacity))
|
||||
(str/format "rgba(%s, %s, %s, %s)" r g b a))
|
||||
fontsdb (deref fonts/fontsdb)
|
||||
|
||||
base #js {:textDecoration text-decoration
|
||||
|
|
|
@ -209,7 +209,7 @@
|
|||
(into []
|
||||
(cond
|
||||
(= selected :recent) (reverse recent-colors)
|
||||
(= selected :file) (vals file-colors)
|
||||
(= selected :file) (->> (vals file-colors) (sort-by :name))
|
||||
:else (library->colors shared-libs selected))))))
|
||||
|
||||
(mf/use-effect
|
||||
|
@ -222,7 +222,8 @@
|
|||
(mf/deps file-colors)
|
||||
(fn []
|
||||
(when (= selected :file)
|
||||
(reset! current-library-colors (into [] (vals file-colors))))))
|
||||
(reset! current-library-colors (into [] (->> (vals file-colors)
|
||||
(sort-by :name)))))))
|
||||
|
||||
[:& palette {:left-sidebar? left-sidebar?
|
||||
:current-colors @current-library-colors
|
||||
|
|
|
@ -150,10 +150,6 @@
|
|||
(dom/prevent-default event)
|
||||
(let [id (:id item)]
|
||||
(cond
|
||||
(or (:blocked item)
|
||||
(:hidden item))
|
||||
nil
|
||||
|
||||
(kbd/shift? event)
|
||||
(st/emit! (dw/shift-select-shapes id))
|
||||
|
||||
|
|
|
@ -288,6 +288,8 @@
|
|||
(fn [changes]
|
||||
(st/emit! (dwl/update-typography (merge typography changes) file-id))))
|
||||
|
||||
multiple? (->> values vals (d/seek #(= % :multiple)))
|
||||
|
||||
opts #js {:ids ids
|
||||
:values values
|
||||
:on-change on-change}]
|
||||
|
@ -295,7 +297,7 @@
|
|||
[:div.element-set
|
||||
[:div.element-set-title
|
||||
[:span label]
|
||||
(when (not typography)
|
||||
(when (and (not typography) (not multiple?))
|
||||
[:div.add-page {:on-click on-convert-to-typography} i/close])]
|
||||
|
||||
(cond
|
||||
|
|
|
@ -27,7 +27,19 @@
|
|||
(defn color-picker-callback
|
||||
[color disable-gradient disable-opacity handle-change-color handle-open handle-close]
|
||||
(fn [event]
|
||||
(let [x (.-clientX event)
|
||||
(let [color
|
||||
(cond
|
||||
(uc/multiple? color)
|
||||
{:color cp/default-color
|
||||
:opacity 1}
|
||||
|
||||
(= :multiple (:opacity color))
|
||||
(assoc color :opacity 1)
|
||||
|
||||
:else
|
||||
color)
|
||||
|
||||
x (.-clientX event)
|
||||
y (.-clientY event)
|
||||
props {:x x
|
||||
:y y
|
||||
|
@ -98,16 +110,12 @@
|
|||
|
||||
handle-click-color (mf/use-callback
|
||||
(mf/deps color)
|
||||
(let [;; If multiple, we change to default color
|
||||
color (if (uc/multiple? color)
|
||||
{:color cp/default-color :opacity 1}
|
||||
color)]
|
||||
(color-picker-callback color
|
||||
disable-gradient
|
||||
disable-opacity
|
||||
handle-pick-color
|
||||
handle-open
|
||||
handle-close)))
|
||||
(color-picker-callback color
|
||||
disable-gradient
|
||||
disable-opacity
|
||||
handle-pick-color
|
||||
handle-open
|
||||
handle-close))
|
||||
|
||||
prev-color (h/use-previous color)]
|
||||
|
||||
|
|
|
@ -148,22 +148,23 @@
|
|||
|
||||
extract-attrs
|
||||
(fn [[ids values] {:keys [id type shapes content] :as shape}]
|
||||
(let [props (get-in type->props [type attr-type])
|
||||
result (case props
|
||||
:ignore [ids values]
|
||||
:shape [(conj ids id)
|
||||
(merge-attrs values (merge
|
||||
(empty-map attrs)
|
||||
(select-keys shape attrs)))]
|
||||
:text [(conj ids id)
|
||||
(-> values
|
||||
(merge-attrs (select-keys shape attrs))
|
||||
(merge-attrs (attrs/get-attrs-multi (txt/node-seq content) attrs)))]
|
||||
:children (let [children (->> (:shapes shape []) (map #(get objects %)))
|
||||
[new-ids new-values] (get-attrs children objects attr-type)]
|
||||
[(d/concat ids new-ids) (merge-attrs values new-values)])
|
||||
[])]
|
||||
result))]
|
||||
(let [props (get-in type->props [type attr-type])]
|
||||
(case props
|
||||
:ignore [ids values]
|
||||
:shape [(conj ids id)
|
||||
(merge-attrs values (merge
|
||||
(empty-map attrs)
|
||||
(select-keys shape attrs)))]
|
||||
:text [(conj ids id)
|
||||
(-> values
|
||||
(merge-attrs (select-keys shape attrs))
|
||||
(merge-attrs (merge
|
||||
(select-keys txt/default-text-attrs attrs)
|
||||
(attrs/get-attrs-multi (txt/node-seq content) attrs))))]
|
||||
:children (let [children (->> (:shapes shape []) (map #(get objects %)))
|
||||
[new-ids new-values] (get-attrs children objects attr-type)]
|
||||
[(d/concat ids new-ids) (merge-attrs values new-values)])
|
||||
[])))]
|
||||
(reduce extract-attrs [[] []] shapes)))
|
||||
|
||||
(mf/defc options
|
||||
|
|
|
@ -131,7 +131,7 @@
|
|||
#(rx/dispose! sub))))
|
||||
|
||||
(mf/use-effect
|
||||
(mf/deps shapes modifiers)
|
||||
(mf/deps shapes filter-shapes modifiers)
|
||||
(fn []
|
||||
(rx/push! subject props)))
|
||||
|
||||
|
@ -161,7 +161,8 @@
|
|||
(map #(get objects %))
|
||||
(filterv (comp not nil?)))
|
||||
filter-shapes (into #{}
|
||||
(mapcat #(cp/get-object-with-children % objects))
|
||||
(comp (mapcat #(cp/get-object-with-children % objects))
|
||||
(map :id))
|
||||
selected)
|
||||
|
||||
filter-shapes (fn [id]
|
||||
|
|
|
@ -29,16 +29,19 @@
|
|||
(when node
|
||||
(let [img-node (mf/ref-val thumbnail-img)]
|
||||
(timers/schedule-on-idle
|
||||
#(if-let [frame-node (dom/get-element (str "shape-" (:id shape)))]
|
||||
(let [xml (-> (js/XMLSerializer.)
|
||||
(.serializeToString frame-node)
|
||||
js/encodeURIComponent
|
||||
js/unescape
|
||||
js/btoa)
|
||||
img-src (str "data:image/svg+xml;base64," xml)]
|
||||
(obj/set! img-node "src" img-src))
|
||||
#(let [frame-node (dom/get-element (str "shape-" (:id shape)))
|
||||
loading-node (when frame-node
|
||||
(dom/query frame-node "[data-loading=\"true\"]"))]
|
||||
(if (and (some? frame-node) (not (some? loading-node)))
|
||||
(let [xml (-> (js/XMLSerializer.)
|
||||
(.serializeToString frame-node)
|
||||
js/encodeURIComponent
|
||||
js/unescape
|
||||
js/btoa)
|
||||
img-src (str "data:image/svg+xml;base64," xml)]
|
||||
(obj/set! img-node "src" img-src))
|
||||
|
||||
(on-frame-not-found (:id shape))))))))
|
||||
(on-frame-not-found (:id shape)))))))))
|
||||
|
||||
on-image-load
|
||||
(mf/use-callback
|
||||
|
@ -108,8 +111,9 @@
|
|||
(fn [frame-id]
|
||||
;; If we couldn't find the frame maybe is still rendering. We push the event again
|
||||
;; after a time
|
||||
(timers/schedule-on-idle #(dwp/update-frame-thumbnail frame-id))
|
||||
(rx/push! next :next)))]
|
||||
(reset! shape-id nil)
|
||||
(rx/push! next :next)
|
||||
(timers/schedule-on-idle (st/emitf (dwp/update-frame-thumbnail frame-id)))))]
|
||||
|
||||
(mf/use-effect
|
||||
(mf/deps render-frame)
|
||||
|
|
|
@ -135,7 +135,7 @@
|
|||
|
||||
:else "transparent")))
|
||||
|
||||
(defn multiple? [{:keys [id file-id value color gradient]}]
|
||||
(defn multiple? [{:keys [id file-id value color gradient opacity]}]
|
||||
(or (= value :multiple)
|
||||
(= color :multiple)
|
||||
(= gradient :multiple)
|
||||
|
|
|
@ -22,7 +22,10 @@
|
|||
(defn add-subpath-command
|
||||
"Adds a command to the subpath"
|
||||
[subpath command]
|
||||
(let [p (upc/command->point command)]
|
||||
(let [command (if (= :close-path (:command command))
|
||||
(upc/make-line-to (:from subpath))
|
||||
command)
|
||||
p (upc/command->point command)]
|
||||
(-> subpath
|
||||
(assoc :to p)
|
||||
(update :data conj command))))
|
||||
|
|
|
@ -34,12 +34,13 @@
|
|||
(-dispose [_]
|
||||
(js/clearInterval sem)))))
|
||||
|
||||
(if (and (exists? js/window) (.-requestIdleCallback js/window))
|
||||
(if (and (exists? js/window)
|
||||
(.-requestIdleCallback js/window))
|
||||
(do
|
||||
(def ^:private request-idle-callback #(js/requestIdleCallback %))
|
||||
(def ^:private cancel-idle-callback #(js/cancelIdleCallback %)))
|
||||
(do
|
||||
(def ^:private request-idle-callback #(js/setTimeout % 100))
|
||||
(def ^:private request-idle-callback #(js/setTimeout % 250))
|
||||
(def ^:private cancel-idle-callback #(js/clearTimeout %))))
|
||||
|
||||
(defn schedule-on-idle
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue