mirror of
https://github.com/penpot/penpot.git
synced 2026-08-01 10:56:20 +00:00
commit
fdbabe49df
@ -43,7 +43,11 @@
|
|||||||
- Fix validation on team name input [Taiga #5510](https://tree.taiga.io/project/penpot/issue/5510)
|
- Fix validation on team name input [Taiga #5510](https://tree.taiga.io/project/penpot/issue/5510)
|
||||||
- Fix incorrect uri generation issues on share-link modal [Taiga #5564](https://tree.taiga.io/project/penpot/issue/5564)
|
- Fix incorrect uri generation issues on share-link modal [Taiga #5564](https://tree.taiga.io/project/penpot/issue/5564)
|
||||||
- Fix cache issues with share-links [Taiga #5559](https://tree.taiga.io/project/penpot/issue/5559)
|
- Fix cache issues with share-links [Taiga #5559](https://tree.taiga.io/project/penpot/issue/5559)
|
||||||
|
- Makes height priority for the rows/columns grids [#2774](https://github.com/penpot/penpot/issues/2774)
|
||||||
|
- 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
|
### :arrow_up: Deps updates
|
||||||
|
|
||||||
|
|||||||
@ -218,7 +218,7 @@
|
|||||||
(make-selrect (min xp1 xp2) (min yp1 yp2) (abs (- xp1 xp2)) (abs (- yp1 yp2)))))
|
(make-selrect (min xp1 xp2) (min yp1 yp2) (abs (- xp1 xp2)) (abs (- yp1 yp2)))))
|
||||||
|
|
||||||
(defn clip-selrect
|
(defn clip-selrect
|
||||||
[{:keys [x1 y1 x2 y2] :as sr} bounds]
|
[{:keys [x1 y1 x2 y2] :as sr} clip-rect]
|
||||||
(when (some? sr)
|
(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)))))
|
(corners->selrect (max bx1 x1) (max by1 y1) (min bx2 x2) (min by2 y2)))))
|
||||||
|
|||||||
@ -282,7 +282,7 @@
|
|||||||
(fetched [[users comments] state]
|
(fetched [[users comments] state]
|
||||||
(let [state (-> state
|
(let [state (-> state
|
||||||
(assoc :comment-threads (d/index-by :id comments))
|
(assoc :comment-threads (d/index-by :id comments))
|
||||||
(assoc :current-file-comments-users (d/index-by :id users)))]
|
(update :current-file-comments-users merge (d/index-by :id users)))]
|
||||||
(reduce set-comment-threds state comments)))]
|
(reduce set-comment-threds state comments)))]
|
||||||
|
|
||||||
(ptk/reify ::retrieve-comment-threads
|
(ptk/reify ::retrieve-comment-threads
|
||||||
|
|||||||
@ -298,6 +298,15 @@
|
|||||||
(into [] (keep #(get objects %)) parent-ids)))
|
(into [] (keep #(get objects %)) parent-ids)))
|
||||||
workspace-page-objects =))
|
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
|
(defn children-objects
|
||||||
[id]
|
[id]
|
||||||
(l/derived
|
(l/derived
|
||||||
|
|||||||
@ -16,6 +16,8 @@
|
|||||||
[app.util.object :as obj]
|
[app.util.object :as obj]
|
||||||
[rumext.v2 :as mf]))
|
[rumext.v2 :as mf]))
|
||||||
|
|
||||||
|
(def no-repeat-padding 1.05)
|
||||||
|
|
||||||
(mf/defc fills
|
(mf/defc fills
|
||||||
{::mf/wrap-props false}
|
{::mf/wrap-props false}
|
||||||
[props]
|
[props]
|
||||||
@ -71,7 +73,10 @@
|
|||||||
|
|
||||||
(let [fill-id (dm/str "fill-" shape-index "-" render-id)]
|
(let [fill-id (dm/str "fill-" shape-index "-" render-id)]
|
||||||
[:> :pattern (-> (obj/clone pattern-attrs)
|
[:> :pattern (-> (obj/clone pattern-attrs)
|
||||||
(obj/set! "id" fill-id))
|
(obj/set! "id" fill-id)
|
||||||
|
(cond-> has-image?
|
||||||
|
(-> (obj/set! "width" (* width no-repeat-padding))
|
||||||
|
(obj/set! "height" (* height no-repeat-padding)))))
|
||||||
[:g
|
[:g
|
||||||
(for [[fill-index value] (-> (d/enumerate (:fills shape [])) reverse)]
|
(for [[fill-index value] (-> (d/enumerate (:fills shape [])) reverse)]
|
||||||
[:> :rect (-> (attrs/extract-fill-attrs value render-id fill-index type)
|
[:> :rect (-> (attrs/extract-fill-attrs value render-id fill-index type)
|
||||||
@ -80,7 +85,17 @@
|
|||||||
(obj/set! "height" height))])
|
(obj/set! "height" height))])
|
||||||
|
|
||||||
(when has-image?
|
(when has-image?
|
||||||
[:image {:href (or (:data-uri shape) (get embed uri uri))
|
[:g
|
||||||
:preserveAspectRatio "none"
|
;; We add this shape to add a padding so the patter won't repeat
|
||||||
:width width
|
;; Issue: https://tree.taiga.io/project/penpot/issue/5583
|
||||||
:height height}])]])])))))
|
[:rect {:x 0
|
||||||
|
:y 0
|
||||||
|
:width (* width no-repeat-padding)
|
||||||
|
:height (* height no-repeat-padding)
|
||||||
|
:fill "none"}]
|
||||||
|
[:image {:href (or (:data-uri shape) (get embed uri uri))
|
||||||
|
:preserveAspectRatio "none"
|
||||||
|
:x 0
|
||||||
|
:y 0
|
||||||
|
:width width
|
||||||
|
:height height}]])]])])))))
|
||||||
|
|||||||
@ -81,7 +81,11 @@
|
|||||||
(let [tool (-> (dom/get-current-target event)
|
(let [tool (-> (dom/get-current-target event)
|
||||||
(dom/get-data "tool")
|
(dom/get-data "tool")
|
||||||
(keyword))]
|
(keyword))]
|
||||||
(st/emit! :interrupt (dw/select-for-drawing tool)))))
|
(st/emit! :interrupt
|
||||||
|
dw/clear-edition-mode)
|
||||||
|
|
||||||
|
;; Delay so anything that launched :interrupt can finish
|
||||||
|
(st/emit! 100 (dw/select-for-drawing tool)))))
|
||||||
|
|
||||||
toggle-text-palette
|
toggle-text-palette
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
|
|||||||
@ -7,7 +7,10 @@
|
|||||||
(ns app.main.ui.workspace.viewport.frame-grid
|
(ns app.main.ui.workspace.viewport.frame-grid
|
||||||
(:require
|
(:require
|
||||||
[app.common.data :as d]
|
[app.common.data :as d]
|
||||||
|
[app.common.data.macros :as dm]
|
||||||
|
[app.common.geom.shapes :as gsh]
|
||||||
[app.common.math :as mth]
|
[app.common.math :as mth]
|
||||||
|
[app.common.pages.helpers :as cph]
|
||||||
[app.common.types.shape-tree :as ctst]
|
[app.common.types.shape-tree :as ctst]
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
[app.main.refs :as refs]
|
[app.main.refs :as refs]
|
||||||
@ -109,32 +112,70 @@
|
|||||||
:strokeOpacity color-opacity
|
:strokeOpacity color-opacity
|
||||||
:fill "none"}}]]))]))
|
: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
|
(mf/defc grid-display-frame
|
||||||
[{:keys [frame zoom]}]
|
{::mf/wrap [mf/memo]}
|
||||||
(for [[index grid] (->> (:grids frame)
|
[{:keys [frame zoom transforming]}]
|
||||||
(filter :display)
|
(let [frame-id (:id frame)
|
||||||
(map-indexed vector))]
|
parents-ref (mf/with-memo [frame-id] (refs/shape-parents frame-id))
|
||||||
(let [props #js {:key (str (:id frame) "-grid-" index)
|
parents (mf/deref parents-ref)
|
||||||
:frame frame
|
clip-area (frame-clip-area frame parents)
|
||||||
:zoom zoom
|
clip-id (dm/str (:id frame) "-grid-clip")
|
||||||
:grid grid}]
|
|
||||||
(case (:type grid)
|
transform?
|
||||||
:square [:> square-grid props]
|
(or (contains? transforming frame-id)
|
||||||
:column [:> layout-grid props]
|
(some #(contains? transforming %) (map :id parents)))]
|
||||||
:row [:> layout-grid props]))))
|
|
||||||
|
(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/defc frame-grid
|
||||||
{::mf/wrap [mf/memo]}
|
{::mf/wrap [mf/memo]}
|
||||||
[{:keys [zoom transform selected focus]}]
|
[{:keys [zoom transform selected focus]}]
|
||||||
(let [frames (mf/deref refs/workspace-frames)
|
(let [frames (->> (mf/deref refs/workspace-frames)
|
||||||
transforming (when (some? transform) selected)
|
(filter has-grid?))
|
||||||
is-transform? #(contains? transforming (:id %))]
|
transforming (when (some? transform) selected)]
|
||||||
|
|
||||||
[:g.grid-display {:style {:pointer-events "none"}}
|
[:g.grid-display {:style {:pointer-events "none"}}
|
||||||
(for [frame frames]
|
(for [frame frames]
|
||||||
(when (and (not (is-transform? frame))
|
(when (and #_(not (is-transform? frame))
|
||||||
(not (ctst/rotated-frame? frame))
|
(not (ctst/rotated-frame? frame))
|
||||||
(or (empty? focus) (contains? focus (:id frame))))
|
(or (empty? focus) (contains? focus (:id frame))))
|
||||||
[:& grid-display-frame {:key (str "grid-" (:id frame))
|
[:& grid-display-frame {:key (str "grid-" (:id frame))
|
||||||
:zoom zoom
|
:zoom zoom
|
||||||
:frame frame}]))]))
|
:frame frame
|
||||||
|
:transforming transforming}]))]))
|
||||||
|
|||||||
@ -25,28 +25,31 @@
|
|||||||
(mth/floor (/ frame-length-no-margins (+ item-length gutter)))))
|
(mth/floor (/ frame-length-no-margins (+ item-length gutter)))))
|
||||||
|
|
||||||
(defn- calculate-generic-grid
|
(defn- calculate-generic-grid
|
||||||
[v width {:keys [size gutter margin item-length type]}]
|
[v total-length {:keys [size gutter margin item-length type]}]
|
||||||
(let [size (if (number? size)
|
(let [size (if (number? size)
|
||||||
size
|
size
|
||||||
(calculate-size width item-length margin gutter))
|
(calculate-size total-length item-length margin gutter))
|
||||||
parts (/ width size)
|
|
||||||
|
|
||||||
width' (min (or item-length ##Inf) (+ parts (- gutter) (/ gutter size) (- (/ (* margin 2) size))))
|
parts (/ total-length size)
|
||||||
|
|
||||||
|
item-length (if (number? item-length)
|
||||||
|
item-length
|
||||||
|
(+ parts (- gutter) (/ gutter size) (- (/ (* margin 2) size))))
|
||||||
|
|
||||||
offset (case type
|
offset (case type
|
||||||
:right (- width (* width' size) (* gutter (dec size)) margin)
|
:right (- total-length (* item-length size) (* gutter (dec size)) margin)
|
||||||
:center (/ (- width (* width' size) (* gutter (dec size))) 2)
|
:center (/ (- total-length (* item-length size) (* gutter (dec size))) 2)
|
||||||
margin)
|
margin)
|
||||||
|
|
||||||
gutter (if (= :stretch type)
|
gutter (if (= :stretch type)
|
||||||
(let [gutter (/ (- width (* width' size) (* margin 2)) (dec size))]
|
(let [gutter (max 0 gutter (/ (- total-length (* item-length size) (* margin 2)) (dec size)))]
|
||||||
(if (d/num? gutter) gutter 0))
|
(if (d/num? gutter) gutter 0))
|
||||||
gutter)
|
gutter)
|
||||||
|
|
||||||
next-v (fn [cur-val]
|
next-v (fn [cur-val]
|
||||||
(+ offset v (* (+ width' gutter) cur-val)))]
|
(+ offset v (* (+ item-length gutter) cur-val)))]
|
||||||
|
|
||||||
[size width' next-v gutter]))
|
[size item-length next-v gutter]))
|
||||||
|
|
||||||
(defn- calculate-column-grid
|
(defn- calculate-column-grid
|
||||||
[{:keys [width height x y] :as frame} params]
|
[{:keys [width height x y] :as frame} params]
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user