mirror of
https://github.com/penpot/penpot.git
synced 2025-05-06 13:05:54 +02:00
Merge pull request #3628 from penpot/niwinz-develop-bugfixes-4
⚡ Don't render not visible shapes on workspace
This commit is contained in:
commit
aa62b9d248
9 changed files with 119 additions and 107 deletions
|
@ -275,21 +275,19 @@
|
||||||
[a b]
|
[a b]
|
||||||
(mth/almost-zero? (- a b)))
|
(mth/almost-zero? (- a b)))
|
||||||
|
|
||||||
;; FIXME: performance
|
|
||||||
(defn overlaps-rects?
|
(defn overlaps-rects?
|
||||||
"Check for two rects to overlap. Rects won't overlap only if
|
"Check for two rects to overlap. Rects won't overlap only if
|
||||||
one of them is fully to the left or the top"
|
one of them is fully to the left or the top"
|
||||||
[rect-a rect-b]
|
[rect-a rect-b]
|
||||||
|
(let [x1a (dm/get-prop rect-a :x)
|
||||||
|
y1a (dm/get-prop rect-a :y)
|
||||||
|
x2a (+ x1a (dm/get-prop rect-a :width))
|
||||||
|
y2a (+ y1a (dm/get-prop rect-a :height))
|
||||||
|
|
||||||
(let [x1a (:x rect-a)
|
x1b (dm/get-prop rect-b :x)
|
||||||
y1a (:y rect-a)
|
y1b (dm/get-prop rect-b :y)
|
||||||
x2a (+ (:x rect-a) (:width rect-a))
|
x2b (+ x1b (dm/get-prop rect-b :width))
|
||||||
y2a (+ (:y rect-a) (:height rect-a))
|
y2b (+ y1b (dm/get-prop rect-b :height))]
|
||||||
|
|
||||||
x1b (:x rect-b)
|
|
||||||
y1b (:y rect-b)
|
|
||||||
x2b (+ (:x rect-b) (:width rect-b))
|
|
||||||
y2b (+ (:y rect-b) (:height rect-b))]
|
|
||||||
|
|
||||||
(and (or (> x2a x1b) (s= x2a x1b))
|
(and (or (> x2a x1b) (s= x2a x1b))
|
||||||
(or (>= x2b x1a) (s= x2b x1a))
|
(or (>= x2b x1a) (s= x2b x1a))
|
||||||
|
|
|
@ -307,12 +307,12 @@
|
||||||
(defn overlaps?
|
(defn overlaps?
|
||||||
"General case to check for overlapping between shapes and a rectangle"
|
"General case to check for overlapping between shapes and a rectangle"
|
||||||
[shape rect]
|
[shape rect]
|
||||||
(let [stroke-width (/ (or (:stroke-width shape) 0) 2)
|
(let [swidth (/ (or (:stroke-width shape) 0) 2)
|
||||||
rect (-> rect
|
rect (-> rect
|
||||||
(update :x - stroke-width)
|
(update :x - swidth)
|
||||||
(update :y - stroke-width)
|
(update :y - swidth)
|
||||||
(update :width + (* 2 stroke-width))
|
(update :width + (* 2 swidth))
|
||||||
(update :height + (* 2 stroke-width)))]
|
(update :height + (* 2 swidth)))]
|
||||||
(or (not shape)
|
(or (not shape)
|
||||||
(cond
|
(cond
|
||||||
(cph/path-shape? shape)
|
(cph/path-shape? shape)
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
(def current-project-id (mf/create-context nil))
|
(def current-project-id (mf/create-context nil))
|
||||||
(def current-page-id (mf/create-context nil))
|
(def current-page-id (mf/create-context nil))
|
||||||
(def current-file-id (mf/create-context nil))
|
(def current-file-id (mf/create-context nil))
|
||||||
|
(def current-vbox (mf/create-context nil))
|
||||||
|
|
||||||
(def active-frames (mf/create-context nil))
|
(def active-frames (mf/create-context nil))
|
||||||
(def render-thumbnails (mf/create-context nil))
|
(def render-thumbnails (mf/create-context nil))
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
common."
|
common."
|
||||||
(:require
|
(:require
|
||||||
[app.common.data.macros :as dm]
|
[app.common.data.macros :as dm]
|
||||||
|
[app.common.geom.rect :as grc]
|
||||||
[app.common.pages.helpers :as cph]
|
[app.common.pages.helpers :as cph]
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
[app.main.ui.context :as ctx]
|
[app.main.ui.context :as ctx]
|
||||||
|
@ -49,15 +50,14 @@
|
||||||
(let [objects (obj/get props "objects")
|
(let [objects (obj/get props "objects")
|
||||||
active-frames (obj/get props "active-frames")
|
active-frames (obj/get props "active-frames")
|
||||||
shapes (cph/get-immediate-children objects)
|
shapes (cph/get-immediate-children objects)
|
||||||
|
vbox (mf/use-ctx ctx/current-vbox)
|
||||||
|
|
||||||
;; vbox (mf/use-ctx ctx/current-vbox)
|
shapes (mf/with-memo [shapes vbox]
|
||||||
;; shapes (mf/with-memo [shapes vbox]
|
(if (some? vbox)
|
||||||
;; (if (some? vbox)
|
(filter (fn [shape]
|
||||||
;; (filter (fn [shape]
|
(grc/overlaps-rects? vbox (dm/get-prop shape :selrect)))
|
||||||
;; (grc/overlaps-rects? vbox (dm/get-prop shape :selrect)))
|
shapes)
|
||||||
;; shapes)
|
shapes))]
|
||||||
;; shapes))
|
|
||||||
]
|
|
||||||
|
|
||||||
[:g {:id (dm/str "shape-" uuid/zero)}
|
[:g {:id (dm/str "shape-" uuid/zero)}
|
||||||
[:& (mf/provider ctx/active-frames) {:value active-frames}
|
[:& (mf/provider ctx/active-frames) {:value active-frames}
|
||||||
|
|
|
@ -73,6 +73,7 @@
|
||||||
(fdm/use-dynamic-modifiers objects (mf/ref-val node-ref) modifiers)
|
(fdm/use-dynamic-modifiers objects (mf/ref-val node-ref) modifiers)
|
||||||
[:& frame-shape {:shape shape :ref node-ref}]))))
|
[:& frame-shape {:shape shape :ref node-ref}]))))
|
||||||
|
|
||||||
|
|
||||||
(defn root-frame-wrapper-factory
|
(defn root-frame-wrapper-factory
|
||||||
[shape-wrapper]
|
[shape-wrapper]
|
||||||
|
|
||||||
|
@ -86,9 +87,9 @@
|
||||||
thumbnail? (unchecked-get props "thumbnail?")
|
thumbnail? (unchecked-get props "thumbnail?")
|
||||||
|
|
||||||
page-id (mf/use-ctx ctx/current-page-id)
|
page-id (mf/use-ctx ctx/current-page-id)
|
||||||
frame-id (:id shape)
|
frame-id (dm/get-prop shape :id)
|
||||||
|
|
||||||
objects (wsh/lookup-page-objects @st/state)
|
objects (wsh/lookup-page-objects @st/state page-id)
|
||||||
|
|
||||||
node-ref (mf/use-ref nil)
|
node-ref (mf/use-ref nil)
|
||||||
root-ref (mf/use-ref nil)
|
root-ref (mf/use-ref nil)
|
||||||
|
@ -114,6 +115,7 @@
|
||||||
|
|
||||||
on-frame-load
|
on-frame-load
|
||||||
(fns/use-node-store node-ref rendered-ref thumbnail? render-frame?)
|
(fns/use-node-store node-ref rendered-ref thumbnail? render-frame?)
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|
||||||
(fdm/use-dynamic-modifiers objects (mf/ref-val node-ref) modifiers)
|
(fdm/use-dynamic-modifiers objects (mf/ref-val node-ref) modifiers)
|
||||||
|
|
|
@ -225,8 +225,8 @@
|
||||||
:spell-check false
|
:spell-check false
|
||||||
:on-change on-filter-change}]
|
:on-change on-filter-change}]
|
||||||
(when (and recent-fonts show-recent)
|
(when (and recent-fonts show-recent)
|
||||||
[:hr]
|
[:*
|
||||||
[*
|
[:hr]
|
||||||
[:p.title (tr "workspace.options.recent-fonts")]
|
[:p.title (tr "workspace.options.recent-fonts")]
|
||||||
(for [[idx font] (d/enumerate recent-fonts)]
|
(for [[idx font] (d/enumerate recent-fonts)]
|
||||||
[:& font-item {:key (dm/str "font-" idx)
|
[:& font-item {:key (dm/str "font-" idx)
|
||||||
|
|
|
@ -88,6 +88,8 @@
|
||||||
show-distances?
|
show-distances?
|
||||||
picking-color?]} wglobal
|
picking-color?]} wglobal
|
||||||
|
|
||||||
|
vbox' (mf/use-debounce 100 vbox)
|
||||||
|
|
||||||
;; CONTEXT
|
;; CONTEXT
|
||||||
page-id (mf/use-ctx ctx/current-page-id)
|
page-id (mf/use-ctx ctx/current-page-id)
|
||||||
|
|
||||||
|
@ -323,12 +325,13 @@
|
||||||
:y (:y vbox 0)
|
:y (:y vbox 0)
|
||||||
:fill background}]
|
:fill background}]
|
||||||
|
|
||||||
[:& (mf/provider use/include-metadata-ctx) {:value (debug? :show-export-metadata)}
|
[:& (mf/provider ctx/current-vbox) {:value vbox'}
|
||||||
[:& (mf/provider embed/context) {:value true}
|
[:& (mf/provider use/include-metadata-ctx) {:value (debug? :show-export-metadata)}
|
||||||
;; Render root shape
|
[:& (mf/provider embed/context) {:value true}
|
||||||
[:& shapes/root-shape {:key page-id
|
;; Render root shape
|
||||||
:objects base-objects
|
[:& shapes/root-shape {:key page-id
|
||||||
:active-frames @active-frames}]]]]
|
:objects base-objects
|
||||||
|
:active-frames @active-frames}]]]]]
|
||||||
|
|
||||||
[:svg.viewport-controls
|
[:svg.viewport-controls
|
||||||
{:xmlns "http://www.w3.org/2000/svg"
|
{:xmlns "http://www.w3.org/2000/svg"
|
||||||
|
|
|
@ -409,16 +409,25 @@
|
||||||
(defn bounding-rect->rect
|
(defn bounding-rect->rect
|
||||||
[rect]
|
[rect]
|
||||||
(when (some? rect)
|
(when (some? rect)
|
||||||
{:x (or (.-left rect) (:left rect) 0)
|
(grc/make-rect
|
||||||
:y (or (.-top rect) (:top rect) 0)
|
(or (.-left rect) (:left rect) 0)
|
||||||
:width (or (.-width rect) (:width rect) 1)
|
(or (.-top rect) (:top rect) 0)
|
||||||
:height (or (.-height rect) (:height rect) 1)}))
|
(or (.-width rect) (:width rect) 1)
|
||||||
|
(or (.-height rect) (:height rect) 1))))
|
||||||
|
|
||||||
(defn get-window-size
|
(defn get-window-size
|
||||||
[]
|
[]
|
||||||
{:width (.-innerWidth ^js js/window)
|
{:width (.-innerWidth ^js js/window)
|
||||||
:height (.-innerHeight ^js js/window)})
|
:height (.-innerHeight ^js js/window)})
|
||||||
|
|
||||||
|
(defn get-computed-styles
|
||||||
|
[node]
|
||||||
|
(js/getComputedStyle node))
|
||||||
|
|
||||||
|
(defn get-property-value
|
||||||
|
[o prop]
|
||||||
|
(.getPropertyValue ^js o prop))
|
||||||
|
|
||||||
(defn focus!
|
(defn focus!
|
||||||
[^js node]
|
[^js node]
|
||||||
(when (some? node)
|
(when (some? node)
|
||||||
|
|
|
@ -12,22 +12,21 @@
|
||||||
[app.main.fonts :as fonts]
|
[app.main.fonts :as fonts]
|
||||||
[app.util.dom :as dom]
|
[app.util.dom :as dom]
|
||||||
[app.util.text-position-data :as tpd]
|
[app.util.text-position-data :as tpd]
|
||||||
|
[cuerdas.core :as str]
|
||||||
[promesa.core :as p]))
|
[promesa.core :as p]))
|
||||||
|
|
||||||
(defn parse-text-nodes
|
(defn parse-text-nodes
|
||||||
"Given a text node retrieves the rectangles for everyone of its paragraphs and its text."
|
"Given a text node retrieves the rectangles for everyone of its paragraphs and its text."
|
||||||
[parent-node direction text-node text-align]
|
[parent-node direction text-node text-align]
|
||||||
|
|
||||||
(letfn [(parse-entry [^js entry]
|
(letfn [(parse-entry [^js entry]
|
||||||
(when (some? (.-position entry))
|
(when (some? (.-position entry))
|
||||||
{:node (.-node entry)
|
{:node (.-node entry)
|
||||||
:position (dom/bounding-rect->rect (.-position entry))
|
:position (dom/bounding-rect->rect (.-position entry))
|
||||||
:text (.-text entry)
|
:text (.-text entry)
|
||||||
:direction direction}))]
|
:direction direction}))]
|
||||||
(into
|
(into []
|
||||||
[]
|
(keep parse-entry)
|
||||||
(keep parse-entry)
|
(tpd/parse-text-nodes parent-node text-node text-align))))
|
||||||
(tpd/parse-text-nodes parent-node text-node text-align))))
|
|
||||||
|
|
||||||
(def load-promises (atom {}))
|
(def load-promises (atom {}))
|
||||||
|
|
||||||
|
@ -40,76 +39,76 @@
|
||||||
load-promise)))
|
load-promise)))
|
||||||
|
|
||||||
(defn resolve-font
|
(defn resolve-font
|
||||||
[^js node]
|
[node]
|
||||||
|
(let [styles (dom/get-computed-styles node)
|
||||||
|
font (dom/get-property-value styles "font")
|
||||||
|
font (if (or (not font) (empty? font))
|
||||||
|
;; Firefox 95 won't return the font correctly.
|
||||||
|
;; We can get the font shorthand with the font-size + font-family
|
||||||
|
(str/ffmt "% %"
|
||||||
|
(dom/get-property-value styles "font-size")
|
||||||
|
(dom/get-property-value styles "font-family"))
|
||||||
|
font)
|
||||||
|
|
||||||
(let [styles (js/getComputedStyle node)
|
font-id (dom/get-property-value styles "--font-id")]
|
||||||
font (.getPropertyValue styles "font")
|
|
||||||
font (if (or (not font) (empty? font))
|
|
||||||
;; Firefox 95 won't return the font correctly.
|
|
||||||
;; We can get the font shorthand with the font-size + font-family
|
|
||||||
(dm/str (.getPropertyValue styles "font-size")
|
|
||||||
" "
|
|
||||||
(.getPropertyValue styles "font-family"))
|
|
||||||
font)
|
|
||||||
|
|
||||||
font-id (.getPropertyValue styles "--font-id")]
|
(->> (fonts/ensure-loaded! font-id)
|
||||||
|
(p/fmap (fn []
|
||||||
|
(when-not ^boolean (dom/check-font? font)
|
||||||
|
(load-font font))))
|
||||||
|
(p/merr (fn [_cause]
|
||||||
|
(js/console.error (str/ffmt "Cannot load font %" font-id))
|
||||||
|
(p/resolved nil))))))
|
||||||
|
|
||||||
(-> (fonts/ensure-loaded! font-id)
|
|
||||||
(p/then #(when (not (dom/check-font? font))
|
(defn- process-text-node
|
||||||
(load-font font)))
|
[parent-node]
|
||||||
(p/catch #(.error js/console (dm/str "Cannot load font " font-id) %)))))
|
(let [root (dom/get-parent-with-selector parent-node ".text-node-html")
|
||||||
|
paragraph (dom/get-parent-with-selector parent-node ".paragraph")
|
||||||
|
shape-x (d/parse-double (dom/get-attribute root "data-x"))
|
||||||
|
shape-y (d/parse-double (dom/get-attribute root "data-y"))
|
||||||
|
direction (.-direction ^js (dom/get-computed-styles parent-node))
|
||||||
|
text-align (.-textAlign ^js (dom/get-computed-styles paragraph))]
|
||||||
|
|
||||||
|
(sequence
|
||||||
|
(comp
|
||||||
|
(mapcat #(parse-text-nodes parent-node direction % text-align))
|
||||||
|
(map #(-> %
|
||||||
|
(update-in [:position :x] + shape-x)
|
||||||
|
(update-in [:position :y] + shape-y))))
|
||||||
|
(seq (.-childNodes parent-node)))))
|
||||||
|
|
||||||
(defn- calc-text-node-positions
|
(defn- calc-text-node-positions
|
||||||
[shape-id]
|
[shape-id]
|
||||||
|
(let [text-nodes (-> (dom/query (dm/fmt "#html-text-node-%" shape-id))
|
||||||
(when (some? shape-id)
|
(dom/query-all ".text-node"))]
|
||||||
(let [text-nodes (-> (dom/query (dm/fmt "#html-text-node-%" shape-id))
|
(->> (p/all (map resolve-font text-nodes))
|
||||||
(dom/query-all ".text-node"))
|
(p/fmap #(mapcat process-text-node text-nodes)))))
|
||||||
load-fonts (->> text-nodes (map resolve-font))
|
|
||||||
|
|
||||||
process-text-node
|
|
||||||
(fn [parent-node]
|
|
||||||
(let [root (dom/get-parent-with-selector parent-node ".text-node-html")
|
|
||||||
paragraph (dom/get-parent-with-selector parent-node ".paragraph")
|
|
||||||
shape-x (-> (dom/get-attribute root "data-x") d/parse-double)
|
|
||||||
shape-y (-> (dom/get-attribute root "data-y") d/parse-double)
|
|
||||||
direction (.-direction (js/getComputedStyle parent-node))
|
|
||||||
text-align (.-textAlign (js/getComputedStyle paragraph))]
|
|
||||||
|
|
||||||
(->> (.-childNodes parent-node)
|
|
||||||
(mapcat #(parse-text-nodes parent-node direction % text-align))
|
|
||||||
(mapv #(-> %
|
|
||||||
(update-in [:position :x] + shape-x)
|
|
||||||
(update-in [:position :y] + shape-y))))))]
|
|
||||||
(-> (p/all load-fonts)
|
|
||||||
(p/then
|
|
||||||
(fn []
|
|
||||||
(->> text-nodes (mapcat process-text-node))))))))
|
|
||||||
|
|
||||||
(defn calc-position-data
|
(defn calc-position-data
|
||||||
[shape-id]
|
[shape-id]
|
||||||
(when (some? shape-id)
|
(letfn [(get-prop [styles prop]
|
||||||
(p/let [text-data (calc-text-node-positions shape-id)]
|
(let [value (.getPropertyValue styles prop)]
|
||||||
(->> text-data
|
(when (and (some? value) (not= value ""))
|
||||||
(mapv (fn [{:keys [node position text direction]}]
|
value)))
|
||||||
(let [{:keys [x y width height]} position
|
|
||||||
styles (js/getComputedStyle ^js node)
|
(transform-data [{:keys [node position text direction]}]
|
||||||
get (fn [prop]
|
(let [styles (dom/get-computed-styles node)
|
||||||
(let [value (.getPropertyValue styles prop)]
|
position (assoc position :y (+ (dm/get-prop position :y)
|
||||||
(when (and value (not= value ""))
|
(dm/get-prop position :height)))]
|
||||||
value)))]
|
(into position (filter val)
|
||||||
(d/without-nils
|
{:direction direction
|
||||||
{:x x
|
:font-family (dm/str (get-prop styles "font-family"))
|
||||||
:y (+ y height)
|
:font-size (dm/str (get-prop styles "font-size"))
|
||||||
:width width
|
:font-weight (dm/str (get-prop styles "font-weight"))
|
||||||
:height height
|
:text-transform (dm/str (get-prop styles "text-transform"))
|
||||||
:direction direction
|
:text-decoration (dm/str (get-prop styles "text-decoration"))
|
||||||
:font-family (str (get "font-family"))
|
:letter-spacing (dm/str (get-prop styles "letter-spacing"))
|
||||||
:font-size (str (get "font-size"))
|
:font-style (dm/str (get-prop styles "font-style"))
|
||||||
:font-weight (str (get "font-weight"))
|
:fills (transit/decode-str (get-prop styles "--fills"))
|
||||||
:text-transform (str (get "text-transform"))
|
:text text})))]
|
||||||
:text-decoration (str (get "text-decoration"))
|
|
||||||
:letter-spacing (str (get "letter-spacing"))
|
(when (some? shape-id)
|
||||||
:font-style (str (get "font-style"))
|
(->> (calc-text-node-positions shape-id)
|
||||||
:fills (transit/decode-str (get "--fills"))
|
(p/fmap (fn [text-data]
|
||||||
:text text}))))))))
|
(mapv transform-data text-data)))))))
|
||||||
|
|
Loading…
Add table
Reference in a new issue