diff --git a/CHANGES.md b/CHANGES.md index 169624d0a..3f41e504e 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -39,6 +39,7 @@ - Fix problem with multiple exports [Taiga #2468](https://tree.taiga.io/project/penpot/issue/2468) - Allow import to continue from recoverable failures [#1412](https://github.com/penpot/penpot/issues/1412) - Improved behaviour on text options when not text is selected [Taiga #2390](https://tree.taiga.io/project/penpot/issue/2390) +- Fix decimal numbers in export viewbox [Taiga #2290](https://tree.taiga.io/project/penpot/issue/2290) ### :arrow_up: Deps updates ### :heart: Community contributions by (Thank you!) diff --git a/frontend/src/app/main/exports.cljs b/frontend/src/app/main/exports.cljs index 04da9d9d9..318643a03 100644 --- a/frontend/src/app/main/exports.cljs +++ b/frontend/src/app/main/exports.cljs @@ -29,11 +29,13 @@ [app.main.ui.shapes.text :as text] [app.main.ui.shapes.text.fontfaces :as ff] [app.util.object :as obj] + [app.util.strings :as ust] [app.util.timers :as ts] [cuerdas.core :as str] [debug :refer [debug?]] [rumext.alpha :as mf])) +(def ^:const viewbox-decimal-precision 3) (def ^:private default-color clr/canvas) (mf/defc background @@ -139,8 +141,13 @@ ;; Don't wrap svg elements inside a otherwise some can break [:> svg-raw-wrapper {:shape shape :frame frame}])))))) -(defn get-viewbox [{:keys [x y width height] :or {x 0 y 0 width 100 height 100}}] - (str/fmt "%s %s %s %s" x y width height)) +(defn format-viewbox + "Format a viewbox given a rectangle" + [{:keys [x y width height] :or {x 0 y 0 width 100 height 100}}] + (str/join + " " + (->> [x y width height] + (map #(ust/format-precision % viewbox-decimal-precision))))) (mf/defc page-svg {::mf/wrap [mf/memo]} @@ -160,7 +167,7 @@ vport (when (and (some? width) (some? height)) {:width width :height height}) dim (calculate-dimensions data vport) - vbox (get-viewbox dim) + vbox (format-viewbox dim) background-color (get-in data [:options :background] default-color) frame-wrapper (mf/use-memo @@ -221,15 +228,15 @@ width (* (:width frame) zoom) height (* (:height frame) zoom) - vbox (str "0 0 " (:width frame 0) - " " (:height frame 0)) + vbox (format-viewbox {:width (:width frame 0) :height (:height frame 0)}) + wrapper (mf/use-memo (mf/deps objects) #(frame-wrapper-factory objects))] [:svg {:view-box vbox - :width width - :height height + :width (ust/format-precision width viewbox-decimal-precision) + :height (ust/format-precision height viewbox-decimal-precision) :version "1.1" :xmlns "http://www.w3.org/2000/svg" :xmlnsXlink "http://www.w3.org/1999/xlink" @@ -255,18 +262,20 @@ group (get objects group-id) + width (* (:width group) zoom) height (* (:height group) zoom) - vbox (str "0 0 " (:width group 0) - " " (:height group 0)) + vbox (format-viewbox {:width (:width group 0) + :height (:height group 0)}) + group-wrapper (mf/use-memo (mf/deps objects) #(group-wrapper-factory objects))] [:svg {:view-box vbox - :width width - :height height + :width (ust/format-precision width viewbox-decimal-precision) + :height (ust/format-precision height viewbox-decimal-precision) :version "1.1" :xmlns "http://www.w3.org/2000/svg" :xmlnsXlink "http://www.w3.org/1999/xlink" @@ -281,7 +290,7 @@ root (get objects id) {:keys [width height]} (:selrect root) - vbox (str "0 0 " width " " height) + vbox (format-viewbox {:width width :height height}) modifier (-> (gpt/point (:x root) (:y root)) (gpt/negate) diff --git a/frontend/src/app/main/ui/components/numeric_input.cljs b/frontend/src/app/main/ui/components/numeric_input.cljs index 04483405f..f385796da 100644 --- a/frontend/src/app/main/ui/components/numeric_input.cljs +++ b/frontend/src/app/main/ui/components/numeric_input.cljs @@ -13,6 +13,7 @@ [app.util.keyboard :as kbd] [app.util.object :as obj] [app.util.simple-math :as sm] + [app.util.strings :as ust] [rumext.alpha :as mf])) (defn num? [val] @@ -20,12 +21,6 @@ (not (math/nan? val)) (math/finite? val))) -(defn fixed [value precision] - (try - (.toFixed value precision) - (catch :default _ - (str value)))) - (mf/defc numeric-input {::mf/wrap-props false ::mf/forward-ref true} @@ -102,7 +97,7 @@ (fn [new-value] (let [input-node (mf/ref-val ref)] (dom/set-value! input-node (if (some? precision) - (fixed new-value precision) + (ust/format-precision new-value precision) (str new-value)))))) apply-value diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/typography.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/typography.cljs index d5bf868b5..c39f71599 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/typography.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/typography.cljs @@ -23,6 +23,7 @@ [app.util.keyboard :as kbd] [app.util.object :as obj] [app.util.router :as rt] + [app.util.strings :as ust] [app.util.timers :as tm] [cuerdas.core :as str] [goog.events :as events] @@ -31,7 +32,7 @@ (defn- attr->string [value] (if (= value :multiple) "" - (str value))) + (ust/format-precision value 2))) (defn- get-next-font [{:keys [id] :as current} fonts] diff --git a/frontend/src/app/util/strings.cljs b/frontend/src/app/util/strings.cljs new file mode 100644 index 000000000..e51bbe86d --- /dev/null +++ b/frontend/src/app/util/strings.cljs @@ -0,0 +1,38 @@ +;; 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/. +;; +;; Copyright (c) UXBOX Labs SL + +(ns app.util.strings + (:require + [cuerdas.core :as str])) + + +(def ^:const trail-zeros-regex-1 #"\.0+$") +(def ^:const trail-zeros-regex-2 #"(\.\d*[^0])0+$") + +(defn format-precision + "Creates a number with predetermined precision and then removes the trailing 0. + Examples: + 12.0123, 0 => 12 + 12.0123, 1 => 12 + 12.0123, 2 => 12.01" + [num precision] + + (try + (if (number? num) + (let [num-str (.toFixed num precision) + + ;; Remove all trailing zeros after the comma 100.00000 + num-str (str/replace num-str trail-zeros-regex-1 "") + + ;; Remove trailing zeros after a decimal number: 0.001|00| + num-str (if-let [m (re-find trail-zeros-regex-2 num-str)] + (str/replace num-str (first m) (second m)) + num-str)] + num-str) + (str num)) + (catch :default _ + (str num)))) +