mirror of
https://github.com/penpot/penpot.git
synced 2025-07-23 17:17:13 +02:00
🐛 Improve html generation
This commit is contained in:
parent
1f04304210
commit
7fd02022ac
8 changed files with 210 additions and 174 deletions
|
@ -58,5 +58,6 @@
|
|||
[objects shape]
|
||||
;; Layout children with a transform should be wrapped
|
||||
(and (ctl/any-layout-immediate-child? objects shape)
|
||||
(not (ctl/layout-absolute? shape))
|
||||
(not (gmt/unit? (:transform shape)))))
|
||||
|
||||
|
|
|
@ -23,68 +23,69 @@
|
|||
(generate-html objects shape 0))
|
||||
|
||||
([objects shape level]
|
||||
(let [indent (str/repeat " " level)
|
||||
maybe-reverse (if (ctl/any-layout? shape) reverse identity)
|
||||
(when (and (some? shape) (some? (:selrect shape)))
|
||||
(let [indent (str/repeat " " level)
|
||||
maybe-reverse (if (ctl/any-layout? shape) reverse identity)
|
||||
|
||||
shape-html
|
||||
(cond
|
||||
(cgc/svg-markup? shape)
|
||||
(let [svg-markup (generate-svg objects shape)]
|
||||
shape-html
|
||||
(cond
|
||||
(cgc/svg-markup? shape)
|
||||
(let [svg-markup (generate-svg objects shape)]
|
||||
(dm/fmt "%<div class=\"%\">\n%\n%</div>"
|
||||
indent
|
||||
(dm/str "shape " (d/name (:type shape)) " "
|
||||
(cgc/shape->selector shape))
|
||||
svg-markup
|
||||
indent))
|
||||
|
||||
(cph/text-shape? shape)
|
||||
(let [text-shape-html (rds/renderToStaticMarkup (mf/element text/text-shape #js {:shape shape :code? true}))]
|
||||
(dm/fmt "%<div class=\"%\">\n%\n%</div>"
|
||||
indent
|
||||
(dm/str "shape " (d/name (:type shape)) " "
|
||||
(cgc/shape->selector shape))
|
||||
text-shape-html
|
||||
indent))
|
||||
|
||||
(cph/image-shape? shape)
|
||||
(let [data (or (:metadata shape) (:fill-image shape))
|
||||
image-url (cfg/resolve-file-media data)]
|
||||
(dm/fmt "%<img src=\"%\" class=\"%\">\n%</img>"
|
||||
indent
|
||||
image-url
|
||||
(dm/str "shape " (d/name (:type shape)) " "
|
||||
(cgc/shape->selector shape))
|
||||
indent))
|
||||
|
||||
(empty? (:shapes shape))
|
||||
(dm/fmt "%<div class=\"%\">\n%</div>"
|
||||
indent
|
||||
(dm/str "shape " (d/name (:type shape)) " "
|
||||
(cgc/shape->selector shape))
|
||||
indent)
|
||||
|
||||
:else
|
||||
(dm/fmt "%<div class=\"%\">\n%\n%</div>"
|
||||
indent
|
||||
(dm/str "shape " (d/name (:type shape)) " "
|
||||
(dm/str (d/name (:type shape)) " "
|
||||
(cgc/shape->selector shape))
|
||||
svg-markup
|
||||
(->> (:shapes shape)
|
||||
(maybe-reverse)
|
||||
(map #(generate-html objects (get objects %) (inc level)))
|
||||
(str/join "\n"))
|
||||
indent))
|
||||
|
||||
(cph/text-shape? shape)
|
||||
(let [text-shape-html (rds/renderToStaticMarkup (mf/element text/text-shape #js {:shape shape :code? true}))]
|
||||
(dm/fmt "%<div class=\"%\">\n%\n%</div>"
|
||||
indent
|
||||
(dm/str "shape " (d/name (:type shape)) " "
|
||||
(cgc/shape->selector shape))
|
||||
text-shape-html
|
||||
indent))
|
||||
shape-html
|
||||
(if (cgc/has-wrapper? objects shape)
|
||||
(dm/fmt "<div class=\"%\">%</div>"
|
||||
(dm/str (cgc/shape->selector shape) "-wrapper")
|
||||
shape-html)
|
||||
|
||||
(cph/image-shape? shape)
|
||||
(let [data (or (:metadata shape) (:fill-image shape))
|
||||
image-url (cfg/resolve-file-media data)]
|
||||
(dm/fmt "%<img src=\"%\" class=\"%\">\n%</img>"
|
||||
indent
|
||||
image-url
|
||||
(dm/str "shape " (d/name (:type shape)) " "
|
||||
(cgc/shape->selector shape))
|
||||
indent))
|
||||
|
||||
(empty? (:shapes shape))
|
||||
(dm/fmt "%<div class=\"%\">\n%</div>"
|
||||
indent
|
||||
(dm/str "shape " (d/name (:type shape)) " "
|
||||
(cgc/shape->selector shape))
|
||||
indent)
|
||||
|
||||
:else
|
||||
(dm/fmt "%<div class=\"%\">\n%\n%</div>"
|
||||
indent
|
||||
(dm/str (d/name (:type shape)) " "
|
||||
(cgc/shape->selector shape))
|
||||
(->> (:shapes shape)
|
||||
(maybe-reverse)
|
||||
(map #(generate-html objects (get objects %) (inc level)))
|
||||
(str/join "\n"))
|
||||
indent))
|
||||
|
||||
shape-html
|
||||
(if (cgc/has-wrapper? objects shape)
|
||||
(dm/fmt "<div class=\"%\">%</div>"
|
||||
(dm/str (cgc/shape->selector shape) "-wrapper")
|
||||
shape-html)
|
||||
|
||||
shape-html)]
|
||||
(dm/fmt "%<!-- % -->\n%" indent (dm/str (d/name (:type shape)) ": " (:name shape)) shape-html))))
|
||||
shape-html)]
|
||||
(dm/fmt "%<!-- % -->\n%" indent (dm/str (d/name (:type shape)) ": " (:name shape)) shape-html)))))
|
||||
|
||||
(defn generate-markup
|
||||
[objects shapes]
|
||||
(->> shapes
|
||||
(map #(generate-html objects %))
|
||||
(keep #(generate-html objects %))
|
||||
(str/join "\n")))
|
||||
|
|
|
@ -9,7 +9,8 @@
|
|||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.geom.matrix :as gmt]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.geom.shapes.bounds :as gsb]
|
||||
[app.common.geom.shapes.points :as gpo]
|
||||
[app.common.pages.helpers :as cph]
|
||||
[app.common.text :as txt]
|
||||
[app.common.types.shape.layout :as ctl]
|
||||
|
@ -38,13 +39,6 @@ body {
|
|||
gap: 2rem;
|
||||
}
|
||||
|
||||
svg {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
@ -64,7 +58,10 @@ svg {
|
|||
:justify-self
|
||||
:grid-column
|
||||
:grid-row
|
||||
:z-index})
|
||||
:z-index
|
||||
:top
|
||||
:left
|
||||
:position})
|
||||
|
||||
(def shape-css-properties
|
||||
[:position
|
||||
|
@ -139,12 +136,16 @@ svg {
|
|||
[shape objects]
|
||||
(when (and (ctl/any-layout-immediate-child? objects shape)
|
||||
(not (gmt/unit? (:transform shape))))
|
||||
(let [{:keys [width height]} (gsh/shapes->rect [shape])]
|
||||
(cond-> [[:position "relative"]
|
||||
[:width width]
|
||||
(let [parent (get objects (:parent-id shape))
|
||||
bounds (gpo/parent-coords-bounds (:points shape) (:points parent))
|
||||
width (gpo/width-points bounds)
|
||||
height (gpo/height-points bounds)]
|
||||
(cond-> [[:width width]
|
||||
[:height height]]
|
||||
(ctl/flex-layout-immediate-child? objects shape)
|
||||
(conj [:flex-shrink 0])))))
|
||||
|
||||
(or (not (ctl/any-layout-immediate-child? objects shape))
|
||||
(not (ctl/layout-absolute? shape)))
|
||||
(conj [:position "relative"])))))
|
||||
|
||||
(defn shape->wrapper-child-css-properties
|
||||
[shape objects]
|
||||
|
@ -153,6 +154,16 @@ svg {
|
|||
[:left "50%"]
|
||||
[:top "50%"]]))
|
||||
|
||||
(defn shape->svg-props
|
||||
[shape objects]
|
||||
(let [bounds (gsb/get-object-bounds objects shape)]
|
||||
[[:position "absolute"]
|
||||
[:top 0]
|
||||
[:left 0]
|
||||
[:transform (dm/fmt "translate(%,%)"
|
||||
(dm/str (- (:x bounds) (-> shape :selrect :x)) "px")
|
||||
(dm/str (- (:y bounds) (-> shape :selrect :y)) "px"))]]))
|
||||
|
||||
(defn shape->css-properties
|
||||
"Given a shape extract the CSS properties in the format of list [property value]"
|
||||
[shape objects properties]
|
||||
|
@ -235,40 +246,49 @@ svg {
|
|||
(get-shape-css-selector shape objects nil))
|
||||
|
||||
([shape objects options]
|
||||
(let [selector (cgc/shape->selector shape)
|
||||
(when (and (some? shape) (some? (:selrect shape)))
|
||||
(let [selector (cgc/shape->selector shape)
|
||||
|
||||
wrapper? (cgc/has-wrapper? objects shape)
|
||||
wrapper? (cgc/has-wrapper? objects shape)
|
||||
svg? (cgc/svg-markup? shape)
|
||||
|
||||
css-properties
|
||||
(if wrapper?
|
||||
(filter (complement shape-wrapper-css-properties) shape-css-properties)
|
||||
shape-css-properties)
|
||||
css-properties
|
||||
(if wrapper?
|
||||
(filter (complement shape-wrapper-css-properties) shape-css-properties)
|
||||
shape-css-properties)
|
||||
|
||||
properties
|
||||
(-> shape
|
||||
(shape->css-properties objects css-properties)
|
||||
(format-css-properties options))
|
||||
|
||||
wrapper-properties
|
||||
(when wrapper?
|
||||
(-> (d/concat-vec
|
||||
(shape->css-properties shape objects shape-wrapper-css-properties)
|
||||
(shape->wrapper-css-properties shape objects))
|
||||
(format-css-properties options)))
|
||||
|
||||
wrapper-child-properties
|
||||
(when wrapper?
|
||||
properties
|
||||
(-> shape
|
||||
(shape->wrapper-child-css-properties objects)
|
||||
(format-css-properties options)))]
|
||||
(shape->css-properties objects css-properties)
|
||||
(format-css-properties options))
|
||||
|
||||
(str/join
|
||||
"\n"
|
||||
(filter some? [(str/fmt "/* %s */" (:name shape))
|
||||
(when wrapper? (str/fmt ".%s-wrapper {\n%s\n}" selector wrapper-properties))
|
||||
(when wrapper? (str/fmt ".%s-wrapper > * {\n%s\n}" selector wrapper-child-properties))
|
||||
(str/fmt ".%s {\n%s\n}" selector properties)
|
||||
(when (cph/text-shape? shape) (generate-text-css shape))])))))
|
||||
wrapper-properties
|
||||
(when wrapper?
|
||||
(-> (d/concat-vec
|
||||
(shape->css-properties shape objects shape-wrapper-css-properties)
|
||||
(shape->wrapper-css-properties shape objects))
|
||||
(format-css-properties options)))
|
||||
|
||||
wrapper-child-properties
|
||||
(when wrapper?
|
||||
(-> shape
|
||||
(shape->wrapper-child-css-properties objects)
|
||||
(format-css-properties options)))
|
||||
|
||||
svg-child-props
|
||||
(when svg?
|
||||
(-> shape
|
||||
(shape->svg-props objects)
|
||||
(format-css-properties options)))]
|
||||
|
||||
(str/join
|
||||
"\n"
|
||||
(filter some? [(str/fmt "/* %s */" (:name shape))
|
||||
(when wrapper? (str/fmt ".%s-wrapper {\n%s\n}" selector wrapper-properties))
|
||||
(when wrapper? (str/fmt ".%s-wrapper > * {\n%s\n}" selector wrapper-child-properties))
|
||||
(when svg? (str/fmt ".%s > svg {\n%s\n}" selector svg-child-props))
|
||||
(str/fmt ".%s {\n%s\n}" selector properties)
|
||||
(when (cph/text-shape? shape) (generate-text-css shape))]))))))
|
||||
|
||||
(defn get-css-property
|
||||
([objects shape property]
|
||||
|
@ -294,5 +314,5 @@ svg {
|
|||
(dm/str
|
||||
prelude
|
||||
(->> shapes
|
||||
(map #(get-shape-css-selector % objects options))
|
||||
(keep #(get-shape-css-selector % objects options))
|
||||
(str/join "\n\n")))))
|
||||
|
|
|
@ -49,12 +49,14 @@
|
|||
(when (and (not (cph/root-frame? shape))
|
||||
(or (not (ctl/any-layout-immediate-child? objects shape))
|
||||
(ctl/layout-absolute? shape)))
|
||||
|
||||
(let [parent (get objects (:parent-id shape))
|
||||
|
||||
parent-value (dm/get-in parent [:selrect coord])
|
||||
|
||||
[selrect _ _]
|
||||
(-> (:points shape)
|
||||
(gsh/transform-points (gsh/shape->center parent) (:transform-inverse parent))
|
||||
(gsh/transform-points (gsh/shape->center parent) (:transform-inverse parent (gmt/matrix)))
|
||||
(gsh/calculate-geometry))
|
||||
|
||||
shape-value (get selrect coord)]
|
||||
|
@ -117,7 +119,17 @@
|
|||
|
||||
(defmethod get-value :transform
|
||||
[_ shape objects]
|
||||
(when-not (cgc/svg-markup? shape)
|
||||
(if (cgc/svg-markup? shape)
|
||||
(let [parent (get objects (:parent-id shape))
|
||||
transform
|
||||
(:transform-inverse parent (gmt/matrix))
|
||||
|
||||
transform-str (when-not (gmt/unit? transform) (fmt/format-matrix transform))]
|
||||
|
||||
(if (cgc/has-wrapper? objects shape)
|
||||
(dm/str "translate(-50%, -50%) " (d/nilv transform-str ""))
|
||||
transform-str))
|
||||
|
||||
(let [parent (get objects (:parent-id shape))
|
||||
|
||||
transform
|
||||
|
@ -207,6 +219,7 @@
|
|||
(defmethod get-value :overflow
|
||||
[_ shape _]
|
||||
(when (and (cph/frame-shape? shape)
|
||||
(not (cgc/svg-markup? shape))
|
||||
(not (:show-content shape)))
|
||||
"hidden"))
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue