mirror of
https://github.com/penpot/penpot.git
synced 2025-06-02 03:21:38 +02:00
✨ Linear and radial gradient handlers
This commit is contained in:
parent
8466c1c54d
commit
08b537a158
6 changed files with 442 additions and 26 deletions
|
@ -8,7 +8,9 @@
|
|||
;; Copyright (c) 2016-2020 UXBOX Labs SL
|
||||
|
||||
(ns app.main.ui.shapes.attrs
|
||||
(:require [app.util.object :as obj]))
|
||||
(:require
|
||||
[cuerdas.core :as str]
|
||||
[app.util.object :as obj]))
|
||||
|
||||
(defn- stroke-type->dasharray
|
||||
[style]
|
||||
|
@ -19,16 +21,20 @@
|
|||
nil))
|
||||
|
||||
(defn extract-style-attrs
|
||||
[shape]
|
||||
(let [stroke-style (:stroke-style shape :none)
|
||||
attrs #js {:fill (or (:fill-color shape) "transparent")
|
||||
:fillOpacity (:fill-opacity shape nil)
|
||||
:rx (:rx shape nil)
|
||||
:ry (:ry shape nil)}]
|
||||
(when (not= stroke-style :none)
|
||||
(obj/merge! attrs
|
||||
#js {:stroke (:stroke-color shape nil)
|
||||
:strokeWidth (:stroke-width shape 1)
|
||||
:strokeOpacity (:stroke-opacity shape nil)
|
||||
:strokeDasharray (stroke-type->dasharray stroke-style)}))
|
||||
attrs))
|
||||
([shape] (extract-style-attrs shape nil))
|
||||
([shape gradient-id]
|
||||
(let [stroke-style (:stroke-style shape :none)
|
||||
attrs #js {:rx (:rx shape nil)
|
||||
:ry (:ry shape nil)}
|
||||
attrs (obj/merge! attrs
|
||||
(if gradient-id
|
||||
#js {:fill (str/format "url(#%s)" gradient-id)}
|
||||
#js {:fill (or (:fill-color shape) "transparent")
|
||||
:fillOpacity (:fill-opacity shape nil)}))]
|
||||
(when (not= stroke-style :none)
|
||||
(obj/merge! attrs
|
||||
#js {:stroke (:stroke-color shape nil)
|
||||
:strokeWidth (:stroke-width shape 1)
|
||||
:strokeOpacity (:stroke-opacity shape nil)
|
||||
:strokeDasharray (stroke-type->dasharray stroke-style)}))
|
||||
attrs)))
|
||||
|
|
78
frontend/src/app/main/ui/shapes/gradients.cljs
Normal file
78
frontend/src/app/main/ui/shapes/gradients.cljs
Normal file
|
@ -0,0 +1,78 @@
|
|||
;; This Source Code Form is subject to the terms of the Mozilla Public
|
||||
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
;;
|
||||
;; This Source Code Form is "Incompatible With Secondary Licenses", as
|
||||
;; defined by the Mozilla Public License, v. 2.0.
|
||||
;;
|
||||
;; Copyright (c) 2020 UXBOX Labs SL
|
||||
|
||||
(ns app.main.ui.shapes.gradients
|
||||
(:require
|
||||
[rumext.alpha :as mf]
|
||||
[cuerdas.core :as str]
|
||||
[goog.object :as gobj]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.common.geom.point :as gpt]))
|
||||
|
||||
(mf/defc linear-gradient [{:keys [id shape gradient]}]
|
||||
(let [{:keys [x y width height]} shape]
|
||||
[:defs
|
||||
[:linearGradient {:id id
|
||||
:x1 (:start-x gradient)
|
||||
:y1 (:start-y gradient)
|
||||
:x2 (:end-x gradient)
|
||||
:y2 (:end-y gradient)}
|
||||
(for [{:keys [offset color opacity]} (:stops gradient)]
|
||||
[:stop {:key (str id "-stop-" offset)
|
||||
:offset (or offset 0)
|
||||
:stop-color color
|
||||
:stop-opacity opacity}])]]))
|
||||
|
||||
(mf/defc radial-gradient [{:keys [id shape gradient]}]
|
||||
(let [{:keys [x y width height]} shape]
|
||||
[:defs
|
||||
(let [translate-vec (gpt/point (+ x (* width (:start-x gradient)))
|
||||
(+ y (* height (:start-y gradient))))
|
||||
|
||||
|
||||
gradient-vec (gpt/to-vec (gpt/point (* width (:start-x gradient))
|
||||
(* height (:start-y gradient)))
|
||||
(gpt/point (* width (:end-x gradient))
|
||||
(* height (:end-y gradient))))
|
||||
|
||||
angle (gpt/angle gradient-vec
|
||||
(gpt/point 1 0))
|
||||
|
||||
shape-height-vec (gpt/point 0 (/ height 2))
|
||||
|
||||
scale-factor-y (/ (gpt/length gradient-vec) (/ height 2))
|
||||
scale-factor-x (* scale-factor-y (:width gradient))
|
||||
|
||||
scale-vec (gpt/point (* scale-factor-y (/ height 2))
|
||||
(* scale-factor-x (/ width 2))
|
||||
)
|
||||
tr-translate (str/fmt "translate(%s, %s)" (:x translate-vec) (:y translate-vec))
|
||||
tr-rotate (str/fmt "rotate(%s)" angle)
|
||||
tr-scale (str/fmt "scale(%s, %s)" (:x scale-vec) (:y scale-vec))
|
||||
transform (str/fmt "%s %s %s" tr-translate tr-rotate tr-scale)]
|
||||
[:radialGradient {:id id
|
||||
:cx 0
|
||||
:cy 0
|
||||
:r 1
|
||||
:gradientUnits "userSpaceOnUse"
|
||||
:gradientTransform transform}
|
||||
(for [{:keys [offset color opacity]} (:stops gradient)]
|
||||
[:stop {:key (str id "-stop-" offset)
|
||||
:offset (or offset 0)
|
||||
:stop-color color
|
||||
:stop-opacity opacity}])])]))
|
||||
|
||||
(mf/defc gradient
|
||||
{::mf/wrap-props false}
|
||||
[props]
|
||||
(let [gradient (gobj/get props "gradient")]
|
||||
(case (:type gradient)
|
||||
:linear [:> linear-gradient props]
|
||||
:radial [:> radial-gradient props]
|
||||
nil)))
|
|
@ -13,7 +13,12 @@
|
|||
[app.main.ui.shapes.attrs :as attrs]
|
||||
[app.main.ui.shapes.custom-stroke :refer [shape-custom-stroke]]
|
||||
[app.common.geom.shapes :as geom]
|
||||
[app.util.object :as obj]))
|
||||
[app.util.object :as obj]
|
||||
[app.main.ui.shapes.gradients :refer [gradient]]
|
||||
|
||||
[cuerdas.core :as str]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.common.geom.point :as gpt]))
|
||||
|
||||
(mf/defc rect-shape
|
||||
{::mf/wrap-props false}
|
||||
|
@ -21,7 +26,10 @@
|
|||
(let [shape (unchecked-get props "shape")
|
||||
{:keys [id x y width height]} shape
|
||||
transform (geom/transform-matrix shape)
|
||||
props (-> (attrs/extract-style-attrs shape)
|
||||
|
||||
gradient-id (when (:fill-color-gradient shape) (str (uuid/next)))
|
||||
|
||||
props (-> (attrs/extract-style-attrs shape gradient-id)
|
||||
(obj/merge!
|
||||
#js {:x x
|
||||
:y y
|
||||
|
@ -30,7 +38,12 @@
|
|||
:width width
|
||||
:height height}))]
|
||||
|
||||
[:& shape-custom-stroke {:shape shape
|
||||
:base-props props
|
||||
:elem-name "rect"}]))
|
||||
|
||||
[:*
|
||||
(when gradient-id
|
||||
[:& gradient {:id gradient-id
|
||||
:shape shape
|
||||
:gradient (:fill-color-gradient shape)}])
|
||||
[:& shape-custom-stroke {:shape shape
|
||||
:base-props props
|
||||
:elem-name "rect"}]]))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue