mirror of
https://github.com/penpot/penpot.git
synced 2025-03-13 00:01:51 -05:00
✨ Fix problems with strokes
This commit is contained in:
parent
82c6b8daae
commit
40b7cafacc
3 changed files with 45 additions and 37 deletions
|
@ -6,7 +6,6 @@
|
|||
|
||||
(ns app.main.ui.shapes.custom-stroke
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.main.ui.context :as muc]
|
||||
[app.util.object :as obj]
|
||||
|
@ -25,16 +24,18 @@
|
|||
(-> props (obj/merge #js {:style style}))))
|
||||
|
||||
(mf/defc inner-stroke-clip-path
|
||||
[{:keys [render-id]}]
|
||||
(let [clip-id (str "inner-stroke-" render-id)
|
||||
shape-id (str "stroke-shape-" render-id)]
|
||||
[{:keys [shape render-id index]}]
|
||||
(let [suffix (if index (str "-" index) "")
|
||||
clip-id (str "inner-stroke-" render-id "-" (:id shape) suffix)
|
||||
shape-id (str "stroke-shape-" render-id "-" (:id shape) suffix)]
|
||||
[:> "clipPath" #js {:id clip-id}
|
||||
[:use {:xlinkHref (str "#" shape-id)}]]))
|
||||
|
||||
(mf/defc outer-stroke-mask
|
||||
[{:keys [shape render-id]}]
|
||||
(let [stroke-mask-id (str "outer-stroke-" render-id)
|
||||
shape-id (str "stroke-shape-" render-id)
|
||||
[{:keys [shape render-id index]}]
|
||||
(let [suffix (if index (str "-" index) "")
|
||||
stroke-mask-id (str "outer-stroke-" render-id "-" (:id shape) suffix)
|
||||
shape-id (str "stroke-shape-" render-id "-" (:id shape) suffix)
|
||||
stroke-width (case (:stroke-alignment shape :center)
|
||||
:center (/ (:stroke-width shape 0) 2)
|
||||
:outer (:stroke-width shape 0)
|
||||
|
@ -44,7 +45,8 @@
|
|||
:style #js {:fill "none" :stroke "white" :strokeWidth (* stroke-width 2)}}]
|
||||
|
||||
[:use {:xlinkHref (str "#" shape-id)
|
||||
:style #js {:fill "black"}}]]))
|
||||
:style #js {:fill "black"
|
||||
:stroke "none"}}]]))
|
||||
|
||||
(mf/defc cap-markers
|
||||
[{:keys [shape render-id]}]
|
||||
|
@ -149,7 +151,7 @@
|
|||
[:rect {:x 3 :y 2.5 :width 0.5 :height 1}]])]))
|
||||
|
||||
(mf/defc stroke-defs
|
||||
[{:keys [shape render-id]}]
|
||||
[{:keys [shape render-id index]}]
|
||||
|
||||
(let [open-path? (and (= :path (:type shape)) (gsh/open-path? shape))]
|
||||
(cond
|
||||
|
@ -157,18 +159,21 @@
|
|||
(= :inner (:stroke-alignment shape :center))
|
||||
(> (:stroke-width shape 0) 0))
|
||||
[:& inner-stroke-clip-path {:shape shape
|
||||
:render-id render-id}]
|
||||
:render-id render-id
|
||||
:index index}]
|
||||
|
||||
(and (not open-path?)
|
||||
(= :outer (:stroke-alignment shape :center))
|
||||
(> (:stroke-width shape 0) 0))
|
||||
[:& outer-stroke-mask {:shape shape
|
||||
:render-id render-id}]
|
||||
:render-id render-id
|
||||
:index index}]
|
||||
|
||||
(or (some? (:stroke-cap-start shape))
|
||||
(some? (:stroke-cap-end shape)))
|
||||
[:& cap-markers {:shape shape
|
||||
:render-id render-id}])))
|
||||
:render-id render-id
|
||||
:index index}])))
|
||||
|
||||
;; Outer alignment: display the shape in two layers. One
|
||||
;; without stroke (only fill), and another one only with stroke
|
||||
|
@ -179,40 +184,41 @@
|
|||
{::mf/wrap-props false}
|
||||
[props]
|
||||
|
||||
(let [render-id (mf/use-ctx muc/render-ctx)
|
||||
child (obj/get props "children")
|
||||
base-props (obj/get child "props")
|
||||
elem-name (obj/get child "type")
|
||||
stroke-mask-id (str "outer-stroke-" render-id)
|
||||
shape-id (str "stroke-shape-" render-id)
|
||||
(let [render-id (mf/use-ctx muc/render-ctx)
|
||||
child (obj/get props "children")
|
||||
base-props (obj/get child "props")
|
||||
elem-name (obj/get child "type")
|
||||
shape (obj/get props "shape")
|
||||
index (obj/get props "index")
|
||||
stroke-width (:stroke-width shape)
|
||||
|
||||
style-str (->> (obj/get base-props "style")
|
||||
(js->clj)
|
||||
(mapv (fn [[k v]]
|
||||
(-> (d/name k)
|
||||
(str/kebab)
|
||||
(str ":" v))))
|
||||
(str/join ";"))]
|
||||
suffix (if index (str "-" index) "")
|
||||
stroke-mask-id (str "outer-stroke-" render-id "-" (:id shape) suffix)
|
||||
shape-id (str "stroke-shape-" render-id "-" (:id shape) suffix)]
|
||||
|
||||
[:g.outer-stroke-shape
|
||||
[:defs
|
||||
[:& stroke-defs {:shape shape :render-id render-id :index index}]
|
||||
[:> elem-name (-> (obj/clone base-props)
|
||||
(obj/set! "id" shape-id)
|
||||
(obj/set! "data-style" style-str)
|
||||
(obj/without ["style"]))]]
|
||||
(obj/set!
|
||||
"style"
|
||||
(-> (obj/get base-props "style")
|
||||
(obj/clone)
|
||||
(obj/without ["fill" "fillOpacity" "stroke" "strokeWidth" "strokeOpacity" "strokeStyle" "strokeDasharray"]))))]]
|
||||
|
||||
[:use {:xlinkHref (str "#" shape-id)
|
||||
:mask (str "url(#" stroke-mask-id ")")
|
||||
:style (-> (obj/get base-props "style")
|
||||
(obj/clone)
|
||||
(obj/update! "strokeWidth" * 2)
|
||||
(obj/set! "strokeWidth" (* stroke-width 2))
|
||||
(obj/without ["fill" "fillOpacity"])
|
||||
(obj/set! "fill" "none"))}]
|
||||
|
||||
[:use {:xlinkHref (str "#" shape-id)
|
||||
:style (-> (obj/get base-props "style")
|
||||
(obj/clone)
|
||||
(obj/without ["stroke" "strokeWidth" "strokeOpacity" "strokeStyle" "strokeDasharray"]))}]]))
|
||||
(obj/set! "stroke" "none"))}]]))
|
||||
|
||||
|
||||
;; Inner alignment: display the shape with double width stroke,
|
||||
|
@ -225,12 +231,14 @@
|
|||
base-props (obj/get child "props")
|
||||
elem-name (obj/get child "type")
|
||||
shape (obj/get props "shape")
|
||||
index (obj/get props "index")
|
||||
transform (obj/get base-props "transform")
|
||||
|
||||
stroke-width (:stroke-width shape 0)
|
||||
|
||||
clip-id (str "inner-stroke-" render-id)
|
||||
shape-id (str "stroke-shape-" render-id)
|
||||
suffix (if index (str "-" index) "")
|
||||
clip-id (str "inner-stroke-" render-id "-" (:id shape) suffix)
|
||||
shape-id (str "stroke-shape-" render-id "-" (:id shape) suffix)
|
||||
|
||||
clip-path (str "url('#" clip-id "')")
|
||||
shape-props (-> base-props
|
||||
|
@ -240,12 +248,12 @@
|
|||
|
||||
[:g.inner-stroke-shape {:transform transform}
|
||||
[:defs
|
||||
[:& stroke-defs {:shape shape :render-id render-id :index index}]
|
||||
[:> elem-name shape-props]]
|
||||
|
||||
[:use {:xlinkHref (str "#" shape-id)
|
||||
:clipPath clip-path}]]))
|
||||
|
||||
|
||||
; The SVG standard does not implement yet the 'stroke-alignment'
|
||||
; attribute, to define the position of the stroke relative to the
|
||||
; stroke axis (inner, center, outer). Here we implement a patch to be
|
||||
|
@ -254,8 +262,10 @@
|
|||
(mf/defc shape-custom-stroke
|
||||
{::mf/wrap-props false}
|
||||
[props]
|
||||
|
||||
(let [child (obj/get props "children")
|
||||
shape (obj/get props "shape")
|
||||
index (obj/get props "index")
|
||||
stroke-width (:stroke-width shape 0)
|
||||
stroke-style (:stroke-style shape :none)
|
||||
stroke-position (:stroke-alignment shape :center)
|
||||
|
@ -268,11 +278,11 @@
|
|||
|
||||
(cond
|
||||
(and has-stroke? inner? closed?)
|
||||
[:& inner-stroke {:shape shape}
|
||||
[:& inner-stroke {:shape shape :index index}
|
||||
child]
|
||||
|
||||
(and has-stroke? outer? closed?)
|
||||
[:& outer-stroke {:shape shape}
|
||||
[:& outer-stroke {:shape shape :index index}
|
||||
child]
|
||||
|
||||
:else
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
[app.common.uuid :as uuid]
|
||||
[app.main.ui.context :as muc]
|
||||
[app.main.ui.shapes.attrs :as attrs]
|
||||
[app.main.ui.shapes.custom-stroke :as cs]
|
||||
[app.main.ui.shapes.export :as ed]
|
||||
[app.main.ui.shapes.fills :as fills]
|
||||
[app.main.ui.shapes.filters :as filters]
|
||||
|
@ -69,6 +68,5 @@
|
|||
(> (count (:fills shape)) 1)
|
||||
(some :fill-color-gradient (:fills shape)))
|
||||
[:& fills/fills {:shape shape :render-id render-id}])
|
||||
[:& cs/stroke-defs {:shape shape :render-id render-id}]
|
||||
[:& frame/frame-clip-def {:shape shape :render-id render-id}]]
|
||||
children]]))
|
||||
|
|
|
@ -60,7 +60,7 @@
|
|||
:direction (if (:rtl? data) "rtl" "ltr")
|
||||
:whiteSpace "pre"}
|
||||
(attrs/add-fill data (get-gradient-id index)))})]
|
||||
[:& shape-custom-stroke {:shape shape}
|
||||
[:& shape-custom-stroke {:shape shape :index index}
|
||||
[:> :text props (:text data)]]))]]))
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue