0
Fork 0
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:
alonso.torres 2022-02-21 13:33:17 +01:00
parent 82c6b8daae
commit 40b7cafacc
3 changed files with 45 additions and 37 deletions

View file

@ -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

View file

@ -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]]))

View file

@ -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)]]))]]))