Fix problems with shadows and strokes for nested frames

This commit is contained in:
alonso.torres 2022-06-16 14:16:33 +02:00
parent e0a1da6bca
commit 2e3f443758
10 changed files with 137 additions and 138 deletions

View file

@ -22,7 +22,7 @@
java-http-clj/java-http-clj {:mvn/version "0.4.3"} java-http-clj/java-http-clj {:mvn/version "0.4.3"}
funcool/promesa {:mvn/version "8.0.450"} funcool/promesa {:mvn/version "8.0.450"}
funcool/cuerdas {:mvn/version "2022.06.13-401"} funcool/cuerdas {:mvn/version "2022.06.16-403"}
lambdaisland/uri {:mvn/version "1.13.95" lambdaisland/uri {:mvn/version "1.13.95"
:exclusions [org.clojure/data.json]} :exclusions [org.clojure/data.json]}

View file

@ -223,7 +223,7 @@
(defn close-artboard [file] (defn close-artboard [file]
(assert (nil? (:current-component-id file))) (assert (nil? (:current-component-id file)))
(let [parent-id (peek (get file :parent-stack)) (let [parent-id (-> file :parent-id peek)
parent (lookup-shape file parent-id) parent (lookup-shape file parent-id)
current-frame-id (or (:frame-id parent) root-frame)] current-frame-id (or (:frame-id parent) root-frame)]
(-> file (-> file

View file

@ -223,8 +223,14 @@
(loop [parents-a (rest parents-a) (loop [parents-a (rest parents-a)
parents-b (rest parents-b) parents-b (rest parents-b)
base uuid/zero] base uuid/zero]
(if (not= (first parents-a) (first parents-b)) (cond
(not= (first parents-a) (first parents-b))
[base (first parents-a) (first parents-b)] [base (first parents-a) (first parents-b)]
(or (empty? parents-a) (empty? parents-b))
[uuid/zero (first parents-a) (first parents-b)]
:else
(recur (rest parents-a) (rest parents-b) (first parents-a)))) (recur (rest parents-a) (rest parents-b) (first parents-a))))
index-base-a (when base-child-a (get-position-on-parent objects base-child-a)) index-base-a (when base-child-a (get-position-on-parent objects base-child-a))

View file

@ -1214,12 +1214,6 @@
;; selected and its parents ;; selected and its parents
objects (cph/selected-subtree objects selected) objects (cph/selected-subtree objects selected)
;;z-index (cp/calculate-z-index objects)
;;z-values (->> selected
;; (map #(vector %
;; (+ (get z-index %)
;; (get z-index (get-in objects [% :frame-id]))))))
selected (->> (cph/sort-z-index objects selected) selected (->> (cph/sort-z-index objects selected)
(into (d/ordered-set)))] (into (d/ordered-set)))]

View file

@ -42,86 +42,81 @@
[:> :path props] [:> :path props]
[:> :rect props])]))) [:> :rect props])])))
;; Wrapper around the frame that will handle things such as strokes and other properties
;; we wrap the proper frames and also the thumbnails
(mf/defc frame-container
{::mf/wrap-props false}
[props]
(let [shape (obj/get props "shape")
children (obj/get props "children")
{:keys [x y width height show-content]} shape
transform (gsh/transform-str shape)
props (-> (attrs/extract-style-attrs shape)
(obj/merge!
#js {:x x
:y y
:transform transform
:width width
:height height
:className "frame-background"}))
path? (some? (.-d props))
render-id (mf/use-ctx muc/render-ctx)]
[:*
[:g {:clip-path (when (not show-content) (frame-clip-url shape render-id))}
(when (not show-content)
[:& frame-clip-def {:shape shape :render-id render-id}])
[:& shape-fills {:shape shape}
(if path?
[:> :path props]
[:> :rect props])]
children]
[:& shape-strokes {:shape shape}
(if path?
[:> :path props]
[:> :rect props])]]))
(mf/defc frame-thumbnail-image
{::mf/wrap-props false}
[props]
(let [shape (obj/get props "shape")
bounds (or (obj/get props "bounds") (gsh/points->selrect (:points shape)))]
(when (:thumbnail shape)
[:image.frame-thumbnail
{:id (dm/str "thumbnail-" (:id shape))
:href (:thumbnail shape)
:x (:x bounds)
:y (:y bounds)
:width (:width bounds)
:height (:height bounds)
;; DEBUG
:style {:filter (when (debug? :thumbnails) "sepia(1)")}}])))
(mf/defc frame-thumbnail (mf/defc frame-thumbnail
{::mf/wrap-props false} {::mf/wrap-props false}
[props] [props]
(let [shape (obj/get props "shape") (let [shape (obj/get props "shape")]
bounds (or (obj/get props "bounds") (:selrect shape))]
(when (:thumbnail shape) (when (:thumbnail shape)
(let [{:keys [x y width height show-content]} shape [:> frame-container props
transform (gsh/transform-str shape) [:> frame-thumbnail-image props]])))
props (-> (attrs/extract-style-attrs shape)
(obj/merge!
#js {:x x
:y y
:transform transform
:width width
:height height
:className "frame-background"}))
path? (some? (.-d props))
render-id (mf/use-ctx muc/render-ctx)]
[:*
[:g {:clip-path (when (not show-content) (frame-clip-url shape render-id))}
(when (not show-content)
[:& frame-clip-def {:shape shape :render-id render-id}])
[:& shape-fills {:shape shape}
(if path?
[:> :path props]
[:> :rect props])]
[:image.frame-thumbnail
{:id (dm/str "thumbnail-" (:id shape))
:href (:thumbnail shape)
:x (:x bounds)
:y (:y bounds)
:width (:width bounds)
:height (:height bounds)
;; DEBUG
:style {:filter (when (debug? :thumbnails) "sepia(1)")}}]]
[:& shape-strokes {:shape shape}
(if path?
[:> :path props]
[:> :rect props])]]))))
(defn frame-shape (defn frame-shape
[shape-wrapper] [shape-wrapper]
(mf/fnc frame-shape (mf/fnc frame-shape
{::mf/wrap-props false} {::mf/wrap-props false}
[props] [props]
(let [childs (unchecked-get props "childs")
shape (unchecked-get props "shape")
{:keys [x y width height show-content]} shape
transform (gsh/transform-str shape) (let [childs (unchecked-get props "childs")]
[:> frame-container props
props (-> (attrs/extract-style-attrs shape) [:g.frame-children
(obj/merge! (for [item childs]
#js {:x x [:& shape-wrapper {:key (dm/str (:id item)) :shape item}])]])))
:y y
:transform transform
:width width
:height height
:className "frame-background"}))
path? (some? (.-d props))
render-id (mf/use-ctx muc/render-ctx)]
[:*
[:g {:clip-path (when (not show-content)
(frame-clip-url shape render-id))}
[:& shape-fills {:shape shape}
(if path?
[:> :path props]
[:> :rect props])]
[:g.frame-children
(for [item childs]
[:& shape-wrapper {:shape item
:key (dm/str (:id item))}])]]
[:& shape-strokes {:shape shape}
(if path?
[:> :path props]
[:> :rect props])]])))

View file

@ -87,21 +87,20 @@
opts #js {:shape shape :thumbnail? thumbnail?}] opts #js {:shape shape :thumbnail? thumbnail?}]
(when (and (some? shape) (not (:hidden shape))) (when (and (some? shape) (not (:hidden shape)))
[:* (case (:type shape)
(case (:type shape) :path [:> path/path-wrapper opts]
:path [:> path/path-wrapper opts] :text [:> text/text-wrapper opts]
:text [:> text/text-wrapper opts] :group [:> group-wrapper opts]
:group [:> group-wrapper opts] :rect [:> rect-wrapper opts]
:rect [:> rect-wrapper opts] :image [:> image-wrapper opts]
:image [:> image-wrapper opts] :circle [:> circle-wrapper opts]
:circle [:> circle-wrapper opts] :svg-raw [:> svg-raw-wrapper opts]
:svg-raw [:> svg-raw-wrapper opts] :bool [:> bool-wrapper opts]
:bool [:> bool-wrapper opts]
;; Only used when drawing a new frame. ;; Only used when drawing a new frame.
:frame [:> frame-wrapper opts] :frame [:> frame-wrapper opts]
nil)]))) nil))))
(def group-wrapper (group/group-wrapper-factory shape-wrapper)) (def group-wrapper (group/group-wrapper-factory shape-wrapper))
(def svg-raw-wrapper (svg-raw/svg-raw-wrapper-factory shape-wrapper)) (def svg-raw-wrapper (svg-raw/svg-raw-wrapper-factory shape-wrapper))

View file

@ -9,7 +9,6 @@
[app.common.data :as d] [app.common.data :as d]
[app.common.data.macros :as dm] [app.common.data.macros :as dm]
[app.common.pages.helpers :as cph] [app.common.pages.helpers :as cph]
[app.common.uuid :as uuid]
[app.main.data.workspace.state-helpers :as wsh] [app.main.data.workspace.state-helpers :as wsh]
[app.main.data.workspace.thumbnails :as dwt] [app.main.data.workspace.thumbnails :as dwt]
[app.main.fonts :as fonts] [app.main.fonts :as fonts]
@ -78,8 +77,6 @@
;; If the current shape is root we handle its thumbnail and the dynamic modifiers ;; If the current shape is root we handle its thumbnail and the dynamic modifiers
(let [thumbnail? (unchecked-get props "thumbnail?") (let [thumbnail? (unchecked-get props "thumbnail?")
render-id (mf/use-memo #(str (uuid/next)))
fonts (mf/use-memo (mf/deps shape objects) #(ff/shape->fonts shape objects)) fonts (mf/use-memo (mf/deps shape objects) #(ff/shape->fonts shape objects))
fonts (-> fonts (hooks/use-equal-memo)) fonts (-> fonts (hooks/use-equal-memo))
@ -96,7 +93,7 @@
[on-load-frame-dom render-frame? thumbnail-renderer] [on-load-frame-dom render-frame? thumbnail-renderer]
(ftr/use-render-thumbnail page-id shape node-ref rendered? disable-thumbnail? @force-render) (ftr/use-render-thumbnail page-id shape node-ref rendered? disable-thumbnail? @force-render)
[on-frame-load in-memory?] on-frame-load
(fns/use-node-store thumbnail? node-ref rendered? render-frame?)] (fns/use-node-store thumbnail? node-ref rendered? render-frame?)]
(mf/use-effect (mf/use-effect
@ -128,7 +125,7 @@
@node-ref) @node-ref)
(when (not @rendered?) (reset! rendered? true))))) (when (not @rendered?) (reset! rendered? true)))))
[:& (mf/provider ctx/render-ctx) {:value render-id} [:*
[:g.frame-container {:id (dm/str "frame-container-" (:id shape)) [:g.frame-container {:id (dm/str "frame-container-" (:id shape))
:key "frame-container" :key "frame-container"
:ref on-frame-load :ref on-frame-load
@ -137,5 +134,6 @@
[:g.frame-thumbnail-wrapper [:g.frame-thumbnail-wrapper
{:id (dm/str "thumbnail-container-" (:id shape)) {:id (dm/str "thumbnail-container-" (:id shape))
;; Hide the thumbnail when not displaying ;; Hide the thumbnail when not displaying
:opacity (when (and @rendered? (not thumbnail?) (not render-frame?) (not in-memory?)) 0)} :opacity (when (and @rendered? (not thumbnail?) (not render-frame?)) 0)}
thumbnail-renderer]]])))))) [:& shape-container {:shape shape}
thumbnail-renderer]]]]))))))

View file

@ -78,40 +78,41 @@
(defn get-nodes (defn get-nodes
"Retrieve the DOM nodes to apply the matrix transformation" "Retrieve the DOM nodes to apply the matrix transformation"
[base-node {:keys [id type masked-group?] :as shape}] [base-node {:keys [id type masked-group?] :as shape}]
(let [shape-node (if (= (.-id base-node) (dm/str "shape-" id)) (when (some? base-node)
base-node (let [shape-node (if (= (.-id base-node) (dm/str "shape-" id))
(dom/query base-node (dm/str "#shape-" id))) base-node
(dom/query base-node (dm/str "#shape-" id)))
frame? (= :frame type) frame? (= :frame type)
group? (= :group type) group? (= :group type)
text? (= :text type) text? (= :text type)
mask? (and group? masked-group?)] mask? (and group? masked-group?)]
(cond (cond
frame? frame?
[shape-node [shape-node
(dom/query shape-node ".frame-children") (dom/query shape-node ".frame-children")
(dom/query (dm/str "#thumbnail-container-" id)) (dom/query (dm/str "#thumbnail-container-" id))
(dom/query (dm/str "#thumbnail-" id)) (dom/query (dm/str "#thumbnail-" id))
(dom/query (dm/str "#frame-title-" id))] (dom/query (dm/str "#frame-title-" id))]
;; For groups we don't want to transform the whole group but only ;; For groups we don't want to transform the whole group but only
;; its filters/masks ;; its filters/masks
mask? mask?
[(dom/query shape-node ".mask-clip-path") [(dom/query shape-node ".mask-clip-path")
(dom/query shape-node ".mask-shape")] (dom/query shape-node ".mask-shape")]
group? group?
(let [shape-defs (dom/query shape-node "defs")] (let [shape-defs (dom/query shape-node "defs")]
(d/concat-vec (d/concat-vec
(dom/query-all shape-defs ".svg-def") (dom/query-all shape-defs ".svg-def")
(dom/query-all shape-defs ".svg-mask-wrapper"))) (dom/query-all shape-defs ".svg-mask-wrapper")))
text? text?
[shape-node [shape-node
(dom/query shape-node ".text-container")] (dom/query shape-node ".text-container")]
:else :else
[shape-node]))) [shape-node]))))
(defn transform-region! (defn transform-region!
[node modifiers] [node modifiers]

View file

@ -15,7 +15,7 @@
[thumbnail? node-ref rendered? render-frame?] [thumbnail? node-ref rendered? render-frame?]
(let [;; when `true` the node is in memory (let [;; when `true` the node is in memory
in-memory? (mf/use-var true) in-memory? (mf/use-state true)
;; State just for re-rendering ;; State just for re-rendering
re-render (mf/use-state 0) re-render (mf/use-state 0)
@ -32,7 +32,7 @@
(reset! parent-ref node) (reset! parent-ref node)
(swap! re-render inc)))))] (swap! re-render inc)))))]
(mf/use-effect (mf/use-layout-effect
(mf/deps thumbnail? render-frame?) (mf/deps thumbnail? render-frame?)
(fn [] (fn []
(when (and (some? @parent-ref) (some? @node-ref) @rendered? (and thumbnail? (not render-frame?))) (when (and (some? @parent-ref) (some? @node-ref) @rendered? (and thumbnail? (not render-frame?)))
@ -43,4 +43,4 @@
(.appendChild @parent-ref @node-ref) (.appendChild @parent-ref @node-ref)
(reset! in-memory? false)))) (reset! in-memory? false))))
[on-frame-load @in-memory?])) on-frame-load))

View file

@ -214,13 +214,19 @@
[on-load-frame-dom [on-load-frame-dom
@render-frame? @render-frame?
(mf/html (mf/html
[:* [:& frame/frame-container {:bounds shape-bb
:shape (cond-> shape
(some? thumbnail-data)
(assoc :thumbnail thumbnail-data))}
(when @show-frame-thumbnail (when @show-frame-thumbnail
[:> frame/frame-thumbnail {:key (dm/str (:id shape)) [:> frame/frame-thumbnail-image
:bounds shape-bb {:key (dm/str (:id shape))
:shape (cond-> shape :bounds shape-bb
(some? thumbnail-data) :shape (cond-> shape
(assoc :thumbnail thumbnail-data))}]) (some? thumbnail-data)
(assoc :thumbnail thumbnail-data))}])
[:foreignObject {:x x :y y :width width :height height} [:foreignObject {:x x :y y :width width :height height}
[:canvas.thumbnail-canvas [:canvas.thumbnail-canvas