mirror of
https://github.com/penpot/penpot.git
synced 2025-07-22 07:27:11 +02:00
✨ SVG generation first version
This commit is contained in:
parent
28f90da70e
commit
96098be5ae
19 changed files with 104 additions and 99 deletions
|
@ -21,7 +21,6 @@
|
|||
[app.main.ui.shapes.filters :as filters]
|
||||
[app.main.ui.shapes.frame :as frame]
|
||||
[app.main.ui.shapes.circle :as circle]
|
||||
[app.main.ui.shapes.icon :as icon]
|
||||
[app.main.ui.shapes.image :as image]
|
||||
[app.main.ui.shapes.path :as path]
|
||||
[app.main.ui.shapes.rect :as rect]
|
||||
|
@ -85,7 +84,6 @@
|
|||
(case (:type shape)
|
||||
:curve [:> path/path-shape opts]
|
||||
:text [:> text/text-shape opts]
|
||||
:icon [:> icon/icon-shape opts]
|
||||
:rect [:> rect/rect-shape opts]
|
||||
:path [:> path/path-shape opts]
|
||||
:image [:> image/image-shape opts]
|
||||
|
|
|
@ -33,8 +33,7 @@
|
|||
:cy cy
|
||||
:rx rx
|
||||
:ry ry
|
||||
:transform transform
|
||||
:id (str "shape-" id)}))]
|
||||
:transform transform}))]
|
||||
|
||||
[:& shape-custom-stroke {:shape shape
|
||||
:base-props props
|
||||
|
|
|
@ -31,7 +31,6 @@
|
|||
(obj/merge!
|
||||
#js {:x 0
|
||||
:y 0
|
||||
:id (str "shape-" id)
|
||||
:width width
|
||||
:height height}))]
|
||||
[:svg {:x x :y y :width width :height height
|
||||
|
|
|
@ -54,7 +54,6 @@
|
|||
:y y
|
||||
:fill (if (debug? :group) "red" "transparent")
|
||||
:opacity 0.5
|
||||
:id (str "group-" id)
|
||||
:width width
|
||||
:height height}])])))
|
||||
|
||||
|
|
|
@ -1,52 +0,0 @@
|
|||
;; 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.icon
|
||||
(:require
|
||||
[rumext.alpha :as mf]
|
||||
[app.common.geom.shapes :as geom]
|
||||
[app.main.ui.shapes.attrs :as attrs]
|
||||
[app.main.ui.shapes.group :refer [mask-id-ctx]]
|
||||
[app.util.object :as obj]))
|
||||
|
||||
(mf/defc icon-shape
|
||||
{::mf/wrap-props false}
|
||||
[props]
|
||||
(let [shape (unchecked-get props "shape")
|
||||
{:keys [id x y width height metadata rotation content]} shape
|
||||
|
||||
mask-id (mf/use-ctx mask-id-ctx)
|
||||
transform (geom/transform-matrix shape)
|
||||
vbox (apply str (interpose " " (:view-box metadata)))
|
||||
|
||||
props (-> (attrs/extract-style-attrs shape)
|
||||
(obj/merge!
|
||||
#js {:x x
|
||||
:y y
|
||||
:transform transform
|
||||
:id (str "shape-" id)
|
||||
:width width
|
||||
:height height
|
||||
:viewBox vbox
|
||||
:preserveAspectRatio "none"
|
||||
:mask mask-id
|
||||
:dangerouslySetInnerHTML #js {:__html content}}))]
|
||||
[:g {:transform transform}
|
||||
[:> "svg" props]]))
|
||||
|
||||
(mf/defc icon-svg
|
||||
[{:keys [shape] :as props}]
|
||||
(let [{:keys [content id metadata]} shape
|
||||
view-box (apply str (interpose " " (:view-box metadata)))
|
||||
mask-id (mf/use-ctx mask-id-ctx)
|
||||
props {:viewBox view-box
|
||||
:id (str "shape-" id)
|
||||
:mask mask-id
|
||||
:dangerouslySetInnerHTML #js {:__html content}}]
|
||||
[:& "svg" props]))
|
|
@ -43,7 +43,6 @@
|
|||
#js {:x x
|
||||
:y y
|
||||
:transform transform
|
||||
:id (str "shape-" id)
|
||||
:width width
|
||||
:height height
|
||||
:preserveAspectRatio "none"
|
||||
|
|
|
@ -52,7 +52,6 @@
|
|||
props (-> (attrs/extract-style-attrs shape)
|
||||
(obj/merge!
|
||||
#js {:transform transform
|
||||
:id (str "shape-" id)
|
||||
:d pdata}))]
|
||||
(if background?
|
||||
[:g {:mask mask-id}
|
||||
|
|
|
@ -32,7 +32,6 @@
|
|||
#js {:x x
|
||||
:y y
|
||||
:transform transform
|
||||
:id (str "shape-" id)
|
||||
:width width
|
||||
:height height}))]
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
group-props (-> props
|
||||
(obj/clone)
|
||||
(obj/without ["shape" "children"])
|
||||
(obj/set! "id" (str "shape-" (:id shape)))
|
||||
(obj/set! "className" "shape")
|
||||
(obj/set! "filter" (filters/filter-str filter-id shape)))]
|
||||
[:& (mf/provider muc/render-ctx) {:value render-id}
|
||||
|
|
|
@ -231,7 +231,6 @@
|
|||
:y y
|
||||
:data-colors (retrieve-colors shape)
|
||||
:transform (geom/transform-matrix shape)
|
||||
:id (str id)
|
||||
:width width
|
||||
:height height
|
||||
:mask mask-id}
|
||||
|
|
|
@ -10,31 +10,38 @@
|
|||
(ns app.main.ui.viewer.handoff.code
|
||||
(:require
|
||||
["highlight.js" :as hljs]
|
||||
["js-beautify" :as beautify]
|
||||
[cuerdas.core :as str]
|
||||
[rumext.alpha :as mf]
|
||||
[app.util.i18n :as i18n]
|
||||
[app.util.color :as uc]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.webapi :as wapi]
|
||||
[app.util.code-gen :as cg]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.common.geom.shapes :as gsh]))
|
||||
|
||||
(def svg-example
|
||||
"<rect
|
||||
x=\"629\"
|
||||
y=\"169\"
|
||||
width=\"176\"
|
||||
height=\"211\"
|
||||
fill=\"#ffffff\"
|
||||
fill-opacity=\"1\">
|
||||
</rect>")
|
||||
|
||||
|
||||
(defn generate-markup-code [type shapes]
|
||||
svg-example)
|
||||
(let [frame (dom/query js/document "#svg-frame")
|
||||
markup-shape
|
||||
(fn [shape]
|
||||
(let [selector (str "#shape-" (:id shape) (when (= :text (:type shape)) " .root"))]
|
||||
(when-let [el (and frame (dom/query frame selector))]
|
||||
(str
|
||||
(str/fmt "<!-- %s -->" (:name shape))
|
||||
(.-outerHTML el)))))]
|
||||
(->> shapes
|
||||
(map markup-shape )
|
||||
(remove nil?)
|
||||
(str/join "\n\n"))))
|
||||
|
||||
(mf/defc code-block [{:keys [code type]}]
|
||||
(let [block-ref (mf/use-ref)]
|
||||
(let [code (-> code
|
||||
(str/replace "<defs></defs>" "")
|
||||
(str/replace "><" ">\n<"))
|
||||
code (cond-> code
|
||||
(= type "svg") (beautify/html #js {"indent_size" 2}))
|
||||
block-ref (mf/use-ref)]
|
||||
(mf/use-effect
|
||||
(mf/deps code type block-ref)
|
||||
(fn []
|
||||
|
@ -52,7 +59,7 @@
|
|||
(map #(gsh/translate-to-frame % frame)))
|
||||
|
||||
style-code (cg/generate-style-code @style-type shapes)
|
||||
markup-code (generate-markup-code @markup-type shapes)]
|
||||
markup-code (mf/use-memo (mf/deps shapes) #(generate-markup-code @markup-type shapes))]
|
||||
[:div.element-options
|
||||
[:div.code-block
|
||||
[:div.code-row-lang
|
||||
|
@ -74,7 +81,7 @@
|
|||
[:div.code-row-lang
|
||||
[:select.code-selection
|
||||
[:option "SVG"]
|
||||
#_[:option "HTML"]]
|
||||
[:option "HTML"]]
|
||||
|
||||
[:button.attributes-copy-button
|
||||
{:on-click #(wapi/write-to-clipboard markup-code)}
|
||||
|
@ -85,5 +92,3 @@
|
|||
:code markup-code}]]]
|
||||
|
||||
]))
|
||||
|
||||
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
[app.main.ui.shapes.circle :as circle]
|
||||
[app.main.ui.shapes.frame :as frame]
|
||||
[app.main.ui.shapes.group :as group]
|
||||
[app.main.ui.shapes.icon :as icon]
|
||||
[app.main.ui.shapes.image :as image]
|
||||
[app.main.ui.shapes.path :as path]
|
||||
[app.main.ui.shapes.rect :as rect]
|
||||
|
@ -111,7 +110,6 @@
|
|||
[objects show-interactions?]
|
||||
(let [path-wrapper (shape-wrapper-factory path/path-shape)
|
||||
text-wrapper (shape-wrapper-factory text/text-shape)
|
||||
icon-wrapper (shape-wrapper-factory icon/icon-shape)
|
||||
rect-wrapper (shape-wrapper-factory rect/rect-shape)
|
||||
image-wrapper (shape-wrapper-factory image/image-shape)
|
||||
circle-wrapper (shape-wrapper-factory circle/circle-shape)]
|
||||
|
@ -130,7 +128,6 @@
|
|||
(case (:type shape)
|
||||
:curve [:> path-wrapper opts]
|
||||
:text [:> text-wrapper opts]
|
||||
:icon [:> icon-wrapper opts]
|
||||
:rect [:> rect-wrapper opts]
|
||||
:path [:> path-wrapper opts]
|
||||
:image [:> image-wrapper opts]
|
||||
|
@ -163,7 +160,8 @@
|
|||
(mf/deps objects)
|
||||
#(frame-container-factory objects))]
|
||||
|
||||
[:svg {:view-box vbox
|
||||
[:svg {:id "svg-frame"
|
||||
:view-box vbox
|
||||
:width width
|
||||
:height height
|
||||
:version "1.1"
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
[app.main.ui.shapes.circle :as circle]
|
||||
[app.main.ui.shapes.frame :as frame]
|
||||
[app.main.ui.shapes.group :as group]
|
||||
[app.main.ui.shapes.icon :as icon]
|
||||
[app.main.ui.shapes.image :as image]
|
||||
[app.main.ui.shapes.path :as path]
|
||||
[app.main.ui.shapes.rect :as rect]
|
||||
|
@ -86,10 +85,6 @@
|
|||
[show-interactions?]
|
||||
(generic-wrapper-factory rect/rect-shape show-interactions?))
|
||||
|
||||
(defn icon-wrapper
|
||||
[show-interactions?]
|
||||
(generic-wrapper-factory icon/icon-shape show-interactions?))
|
||||
|
||||
(defn image-wrapper
|
||||
[show-interactions?]
|
||||
(generic-wrapper-factory image/image-shape show-interactions?))
|
||||
|
@ -142,7 +137,6 @@
|
|||
[objects show-interactions?]
|
||||
(let [path-wrapper (path-wrapper show-interactions?)
|
||||
text-wrapper (text-wrapper show-interactions?)
|
||||
icon-wrapper (icon-wrapper show-interactions?)
|
||||
rect-wrapper (rect-wrapper show-interactions?)
|
||||
image-wrapper (image-wrapper show-interactions?)
|
||||
circle-wrapper (circle-wrapper show-interactions?)]
|
||||
|
@ -160,7 +154,6 @@
|
|||
(case (:type shape)
|
||||
:curve [:> path-wrapper opts]
|
||||
:text [:> text-wrapper opts]
|
||||
:icon [:> icon-wrapper opts]
|
||||
:rect [:> rect-wrapper opts]
|
||||
:path [:> path-wrapper opts]
|
||||
:image [:> image-wrapper opts]
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
[app.main.ui.cursors :as cur]
|
||||
[app.main.ui.shapes.rect :as rect]
|
||||
[app.main.ui.shapes.circle :as circle]
|
||||
[app.main.ui.shapes.icon :as icon]
|
||||
[app.main.ui.shapes.image :as image]
|
||||
[app.main.data.workspace.selection :as dws]
|
||||
[app.main.store :as st]
|
||||
|
@ -40,7 +39,6 @@
|
|||
(declare frame-wrapper)
|
||||
|
||||
(def circle-wrapper (common/generic-wrapper-factory circle/circle-shape))
|
||||
(def icon-wrapper (common/generic-wrapper-factory icon/icon-shape))
|
||||
(def image-wrapper (common/generic-wrapper-factory image/image-shape))
|
||||
(def rect-wrapper (common/generic-wrapper-factory rect/rect-shape))
|
||||
|
||||
|
@ -113,7 +111,6 @@
|
|||
:path [:> path/path-wrapper opts]
|
||||
:text [:> text/text-wrapper opts]
|
||||
:group [:> group-wrapper opts]
|
||||
:icon [:> icon-wrapper opts]
|
||||
:rect [:> rect-wrapper opts]
|
||||
:image [:> image-wrapper opts]
|
||||
:circle [:> circle-wrapper opts]
|
||||
|
|
|
@ -32,7 +32,6 @@
|
|||
[app.main.ui.context :as ctx]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.main.ui.keyboard :as kbd]
|
||||
[app.main.ui.shapes.icon :as icon]
|
||||
[app.main.ui.workspace.sidebar.options.typography :refer [typography-entry]]
|
||||
[app.util.data :refer [matches-search]]
|
||||
[app.util.dom :as dom]
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
[app.main.ui.hooks :as hooks]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.main.ui.keyboard :as kbd]
|
||||
[app.main.ui.shapes.icon :as icon]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.i18n :as i18n :refer [t]]
|
||||
[app.util.object :as obj]
|
||||
|
@ -35,7 +34,6 @@
|
|||
[{:keys [shape] :as props}]
|
||||
(case (:type shape)
|
||||
:frame i/artboard
|
||||
:icon [:& icon/icon-svg {:shape shape}]
|
||||
:image i/image
|
||||
:line i/line
|
||||
:circle i/circle
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
:letter-spacing
|
||||
:text-decoration
|
||||
:text-transform]
|
||||
:to-prop {:fill-color "color" }
|
||||
:to-prop {:fill-color "color"}
|
||||
:format {:font-family #(str "'" % "'")
|
||||
:font-style #(str "'" % "'")
|
||||
:font-size #(str % "px")
|
||||
|
@ -125,7 +125,7 @@
|
|||
shape-format (->> text-shape-style vals (map :format) (reduce merge))
|
||||
|
||||
|
||||
text-values (->> (ut/search-text-attrs (:content shape) (:props style-text))
|
||||
text-values (->> (ut/search-text-attrs (:content shape) (conj (:props style-text) :fill-color-gradient))
|
||||
(merge ut/default-text-attrs))]
|
||||
|
||||
(str/join
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue