mirror of
https://github.com/penpot/penpot.git
synced 2025-07-08 19:17:19 +02:00
✨ Fix problems with shadows and strokes for nested frames
This commit is contained in:
parent
e0a1da6bca
commit
2e3f443758
10 changed files with 137 additions and 138 deletions
|
@ -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]}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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)))]
|
||||||
|
|
||||||
|
|
|
@ -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])]])))
|
|
||||||
|
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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]]]]))))))
|
||||||
|
|
|
@ -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]
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue