0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-01-08 07:50:43 -05:00

Fix shadows in frames for dashboard and viewer

This commit is contained in:
alonso.torres 2022-06-21 22:18:18 +02:00
parent e1d6cded62
commit 8e60834292
11 changed files with 215 additions and 258 deletions

View file

@ -98,13 +98,6 @@
(defn distance-shapes [shape other]
(distance-selrect (:selrect shape) (:selrect other)))
(defn shape-stroke-margin
[shape stroke-width]
(if (= (:type shape) :path)
;; TODO: Calculate with the stroke offset (not implemented yet
(mth/sqrt (* 2 stroke-width stroke-width))
(- (mth/sqrt (* 2 stroke-width stroke-width)) stroke-width)))
(defn close-attrs?
"Compares two shapes attributes to see if they are equal or almost
equal (in case of numeric). Takes into account attributes that are

View file

@ -0,0 +1,151 @@
(ns app.common.geom.shapes.bounds
(:require
[app.common.data :as d]
[app.common.geom.shapes.rect :as gsr]
[app.common.math :as mth]
[app.common.pages.helpers :as cph]))
(defn shape-stroke-margin
[shape stroke-width]
(if (= (:type shape) :path)
;; TODO: Calculate with the stroke offset (not implemented yet
(mth/sqrt (* 2 stroke-width stroke-width))
(- (mth/sqrt (* 2 stroke-width stroke-width)) stroke-width)))
(defn blur-filters [type value]
(->> [value]
(remove :hidden)
(filter #(= (:type %) type))
(map #(hash-map :id (str "filter_" (:id %))
:type (:type %)
:params %))))
(defn shadow-filters [type filters]
(->> filters
(remove :hidden)
(filter #(= (:style %) type))
(map #(hash-map :id (str "filter_" (:id %))
:type (:style %)
:params %))))
(defn shape->filters
[shape]
(d/concat-vec
[{:id "BackgroundImageFix" :type :image-fix}]
;; Background blur won't work in current SVG specification
;; We can revisit this in the future
#_(->> shape :blur (blur-filters :background-blur))
(->> shape :shadow (shadow-filters :drop-shadow))
[{:id "shape" :type :blend-filters}]
(->> shape :shadow (shadow-filters :inner-shadow))
(->> shape :blur (blur-filters :layer-blur))))
(defn calculate-filter-bounds [{:keys [x y width height]} filter-entry]
(let [{:keys [offset-x offset-y blur spread] :or {offset-x 0 offset-y 0 blur 0 spread 0}} (:params filter-entry)
filter-x (min x (+ x offset-x (- spread) (- blur) -5))
filter-y (min y (+ y offset-y (- spread) (- blur) -5))
filter-width (+ width (mth/abs offset-x) (* spread 2) (* blur 2) 10)
filter-height (+ height (mth/abs offset-y) (* spread 2) (* blur 2) 10)]
(gsr/make-selrect filter-x filter-y filter-width filter-height)))
(defn get-rect-filter-bounds
[selrect filters blur-value]
(let [filter-bounds (->> filters
(filter #(= :drop-shadow (:type %)))
(map (partial calculate-filter-bounds selrect))
(concat [selrect])
(gsr/join-selrects))
delta-blur (* blur-value 2)
result
(-> filter-bounds
(update :x - delta-blur)
(update :y - delta-blur)
(update :x1 - delta-blur)
(update :x1 - delta-blur)
(update :x2 + delta-blur)
(update :y2 + delta-blur)
(update :width + (* delta-blur 2))
(update :height + (* delta-blur 2)))]
result))
(defn get-shape-filter-bounds
([shape]
(let [svg-root? (and (= :svg-raw (:type shape)) (not= :svg (get-in shape [:content :tag])))]
(if svg-root?
(:selrect shape)
(let [filters (shape->filters shape)
blur-value (or (-> shape :blur :value) 0)]
(get-rect-filter-bounds (-> shape :points gsr/points->selrect) filters blur-value))))))
(defn calculate-padding
([shape]
(calculate-padding shape false))
([shape ignore-margin?]
(let [stroke-width (apply max 0 (map #(case (:stroke-alignment % :center)
:center (/ (:stroke-width % 0) 2)
:outer (:stroke-width % 0)
0) (:strokes shape)))
margin (if ignore-margin?
0
(apply max 0 (map #(shape-stroke-margin % stroke-width) (:strokes shape))))
shadow-width (apply max 0 (map #(case (:style % :drop-shadow)
:drop-shadow (+ (mth/abs (:offset-x %)) (* (:spread %) 2) (* (:blur %) 2) 10)
0) (:shadow shape)))
shadow-height (apply max 0 (map #(case (:style % :drop-shadow)
:drop-shadow (+ (mth/abs (:offset-y %)) (* (:spread %) 2) (* (:blur %) 2) 10)
0) (:shadow shape)))]
{:horizontal (+ stroke-width margin shadow-width)
:vertical (+ stroke-width margin shadow-height)})))
(defn- add-padding
[bounds padding]
(-> bounds
(update :x - (:horizontal padding))
(update :y - (:vertical padding))
(update :width + (* 2 (:horizontal padding)))
(update :height + (* 2 (:vertical padding)))))
(defn get-object-bounds
[objects shape]
(let [calculate-base-bounds
(fn [shape]
(-> (get-shape-filter-bounds shape)
(add-padding (calculate-padding shape true))))
bounds
(cph/reduce-objects
objects
(fn [shape]
(and (d/not-empty? (:shapes shape))
(or (not (cph/frame-shape? shape))
(:show-content shape))
(or (not (cph/group-shape? shape))
(not (:masked-group? shape)))))
(:id shape)
(fn [result shape]
(conj result (get-object-bounds objects shape)))
[(calculate-base-bounds shape)])
children-bounds (or (:children-bounds shape) (gsr/join-selrects bounds))
filters (shape->filters shape)
blur-value (or (-> shape :blur :value) 0)]
(get-rect-filter-bounds children-bounds filters blur-value)))

View file

@ -657,7 +657,10 @@
(reduce-objects objects nil reducer-fn init-val))
([objects check-children? reducer-fn init-val]
(let [root-children (get-in objects [uuid/zero :shapes])]
(reduce-objects objects check-children? uuid/zero reducer-fn init-val))
([objects check-children? root-id reducer-fn init-val]
(let [root-children (get-in objects [root-id :shapes])]
(if (empty? root-children)
init-val

View file

@ -359,7 +359,6 @@
(p/let [params {:file-id file-id
:page-id page-id
:render-texts true
:render-embed true
:object-id (mapv :id objects)
:route "objects"}

View file

@ -147,6 +147,7 @@
height: 120px;
border: 1px solid $color-gray-20;
border-radius: 2px;
padding: 4px;
display: flex;
justify-content: center;

View file

@ -14,11 +14,11 @@
(:require
["react-dom/server" :as rds]
[app.common.colors :as clr]
[app.common.data :as d]
[app.common.data.macros :as dm]
[app.common.geom.matrix :as gmt]
[app.common.geom.point :as gpt]
[app.common.geom.shapes :as gsh]
[app.common.geom.shapes.bounds :as gsb]
[app.common.math :as mth]
[app.common.pages.helpers :as cph]
[app.config :as cfg]
@ -28,7 +28,6 @@
[app.main.ui.shapes.circle :as circle]
[app.main.ui.shapes.embed :as embed]
[app.main.ui.shapes.export :as export]
[app.main.ui.shapes.filters :as filters]
[app.main.ui.shapes.frame :as frame]
[app.main.ui.shapes.group :as group]
[app.main.ui.shapes.image :as image]
@ -61,13 +60,11 @@
(defn- calculate-dimensions
[objects]
(let [rect
(let [bounds
(->> (cph/get-root-objects objects)
(map #(if (some? (:children-bounds %))
(:children-bounds %)
(gsh/points->selrect (:points %))))
(gsh/join-selrects))]
(-> rect
(map (partial gsb/get-object-bounds objects))
(gsh/join-rects))]
(-> bounds
(update :x mth/finite 0)
(update :y mth/finite 0)
(update :width mth/finite 100000)
@ -193,36 +190,12 @@
(reduce updt-fn objects mod-ids)))
(defn get-object-bounds
[objects object-id]
(let [object (get objects object-id)
padding (filters/calculate-padding object true)
bounds (-> (filters/get-filters-bounds object)
(update :x - (:horizontal padding))
(update :y - (:vertical padding))
(update :width + (* 2 (:horizontal padding)))
(update :height + (* 2 (:vertical padding))))]
(cond
(and (cph/group-shape? object) (:masked-group? object))
(get-object-bounds objects (-> object :shapes first))
(or (cph/group-shape? object)
(and (cph/frame-shape? object) (:show-content object)))
(->> (:shapes object)
(into [bounds] (map (partial get-object-bounds objects)))
(gsh/join-rects))
:else
bounds)))
(mf/defc page-svg
{::mf/wrap [mf/memo]}
[{:keys [data thumbnails? render-embed? include-metadata?] :as props
:or {render-embed? false include-metadata? false}}]
(let [objects (:objects data)
shapes (cph/get-immediate-children objects)
dim (calculate-dimensions objects)
vbox (format-viewbox dim)
bgcolor (dm/get-in data [:options :background] default-color)
@ -248,7 +221,6 @@
(when include-metadata?
[:& export/export-page {:options (:options data)}])
(let [shapes (->> shapes
(remove cph/frame-shape?)
(mapcat #(cph/get-children-with-self objects (:id %))))
@ -262,20 +234,20 @@
;; Component that serves for render frame thumbnails, mainly used in
;; the viewer and handoff
(mf/defc frame-svg
{::mf/wrap [mf/memo]}
[{:keys [objects frame zoom show-thumbnails?] :or {zoom 1} :as props}]
(let [frame-id (:id frame)
include-metadata? (mf/use-ctx export/include-metadata-ctx)
bounds (or (:children-bounds frame) (gsh/points->rect (:points frame)))
bounds (gsb/get-object-bounds objects frame)
modifier
(mf/with-memo [(:x bounds) (:y bounds)]
(-> (gpt/point (:x bounds) (:y bounds))
(gpt/negate)
(gmt/translate-matrix)))
;; Bounds without shadows/blur will be the bounds of the thumbnail
bounds2 (gsb/get-object-bounds objects (dissoc frame :shadow :blur))
delta-bounds (gpt/point (:x bounds) (:y bounds))
modifier (gmt/translate-matrix (gpt/negate delta-bounds))
children-ids
(cph/get-children-ids objects frame-id)
@ -293,19 +265,19 @@
(assoc-in [:modifiers :displacement] modifier)
(gsh/transform-shape)))
bounds
(if (:show-content frame)
(gsh/selection-rect (concat [frame] (->> children-ids (map (d/getf objects)))))
(-> frame :points gsh/points->rect))
frame
(cond-> frame
(and (some? bounds) (nil? (:children-bounds bounds)))
(assoc :children-bounds bounds))
(assoc :children-bounds bounds2))
frame-wrapper
(mf/with-memo [objects]
(frame-wrapper-factory objects))
frame (-> frame
(update-in [:children-bounds :x] - (:x delta-bounds))
(update-in [:children-bounds :y] - (:y delta-bounds)))
shape-wrapper
(mf/use-memo
(mf/deps objects)
#(shape-wrapper-factory objects))
width (* (:width bounds) zoom)
height (* (:height bounds) zoom)
@ -321,13 +293,11 @@
:xmlns:penpot (when include-metadata? "https://penpot.app/xmlns")
:fill "none"}
[:> shape-container {:shape frame}
[:& frame-wrapper {:shape frame :view-box vbox}]]]]))
[:& shape-wrapper {:shape frame}]]]))
;; Component for rendering a thumbnail of a single componenent. Mainly
;; used to render thumbnails on assets panel.
(mf/defc component-svg
{::mf/wrap [mf/memo #(mf/deferred % ts/idle-then-raf)]}
[{:keys [objects group zoom] :or {zoom 1} :as props}]
@ -375,7 +345,7 @@
(mf/defc object-svg
{::mf/wrap [mf/memo]}
[{:keys [objects object-id render-texts? render-embed?]
[{:keys [objects object-id render-embed?]
:or {render-embed? false}
:as props}]
(let [object (get objects object-id)
@ -383,30 +353,21 @@
(:hide-fill-on-export object)
(assoc :fills []))
{:keys [x y width height]} (get-object-bounds objects object-id)
vbox (dm/str x " " y " " width " " height)
frame-wrapper
(mf/with-memo [objects]
(frame-wrapper-factory objects))
group-wrapper
(mf/with-memo [objects]
(group-wrapper-factory objects))
bounds (gsb/get-object-bounds objects object)
vbox (format-viewbox bounds)
fonts (ff/shape->fonts object objects)
shape-wrapper
(mf/with-memo [objects]
(shape-wrapper-factory objects))
text-shapes (sequence (filter cph/text-shape?) (vals objects))
render-texts? (and render-texts? (d/seek (comp nil? :position-data) text-shapes))]
(shape-wrapper-factory objects))]
[:& (mf/provider export/include-metadata-ctx) {:value false}
[:& (mf/provider embed/context) {:value render-embed?}
[:svg {:id (dm/str "screenshot-" object-id)
:view-box vbox
:width width
:height height
:width (:width bounds)
:height (:height bounds)
:version "1.1"
:xmlns "http://www.w3.org/2000/svg"
:xmlnsXlink "http://www.w3.org/1999/xlink"
@ -415,30 +376,8 @@
:style {:-webkit-print-color-adjust :exact}
:fill "none"}
(let [fonts (ff/shape->fonts object objects)]
[:& ff/fontfaces-style {:fonts fonts}])
(case (:type object)
:frame [:> shape-container {:shape object}
[:& frame-wrapper {:shape object :view-box vbox}]]
:group [:> shape-container {:shape object}
[:& group-wrapper {:shape object}]]
[:& shape-wrapper {:shape object}])]
;; Auxiliary SVG for rendering text-shapes
(when render-texts?
(for [object text-shapes]
[:& (mf/provider muc/text-plain-colors-ctx) {:value true}
[:svg
{:id (dm/str "screenshot-text-" (:id object))
:view-box (dm/str "0 0 " (:width object) " " (:height object))
:width (:width object)
:height (:height object)
:version "1.1"
:xmlns "http://www.w3.org/2000/svg"
:xmlnsXlink "http://www.w3.org/1999/xlink"
:fill "none"}
[:& shape-wrapper {:shape (assoc object :x 0 :y 0)}]]]))]]))
[:& ff/fontfaces-style {:fonts fonts}]
[:& shape-wrapper {:shape object}]]]]))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; SPRITES (DEBUG)

View file

@ -9,6 +9,7 @@
[app.common.data :as d]
[app.common.data.macros :as dm]
[app.common.geom.shapes :as gsh]
[app.common.geom.shapes.bounds :as gsb]
[app.common.pages.helpers :as cph]
[app.main.ui.context :as muc]
[app.main.ui.shapes.attrs :as attrs]
@ -45,7 +46,7 @@
:center (/ (:stroke-width shape 0) 2)
:outer (:stroke-width shape 0)
0)
margin (gsh/shape-stroke-margin shape stroke-width)
margin (gsb/shape-stroke-margin shape stroke-width)
bounding-box (-> (gsh/points->selrect (:points shape))
(update :x - (+ stroke-width margin))
(update :y - (+ stroke-width margin))

View file

@ -8,8 +8,7 @@
(:require
[app.common.data :as d]
[app.common.data.macros :as dm]
[app.common.geom.shapes :as gsh]
[app.common.math :as mth]
[app.common.geom.shapes.bounds :as gsb]
[app.common.uuid :as uuid]
[app.util.color :as color]
[cuerdas.core :as str]
@ -108,34 +107,6 @@
:in2 filter-in
:result filter-id}])
(defn filter-bounds [shape filter-entry]
(let [{:keys [x y width height]} (:selrect shape)
{:keys [offset-x offset-y blur spread] :or {offset-x 0 offset-y 0 blur 0 spread 0}} (:params filter-entry)
filter-x (min x (+ x offset-x (- spread) (- blur) -5))
filter-y (min y (+ y offset-y (- spread) (- blur) -5))
filter-width (+ width (mth/abs offset-x) (* spread 2) (* blur 2) 10)
filter-height (+ height (mth/abs offset-y) (* spread 2) (* blur 2) 10)]
{:x1 filter-x
:y1 filter-y
:x2 (+ filter-x filter-width)
:y2 (+ filter-y filter-height)}))
(defn blur-filters [type value]
(->> [value]
(remove :hidden)
(filter #(= (:type %) type))
(map #(hash-map :id (str "filter_" (:id %))
:type (:type %)
:params %))))
(defn shadow-filters [type filters]
(->> filters
(remove :hidden)
(filter #(= (:style %) type))
(map #(hash-map :id (str "filter_" (:id %))
:type (:style %)
:params %))))
(mf/defc filter-entry [{:keys [entry]}]
(let [props #js {:filter-id (:id entry)
:filter-in (:filter-in entry)
@ -148,84 +119,6 @@
:image-fix [:> image-fix-filter props]
:blend-filters [:> blend-filters props])))
(defn shape->filters
[shape]
(d/concat-vec
[{:id "BackgroundImageFix" :type :image-fix}]
;; Background blur won't work in current SVG specification
;; We can revisit this in the future
#_(->> shape :blur (blur-filters :background-blur))
(->> shape :shadow (shadow-filters :drop-shadow))
[{:id "shape" :type :blend-filters}]
(->> shape :shadow (shadow-filters :inner-shadow))
(->> shape :blur (blur-filters :layer-blur))))
(defn get-filters-bounds
([shape]
(let [filters (shape->filters shape)
blur-value (or (-> shape :blur :value) 0)]
(get-filters-bounds shape filters blur-value)))
([shape filters blur-value]
(let [svg-root? (and (= :svg-raw (:type shape)) (not= :svg (get-in shape [:content :tag])))
{:keys [x y width height]} (:selrect shape)]
(if svg-root?
;; When is a raw-svg but not the root we use the whole svg as bound for the filter. Is the maximum
;; we're allowed to display
{:x x :y y :width width :height height}
;; Otherwise we calculate the bound
(let [filter-bounds (->> filters
(filter #(= :drop-shadow (:type %)))
(map (partial filter-bounds shape)))
;; We add the selrect so the minimum size will be the selrect
filter-bounds (conj filter-bounds (-> shape :points gsh/points->selrect))
x1 (apply min (map :x1 filter-bounds))
y1 (apply min (map :y1 filter-bounds))
x2 (apply max (map :x2 filter-bounds))
y2 (apply max (map :y2 filter-bounds))
x1 (- x1 (* blur-value 2))
x2 (+ x2 (* blur-value 2))
y1 (- y1 (* blur-value 2))
y2 (+ y2 (* blur-value 2))]
;; We should move the frame filter coordinates because they should be
;; relative with the frame. By default they come as absolute
{:x x1
:y y1
:width (- x2 x1)
:height (- y2 y1)})))))
(defn calculate-padding
([shape]
(calculate-padding shape false))
([shape ignore-margin?]
(let [stroke-width (apply max 0 (map #(case (:stroke-alignment % :center)
:center (/ (:stroke-width % 0) 2)
:outer (:stroke-width % 0)
0) (:strokes shape)))
margin (if ignore-margin?
0
(apply max 0 (map #(gsh/shape-stroke-margin % stroke-width) (:strokes shape))))
shadow-width (apply max 0 (map #(case (:style % :drop-shadow)
:drop-shadow (+ (mth/abs (:offset-x %)) (* (:spread %) 2) (* (:blur %) 2) 10)
0) (:shadow shape)))
shadow-height (apply max 0 (map #(case (:style % :drop-shadow)
:drop-shadow (+ (mth/abs (:offset-y %)) (* (:spread %) 2) (* (:blur %) 2) 10)
0) (:shadow shape)))]
{:horizontal (+ stroke-width margin shadow-width)
:vertical (+ stroke-width margin shadow-height)})))
(defn change-filter-in
"Adds the previous filter as `filter-in` parameter"
[filters]
@ -234,9 +127,9 @@
(mf/defc filters
[{:keys [filter-id shape]}]
(let [filters (-> shape shape->filters change-filter-in)
bounds (get-filters-bounds shape filters (or (-> shape :blur :value) 0))
padding (calculate-padding shape)
(let [filters (-> shape gsb/shape->filters change-filter-in)
bounds (gsb/get-rect-filter-bounds (:selrect shape) filters (or (-> shape :blur :value) 0))
padding (gsb/calculate-padding shape)
selrect (:selrect shape)
filter-x (/ (- (:x bounds) (:x selrect) (:horizontal padding)) (:width selrect))
filter-y (/ (- (:y bounds) (:y selrect) (:vertical padding)) (:height selrect))

View file

@ -10,7 +10,7 @@
[app.common.data.macros :as dm]
[app.common.geom.matrix :as gmt]
[app.common.geom.shapes :as gsh]
[app.main.ui.shapes.filters :as f]
[app.common.geom.shapes.bounds :as gsb]
[app.util.svg :as usvg]
[rumext.alpha :as mf]))
@ -87,7 +87,7 @@
(d/parse-double (get-in svg-def [:attrs :width]))
(d/parse-double (get-in svg-def [:attrs :height])))
(gsh/transform-rect transform))
(f/get-filters-bounds shape))))
(gsb/get-shape-filter-bounds shape))))
(mf/defc svg-defs [{:keys [shape render-id]}]
(let [svg-defs (:svg-defs shape)

View file

@ -11,7 +11,7 @@
[app.common.data.macros :as dm]
[app.common.exceptions :as ex]
[app.common.geom.point :as gpt]
[app.common.geom.shapes :as gsh]
[app.common.geom.shapes.bounds :as gsb]
[app.common.pages.helpers :as cph]
[app.common.text :as txt]
[app.main.data.comments :as dcm]
@ -23,7 +23,6 @@
[app.main.ui.context :as ctx]
[app.main.ui.hooks :as hooks]
[app.main.ui.icons :as i]
[app.main.ui.shapes.filters :as filters]
[app.main.ui.share-link]
[app.main.ui.static :as static]
[app.main.ui.viewer.comments :refer [comments-layer comments-sidebar]]
@ -39,16 +38,8 @@
[rumext.alpha :as mf]))
(defn- calculate-size
[frame zoom bounds]
(let [frame-bounds (filters/get-filters-bounds frame)
{:keys [x y width height]} (if (:show-content frame)
(gsh/join-rects [bounds frame-bounds])
frame-bounds)
padding (filters/calculate-padding frame)
x (- x (:horizontal padding))
y (- y (:vertical padding))
width (+ width (* 2 (:horizontal padding)))
height (+ height (* 2 (:vertical padding)))]
[objects frame zoom]
(let [{:keys [x y width height]} (gsb/get-object-bounds objects frame)]
{:base-width width
:base-height height
:x x
@ -83,10 +74,9 @@
[:div.counter (str/join " / " [(+ index 1) num-frames])]
[:span]]])
(mf/defc viewer-wrapper
[{:keys [wrapper-size scroll orig-frame orig-viewport-ref orig-size page file users current-viewport-ref
size frame interactions-mode overlays zoom close-overlay section index children-bounds] :as props}]
size frame interactions-mode overlays zoom close-overlay section index] :as props}]
(let [{clist :list} (mf/deref refs/comments-local)
show-comments-list (and (= section :comments) (= :show clist))]
[:*
@ -135,7 +125,7 @@
:interactions-mode interactions-mode}]
(for [overlay overlays]
(let [size-over (calculate-size (:frame overlay) zoom children-bounds)]
(let [size-over (calculate-size (:objects page) (:frame overlay) zoom)]
[:*
(when (or (:close-click-outside overlay)
(:background-overlay overlay))
@ -204,12 +194,6 @@
frames (:frames page)
frame (get frames index)
children-bounds
(mf/use-memo
(mf/deps page (:id frame))
#(-> (cph/get-children (:objects page) (:id frame))
(gsh/selection-rect)))
fullscreen? (mf/deref refs/viewer-fullscreen?)
overlays (:overlays local)
scroll (mf/use-state nil)
@ -219,13 +203,13 @@
(d/seek #(= (:id %) (:orig-frame-id current-animation)) frames))
size (mf/use-memo
(mf/deps frame zoom children-bounds)
(fn [] (calculate-size frame zoom children-bounds)))
(mf/deps frame zoom)
(fn [] (calculate-size (:objects page) frame zoom)))
orig-size (mf/use-memo
(mf/deps orig-frame zoom)
(fn [] (when orig-frame
(calculate-size orig-frame zoom children-bounds))))
(calculate-size (:objects page) orig-frame zoom))))
wrapper-size (mf/use-memo
(mf/deps size orig-size zoom)
@ -318,7 +302,7 @@
wrapper-size)))))
(mf/use-layout-effect
(mf/deps current-animation children-bounds)
(mf/deps current-animation)
(fn []
;; Overlay animations may be started when needed.
(when current-animation
@ -328,7 +312,7 @@
(let [overlay-viewport (dom/get-element (str "overlay-" (str (:overlay-id current-animation))))
overlay (d/seek #(= (:id (:frame %)) (:overlay-id current-animation))
overlays)
overlay-size (calculate-size (:frame overlay) zoom children-bounds)
overlay-size (calculate-size (:objects page) (:frame overlay) zoom)
overlay-position {:x (* (:x (:position overlay)) zoom)
:y (* (:y (:position overlay)) zoom)}]
(interactions/animate-open-overlay
@ -342,7 +326,7 @@
(let [overlay-viewport (dom/get-element (str "overlay-" (str (:overlay-id current-animation))))
overlay (d/seek #(= (:id (:frame %)) (:overlay-id current-animation))
overlays)
overlay-size (calculate-size (:frame overlay) zoom children-bounds)
overlay-size (calculate-size (:objects page) (:frame overlay) zoom)
overlay-position {:x (* (:x (:position overlay)) zoom)
:y (* (:y (:position overlay)) zoom)}]
(interactions/animate-close-overlay
@ -427,8 +411,7 @@
:overlays overlays
:zoom zoom
:section section
:index index
:children-bounds children-bounds}]))]]]))
:index index}]))]]]))
;; --- Component: Viewer Page

View file

@ -98,7 +98,7 @@
state))
(mf/defc object-svg
[{:keys [page-id file-id object-id render-embed? render-texts?]}]
[{:keys [page-id file-id object-id render-embed?]}]
(let [fetch-state (mf/use-fn
(mf/deps file-id page-id object-id)
(fn []
@ -131,11 +131,10 @@
[:& render/object-svg
{:objects objects
:object-id object-id
:render-embed? render-embed?
:render-texts? render-texts?}])))
:render-embed? render-embed?}])))
(mf/defc objects-svg
[{:keys [page-id file-id object-ids render-embed? render-texts?]}]
[{:keys [page-id file-id object-ids render-embed?]}]
(let [fetch-state (mf/use-fn
(mf/deps file-id page-id)
(fn []
@ -157,27 +156,24 @@
{:objects objects
:key (str object-id)
:object-id object-id
:render-embed? render-embed?
:render-texts? render-texts?}])))))
:render-embed? render-embed?}])))))
(s/def ::page-id ::us/uuid)
(s/def ::file-id ::us/uuid)
(s/def ::object-id
(s/or :single ::us/uuid
:multiple (s/coll-of ::us/uuid)))
(s/def ::render-text ::us/boolean)
(s/def ::embed ::us/boolean)
(s/def ::render-objects
(s/keys :req-un [::file-id ::page-id ::object-id]
:opt-un [::render-text ::render-embed]))
:opt-un [::render-embed]))
(defn- render-objects
[params]
(let [{:keys [file-id
page-id
render-embed
render-texts]
render-embed]
:as params}
(us/conform ::render-objects params)
@ -190,8 +186,7 @@
{:file-id file-id
:page-id page-id
:object-id object-id
:render-embed? render-embed
:render-texts? render-texts}])
:render-embed? render-embed}])
:multiple
(mf/html
@ -199,8 +194,7 @@
{:file-id file-id
:page-id page-id
:object-ids (into #{} object-id)
:render-embed? render-embed
:render-texts? render-texts}]))))
:render-embed? render-embed}]))))
;; ---- COMPONENTS SPRITE