mirror of
https://github.com/penpot/penpot.git
synced 2025-05-13 17:07:12 +02:00
✨ Improved code gen
This commit is contained in:
parent
ecc3b29996
commit
cb502fc70d
5 changed files with 80 additions and 48 deletions
|
@ -74,16 +74,24 @@
|
||||||
font-size (:font-size data)
|
font-size (:font-size data)
|
||||||
fill-color (or (-> data :fills first :fill-color) (:fill-color data))
|
fill-color (or (-> data :fills first :fill-color) (:fill-color data))
|
||||||
fill-opacity (or (-> data :fills first :fill-opacity) (:fill-opacity data))
|
fill-opacity (or (-> data :fills first :fill-opacity) (:fill-opacity data))
|
||||||
|
fill-gradient (or (-> data :fills first :fill-color-gradient) (:fill-color-gradient data))
|
||||||
|
|
||||||
[r g b a] (uc/hex->rgba fill-color fill-opacity)
|
[r g b a] (uc/hex->rgba fill-color fill-opacity)
|
||||||
text-color (when (and (some? fill-color) (some? fill-opacity))
|
text-color (when (and (some? fill-color) (some? fill-opacity))
|
||||||
(str/format "rgba(%s, %s, %s, %s)" r g b a))
|
(str/format "rgba(%s, %s, %s, %s)" r g b a))
|
||||||
|
|
||||||
|
gradient? (some? fill-gradient)
|
||||||
|
|
||||||
|
text-color (if gradient?
|
||||||
|
(uc/color->background {:gradient fill-gradient})
|
||||||
|
text-color)
|
||||||
|
|
||||||
fontsdb (deref fonts/fontsdb)
|
fontsdb (deref fonts/fontsdb)
|
||||||
|
|
||||||
base #js {:textDecoration text-decoration
|
base #js {:textDecoration text-decoration
|
||||||
:textTransform text-transform
|
:textTransform text-transform
|
||||||
:color (if show-text? text-color "transparent")
|
:color (if (and show-text? (not gradient?)) text-color "transparent")
|
||||||
|
:background (when (and show-text? gradient?) text-color)
|
||||||
:caretColor (or text-color "black")
|
:caretColor (or text-color "black")
|
||||||
:overflowWrap "initial"
|
:overflowWrap "initial"
|
||||||
:lineBreak "auto"
|
:lineBreak "auto"
|
||||||
|
|
|
@ -32,6 +32,9 @@
|
||||||
[potok.core :as ptk]
|
[potok.core :as ptk]
|
||||||
[rumext.v2 :as mf]))
|
[rumext.v2 :as mf]))
|
||||||
|
|
||||||
|
(def embed-images? false)
|
||||||
|
(def remove-localhost? true)
|
||||||
|
|
||||||
(def page-template
|
(def page-template
|
||||||
"<!DOCTYPE html>
|
"<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
|
@ -46,11 +49,13 @@
|
||||||
</html>")
|
</html>")
|
||||||
|
|
||||||
(defn format-code [code type]
|
(defn format-code [code type]
|
||||||
(let [code (-> code
|
(cond-> code
|
||||||
(str/replace "<defs></defs>" "")
|
(= type "svg")
|
||||||
(str/replace "><" ">\n<"))]
|
(-> (str/replace "<defs></defs>" "")
|
||||||
(cond-> code
|
(str/replace "><" ">\n<"))
|
||||||
(or (= type "svg") (= type "html")) (beautify/html #js {"indent_size" 2}))))
|
|
||||||
|
(or (= type "svg") (= type "html"))
|
||||||
|
(beautify/html #js {"indent_size" 2})))
|
||||||
|
|
||||||
(defn get-flex-elements [page-id shapes from]
|
(defn get-flex-elements [page-id shapes from]
|
||||||
(let [ids (mapv :id shapes)
|
(let [ids (mapv :id shapes)
|
||||||
|
@ -189,7 +194,13 @@
|
||||||
(mf/use-callback
|
(mf/use-callback
|
||||||
(mf/deps style-code markup-code images-data)
|
(mf/deps style-code markup-code images-data)
|
||||||
(fn []
|
(fn []
|
||||||
(let [markup-code (replace-map markup-code images-data)
|
(let [markup-code (cond-> markup-code
|
||||||
|
embed-images? (replace-map images-data))
|
||||||
|
|
||||||
|
style-code (cond-> style-code
|
||||||
|
remove-localhost?
|
||||||
|
(str/replace "http://localhost:3449" ""))
|
||||||
|
|
||||||
data (str/format page-template style-code markup-code)]
|
data (str/format page-template style-code markup-code)]
|
||||||
(wapi/write-to-clipboard data))))]
|
(wapi/write-to-clipboard data))))]
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
(ns app.util.code-gen.markup-html
|
(ns app.util.code-gen.markup-html
|
||||||
(:require
|
(:require
|
||||||
["react-dom/server" :as rds]
|
["react-dom/server" :as rds]
|
||||||
|
[app.common.data :as d]
|
||||||
[app.common.data.macros :as dm]
|
[app.common.data.macros :as dm]
|
||||||
[app.common.pages.helpers :as cph]
|
[app.common.pages.helpers :as cph]
|
||||||
[app.common.types.shape.layout :as ctl]
|
[app.common.types.shape.layout :as ctl]
|
||||||
|
@ -17,6 +18,32 @@
|
||||||
[cuerdas.core :as str]
|
[cuerdas.core :as str]
|
||||||
[rumext.v2 :as mf]))
|
[rumext.v2 :as mf]))
|
||||||
|
|
||||||
|
(defn svg-markup?
|
||||||
|
"Function to determine whether a shape is rendered in HTML+CSS or is rendered
|
||||||
|
through a SVG"
|
||||||
|
[shape]
|
||||||
|
(or
|
||||||
|
;; path and path-like shapes
|
||||||
|
(cph/path-shape? shape)
|
||||||
|
(cph/bool-shape? shape)
|
||||||
|
|
||||||
|
;; imported SVG images
|
||||||
|
(cph/svg-raw-shape? shape)
|
||||||
|
(some? (:svg-attrs shape))
|
||||||
|
|
||||||
|
;; CSS masks are not enough we need to delegate to SVG
|
||||||
|
(cph/mask-shape? shape)
|
||||||
|
|
||||||
|
;; Texts with shadows or strokes we render in SVG
|
||||||
|
(and (cph/text-shape? shape)
|
||||||
|
(or (d/not-empty? (:shadow shape))
|
||||||
|
(d/not-empty? (:strokes shape))))
|
||||||
|
|
||||||
|
;; When a shape has several strokes or the stroke is not a "border"
|
||||||
|
(or (> (count (:strokes shape)) 1)
|
||||||
|
(and (= (count (:strokes shape)) 1)
|
||||||
|
(not= (-> shape :strokes first :stroke-alignment) :center)))))
|
||||||
|
|
||||||
(defn generate-html
|
(defn generate-html
|
||||||
([objects shape]
|
([objects shape]
|
||||||
(generate-html objects shape 0))
|
(generate-html objects shape 0))
|
||||||
|
@ -26,6 +53,14 @@
|
||||||
maybe-reverse (if (ctl/any-layout? shape) reverse identity)]
|
maybe-reverse (if (ctl/any-layout? shape) reverse identity)]
|
||||||
|
|
||||||
(cond
|
(cond
|
||||||
|
(svg-markup? shape)
|
||||||
|
(let [svg-markup (generate-svg objects shape)]
|
||||||
|
(dm/fmt "%<div class=\"%\">\n%\n%</div>"
|
||||||
|
indent
|
||||||
|
(cgc/shape->selector shape)
|
||||||
|
svg-markup
|
||||||
|
indent))
|
||||||
|
|
||||||
(cph/text-shape? shape)
|
(cph/text-shape? shape)
|
||||||
(let [text-shape-html (rds/renderToStaticMarkup (mf/element text/text-shape #js {:shape shape :code? true}))]
|
(let [text-shape-html (rds/renderToStaticMarkup (mf/element text/text-shape #js {:shape shape :code? true}))]
|
||||||
(dm/fmt "%<div class=\"%\">\n%\n%</div>"
|
(dm/fmt "%<div class=\"%\">\n%\n%</div>"
|
||||||
|
@ -43,18 +78,6 @@
|
||||||
(cgc/shape->selector shape)
|
(cgc/shape->selector shape)
|
||||||
indent))
|
indent))
|
||||||
|
|
||||||
(or (cph/path-shape? shape)
|
|
||||||
(cph/mask-shape? shape)
|
|
||||||
(cph/bool-shape? shape)
|
|
||||||
(cph/svg-raw-shape? shape)
|
|
||||||
(some? (:svg-attrs shape)))
|
|
||||||
(let [svg-markup (generate-svg objects shape)]
|
|
||||||
(dm/fmt "%<div class=\"%\">\n%\n%</div>"
|
|
||||||
indent
|
|
||||||
(cgc/shape->selector shape)
|
|
||||||
svg-markup
|
|
||||||
indent))
|
|
||||||
|
|
||||||
(empty? (:shapes shape))
|
(empty? (:shapes shape))
|
||||||
(dm/fmt "%<div class=\"%\">\n%</div>"
|
(dm/fmt "%<div class=\"%\">\n%</div>"
|
||||||
indent
|
indent
|
||||||
|
|
|
@ -46,8 +46,7 @@ svg {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-node { background-clip: text;
|
.text-node { background-clip: text !important; -webkit-background-clip: text !important; }
|
||||||
-webkit-background-clip: text; }
|
|
||||||
|
|
||||||
")
|
")
|
||||||
|
|
||||||
|
|
|
@ -11,15 +11,8 @@
|
||||||
[app.common.geom.matrix :as gmt]
|
[app.common.geom.matrix :as gmt]
|
||||||
[app.common.geom.shapes :as gsh]
|
[app.common.geom.shapes :as gsh]
|
||||||
[app.common.pages.helpers :as cph]
|
[app.common.pages.helpers :as cph]
|
||||||
[app.common.types.shape.layout :as ctl]))
|
[app.common.types.shape.layout :as ctl]
|
||||||
|
[app.util.code-gen.markup-html :refer [svg-markup?]]))
|
||||||
(defn svg-render?
|
|
||||||
[shape]
|
|
||||||
(or (cph/path-shape? shape)
|
|
||||||
(cph/mask-shape? shape)
|
|
||||||
(cph/bool-shape? shape)
|
|
||||||
(cph/svg-raw-shape? shape)
|
|
||||||
(some? (:svg-attrs shape))))
|
|
||||||
|
|
||||||
(defn fill->color
|
(defn fill->color
|
||||||
[{:keys [fill-color fill-opacity fill-color-gradient]}]
|
[{:keys [fill-color fill-opacity fill-color-gradient]}]
|
||||||
|
@ -107,21 +100,17 @@
|
||||||
(get-shape-size shape :height))
|
(get-shape-size shape :height))
|
||||||
|
|
||||||
(defmethod get-value :transform
|
(defmethod get-value :transform
|
||||||
[_ {:keys [transform] :as shape} objects]
|
[_ shape objects]
|
||||||
(let [transform
|
(let [parent (get objects (:parent-id shape))]
|
||||||
(->> (cph/get-parents objects (:id shape))
|
(dm/str (gmt/multiply (:transform shape (gmt/matrix))
|
||||||
(reduce (fn [mtx {:keys [transform-inverse]}]
|
(:transform-inverse parent (gmt/matrix))))))
|
||||||
(gmt/multiply transform-inverse mtx))
|
|
||||||
transform))]
|
|
||||||
(when (and (some? transform) (not (gmt/unit? transform)))
|
|
||||||
(dm/str transform))))
|
|
||||||
|
|
||||||
(defmethod get-value :background
|
(defmethod get-value :background
|
||||||
[_ {:keys [fills] :as shape} _]
|
[_ {:keys [fills] :as shape} _]
|
||||||
(let [single-fill? (= (count fills) 1)
|
(let [single-fill? (= (count fills) 1)
|
||||||
ffill (first fills)
|
ffill (first fills)
|
||||||
gradient? (some? (:fill-color-gradient ffill))]
|
gradient? (some? (:fill-color-gradient ffill))]
|
||||||
(when (and (not (svg-render? shape)) single-fill? gradient?)
|
(when (and (not (svg-markup? shape)) single-fill? gradient?)
|
||||||
(fill->color ffill))))
|
(fill->color ffill))))
|
||||||
|
|
||||||
(defmethod get-value :background-color
|
(defmethod get-value :background-color
|
||||||
|
@ -129,12 +118,12 @@
|
||||||
(let [single-fill? (= (count fills) 1)
|
(let [single-fill? (= (count fills) 1)
|
||||||
ffill (first fills)
|
ffill (first fills)
|
||||||
gradient? (some? (:fill-color-gradient ffill))]
|
gradient? (some? (:fill-color-gradient ffill))]
|
||||||
(when (and (not (svg-render? shape)) single-fill? (not gradient?))
|
(when (and (not (svg-markup? shape)) single-fill? (not gradient?))
|
||||||
(fill->color ffill))))
|
(fill->color ffill))))
|
||||||
|
|
||||||
(defmethod get-value :background-image
|
(defmethod get-value :background-image
|
||||||
[_ {:keys [fills] :as shape} _]
|
[_ {:keys [fills] :as shape} _]
|
||||||
(when (and (not (svg-render? shape)) (> (count fills) 1))
|
(when (and (not (svg-markup? shape)) (> (count fills) 1))
|
||||||
(->> fills
|
(->> fills
|
||||||
(map fill->color))))
|
(map fill->color))))
|
||||||
|
|
||||||
|
@ -153,7 +142,7 @@
|
||||||
|
|
||||||
(defmethod get-value :border
|
(defmethod get-value :border
|
||||||
[_ shape _]
|
[_ shape _]
|
||||||
(when-not (svg-render? shape)
|
(when-not (svg-markup? shape)
|
||||||
(get-stroke-data (first (:strokes shape)))))
|
(get-stroke-data (first (:strokes shape)))))
|
||||||
|
|
||||||
(defmethod get-value :border-radius
|
(defmethod get-value :border-radius
|
||||||
|
@ -170,11 +159,13 @@
|
||||||
|
|
||||||
(defmethod get-value :box-shadow
|
(defmethod get-value :box-shadow
|
||||||
[_ shape _]
|
[_ shape _]
|
||||||
(:shadow shape))
|
(when-not (svg-markup? shape)
|
||||||
|
(:shadow shape)))
|
||||||
|
|
||||||
(defmethod get-value :filter
|
(defmethod get-value :filter
|
||||||
[_ shape _]
|
[_ shape _]
|
||||||
(get-in shape [:blur :value]))
|
(when-not (svg-markup? shape)
|
||||||
|
(get-in shape [:blur :value])))
|
||||||
|
|
||||||
(defmethod get-value :display
|
(defmethod get-value :display
|
||||||
[_ shape _]
|
[_ shape _]
|
||||||
|
@ -226,13 +217,13 @@
|
||||||
|
|
||||||
(defmethod get-value :row-gap
|
(defmethod get-value :row-gap
|
||||||
[_ shape _]
|
[_ shape _]
|
||||||
(let [[g1 _] (ctl/gaps shape)]
|
(let [[g1 g2] (ctl/gaps shape)]
|
||||||
(when (not= g1 0) [g1])))
|
(when (and (not= g1 g2) (not= g1 0)) [g1])))
|
||||||
|
|
||||||
(defmethod get-value :column-gap
|
(defmethod get-value :column-gap
|
||||||
[_ shape _]
|
[_ shape _]
|
||||||
(let [[_ g2] (ctl/gaps shape)]
|
(let [[g1 g2] (ctl/gaps shape)]
|
||||||
(when (not= g2 0) [g2])))
|
(when (and (not= g1 g2) (not= g2 0)) [g2])))
|
||||||
|
|
||||||
(defmethod get-value :padding
|
(defmethod get-value :padding
|
||||||
[_ {:keys [layout-padding]} _]
|
[_ {:keys [layout-padding]} _]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue