From 996a614ed759d2fb16abbc5d8141ffa00776209c Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Thu, 6 Jul 2023 15:50:02 +0200 Subject: [PATCH] :bug: Fix grid not being cutted in frames --- CHANGES.md | 1 + common/src/app/common/geom/shapes/rect.cljc | 4 +- frontend/src/app/main/refs.cljs | 9 +++ .../ui/workspace/viewport/frame_grid.cljs | 75 ++++++++++++++----- 4 files changed, 70 insertions(+), 19 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 6334e4f3d..45d018adf 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -47,6 +47,7 @@ - Fix problem with comments mode not staying [#3363](https://github.com/penpot/penpot/issues/3363) - Fix problem with comments when user left the team [Taiga #5562](https://tree.taiga.io/project/penpot/issue/5562) - Fix problem with images patterns repeating [#3372](https://github.com/penpot/penpot/issues/3372) +- Fix grid not being clipped in frames [#3365](https://github.com/penpot/penpot/issues/3365) ### :arrow_up: Deps updates diff --git a/common/src/app/common/geom/shapes/rect.cljc b/common/src/app/common/geom/shapes/rect.cljc index 258ed0cd3..c304b99f4 100644 --- a/common/src/app/common/geom/shapes/rect.cljc +++ b/common/src/app/common/geom/shapes/rect.cljc @@ -218,7 +218,7 @@ (make-selrect (min xp1 xp2) (min yp1 yp2) (abs (- xp1 xp2)) (abs (- yp1 yp2))))) (defn clip-selrect - [{:keys [x1 y1 x2 y2] :as sr} bounds] + [{:keys [x1 y1 x2 y2] :as sr} clip-rect] (when (some? sr) - (let [{bx1 :x1 by1 :y1 bx2 :x2 by2 :y2} (rect->selrect bounds)] + (let [{bx1 :x1 by1 :y1 bx2 :x2 by2 :y2 :as sr2} (rect->selrect clip-rect)] (corners->selrect (max bx1 x1) (max by1 y1) (min bx2 x2) (min by2 y2))))) diff --git a/frontend/src/app/main/refs.cljs b/frontend/src/app/main/refs.cljs index 92190f031..bcb78e7a4 100644 --- a/frontend/src/app/main/refs.cljs +++ b/frontend/src/app/main/refs.cljs @@ -298,6 +298,15 @@ (into [] (keep #(get objects %)) parent-ids))) workspace-page-objects =)) +(defn shape-parents + [id] + (l/derived + (fn [objects] + (into [] + (keep (d/getf objects)) + (cph/get-parent-ids objects id))) + workspace-page-objects =)) + (defn children-objects [id] (l/derived diff --git a/frontend/src/app/main/ui/workspace/viewport/frame_grid.cljs b/frontend/src/app/main/ui/workspace/viewport/frame_grid.cljs index c7b403286..37a726586 100644 --- a/frontend/src/app/main/ui/workspace/viewport/frame_grid.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/frame_grid.cljs @@ -7,7 +7,10 @@ (ns app.main.ui.workspace.viewport.frame-grid (: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.pages.helpers :as cph] [app.common.types.shape-tree :as ctst] [app.common.uuid :as uuid] [app.main.refs :as refs] @@ -109,32 +112,70 @@ :strokeOpacity color-opacity :fill "none"}}]]))])) +(defn frame-clip-area + [{:keys [selrect]} parents] + (reduce + (fn [sr parent] + (cond-> sr + (and (not (cph/root? parent)) + (cph/frame-shape? parent) + (not (:show-content parent))) + (gsh/clip-selrect (:selrect parent)))) + selrect + parents)) + (mf/defc grid-display-frame - [{:keys [frame zoom]}] - (for [[index grid] (->> (:grids frame) - (filter :display) - (map-indexed vector))] - (let [props #js {:key (str (:id frame) "-grid-" index) - :frame frame - :zoom zoom - :grid grid}] - (case (:type grid) - :square [:> square-grid props] - :column [:> layout-grid props] - :row [:> layout-grid props])))) + {::mf/wrap [mf/memo]} + [{:keys [frame zoom transforming]}] + (let [frame-id (:id frame) + parents-ref (mf/with-memo [frame-id] (refs/shape-parents frame-id)) + parents (mf/deref parents-ref) + clip-area (frame-clip-area frame parents) + clip-id (dm/str (:id frame) "-grid-clip") + + transform? + (or (contains? transforming frame-id) + (some #(contains? transforming %) (map :id parents)))] + + (when-not transform? + [:g {:clip-path (dm/fmt "url(#%)" clip-id)} + [:defs + [:clipPath {:id clip-id} + [:rect {:x (:x clip-area) + :y (:y clip-area) + :width (:width clip-area) + :height (:height clip-area)}]]] + + (for [[index grid] (->> (:grids frame) + (filter :display) + (map-indexed vector))] + (let [props #js {:key (str (:id frame) "-grid-" index) + :frame frame + :zoom zoom + :grid grid}] + (case (:type grid) + :square [:> square-grid props] + :column [:> layout-grid props] + :row [:> layout-grid props])))]))) + +(defn has-grid? + [{:keys [grids]}] + (and (some? grids) + (d/not-empty? (->> grids (filter :display))))) (mf/defc frame-grid {::mf/wrap [mf/memo]} [{:keys [zoom transform selected focus]}] - (let [frames (mf/deref refs/workspace-frames) - transforming (when (some? transform) selected) - is-transform? #(contains? transforming (:id %))] + (let [frames (->> (mf/deref refs/workspace-frames) + (filter has-grid?)) + transforming (when (some? transform) selected)] [:g.grid-display {:style {:pointer-events "none"}} (for [frame frames] - (when (and (not (is-transform? frame)) + (when (and #_(not (is-transform? frame)) (not (ctst/rotated-frame? frame)) (or (empty? focus) (contains? focus (:id frame)))) [:& grid-display-frame {:key (str "grid-" (:id frame)) :zoom zoom - :frame frame}]))])) + :frame frame + :transforming transforming}]))]))