diff --git a/common/src/app/common/geom/proportions.cljc b/common/src/app/common/geom/proportions.cljc index 8294e4301..d6f37c216 100644 --- a/common/src/app/common/geom/proportions.cljc +++ b/common/src/app/common/geom/proportions.cljc @@ -22,8 +22,8 @@ :proportion (/ width height) :proportion-lock true))) -(defn setup-proportions-svg - [{:keys [width height] :as shape}] +(defn setup-proportions-size + [{{:keys [width height]} :selrect :as shape}] (assoc shape :proportion (/ width height) :proportion-lock true)) @@ -35,9 +35,11 @@ :proportion-lock false)) (defn setup-proportions - [shape] - (case (:type shape) - :svg-raw (setup-proportions-svg shape) - :image (setup-proportions-image shape) - :text shape - (setup-proportions-const shape))) + [{:keys [type] :as shape}] + (let [image-fill? (every? #(some? (:fill-image %)) (:fills shape))] + (cond + (= type :svg-raw) (setup-proportions-size shape) + (= type :image) (setup-proportions-image shape) + image-fill? (setup-proportions-size shape) + (= type :text) shape + :else (setup-proportions-const shape)))) diff --git a/common/src/app/common/types/color.cljc b/common/src/app/common/types/color.cljc index 3a726d77a..382530ac2 100644 --- a/common/src/app/common/types/color.cljc +++ b/common/src/app/common/types/color.cljc @@ -52,7 +52,8 @@ [:width :int] [:height :int] [:mtype {:optional true} [:maybe :string]] - [:id ::sm/uuid]]) + [:id ::sm/uuid] + [:keep-aspect-ratio {:optional true} :boolean]]) (sm/define! ::gradient [:map {:title "Gradient"} diff --git a/frontend/src/app/main/data/workspace/media.cljs b/frontend/src/app/main/data/workspace/media.cljs index c68dfe00a..3dc6c8d7a 100644 --- a/frontend/src/app/main/data/workspace/media.cljs +++ b/frontend/src/app/main/data/workspace/media.cljs @@ -72,7 +72,8 @@ :width width :height height :mtype mtype - :id id}}]}] + :id id + :keep-aspect-ratio true}}]}] (rx/of (dwsh/create-and-add-shape :rect x y shape)))))) (defn svg-uploaded @@ -358,7 +359,8 @@ :id id :width width :height height - :mtype mtype}}] + :mtype mtype + :keep-aspect-ratio true}}] :name name :frame-id (:id frame-shape) :parent-id (:id frame-shape)})] diff --git a/frontend/src/app/main/ui/shapes/fills.cljs b/frontend/src/app/main/ui/shapes/fills.cljs index e4cb1eee3..076a662c0 100644 --- a/frontend/src/app/main/ui/shapes/fills.cljs +++ b/frontend/src/app/main/ui/shapes/fills.cljs @@ -117,9 +117,10 @@ :style style}] (if (:fill-image value) (let [uri (cf/resolve-file-media (:fill-image value)) + keep-ar? (-> value :fill-image :keep-aspect-ratio) image-props #js {:id (dm/str "fill-image-" render-id "-" fill-index) :href (get uris uri uri) - :preserveAspectRatio "xMidYMid slice" + :preserveAspectRatio (if keep-ar? "xMidYMid slice" "none") :width width :height height :key (dm/str fill-index) diff --git a/frontend/src/app/main/ui/workspace.scss b/frontend/src/app/main/ui/workspace.scss index 0c7df3205..0cc517eae 100644 --- a/frontend/src/app/main/ui/workspace.scss +++ b/frontend/src/app/main/ui/workspace.scss @@ -29,6 +29,7 @@ grid-template-areas: "left-sidebar viewport right-sidebar"; grid-template-rows: 1fr; grid-template-columns: auto 1fr auto; + overflow: hidden; .workspace-loader { @include flexCenter; diff --git a/frontend/src/app/main/ui/workspace/colorpicker.cljs b/frontend/src/app/main/ui/workspace/colorpicker.cljs index e74f83525..9328a1144 100644 --- a/frontend/src/app/main/ui/workspace/colorpicker.cljs +++ b/frontend/src/app/main/ui/workspace/colorpicker.cljs @@ -84,7 +84,10 @@ on-fill-image-success (mf/use-fn (fn [image] - (st/emit! (dc/update-colorpicker-color {:image (select-keys image [:id :width :height :mtype :name])} (not @drag?))))) + (st/emit! (dc/update-colorpicker-color + {:image (-> (select-keys image [:id :width :height :mtype :name]) + (assoc :keep-aspect-ratio true))} + (not @drag?))))) on-fill-image-click (mf/use-callback #(dom/click (mf/ref-val fill-image-ref))) @@ -94,6 +97,16 @@ (fn [file] (st/emit! (dwm/upload-fill-image file on-fill-image-success)))) + handle-change-keep-aspect-ratio + (mf/use-fn + (mf/deps current-color) + (fn [] + (let [keep-aspect-ratio? (-> current-color :image :keep-aspect-ratio not)] + (st/emit! (dc/update-colorpicker-color + {:image (-> (:image current-color) + (assoc :keep-aspect-ratio keep-aspect-ratio?))} + true))))) + set-tab! (mf/use-fn (fn [event] @@ -248,11 +261,23 @@ :on-select-stop handle-change-stop}]) (if (= selected-mode :image) - (let [uri (cfg/resolve-file-media (:image current-color))] + (let [uri (cfg/resolve-file-media (:image current-color)) + keep-aspect-ratio? (-> current-color :image :keep-aspect-ratio)] [:div {:class (stl/css :select-image)} [:div {:class (stl/css :content)} (when (:image current-color) [:img {:src uri}])] + + [:div {:class (stl/css :checkbox-option)} + [:label {:for "keep-aspect-ratio" + :class (stl/css-case :global/checked keep-aspect-ratio?)} + [:span {:class (stl/css-case :global/checked keep-aspect-ratio?)} + (when keep-aspect-ratio? i/status-tick-refactor)] + (tr "media.keep-aspect-ratio") + [:input {:type "checkbox" + :id "keep-aspect-ratio" + :checked keep-aspect-ratio? + :on-change handle-change-keep-aspect-ratio}]]] [:button {:class (stl/css :choose-image) :title (tr "media.choose-image") diff --git a/frontend/src/app/main/ui/workspace/colorpicker.scss b/frontend/src/app/main/ui/workspace/colorpicker.scss index f3049f387..62a7e5527 100644 --- a/frontend/src/app/main/ui/workspace/colorpicker.scss +++ b/frontend/src/app/main/ui/workspace/colorpicker.scss @@ -166,3 +166,8 @@ margin-top: $s-12; height: $s-32; } + +.checkbox-option { + @extend .input-checkbox; + margin: $s-16 0 0 0; +} diff --git a/frontend/src/app/main/ui/workspace/viewport/widgets.cljs b/frontend/src/app/main/ui/workspace/viewport/widgets.cljs index 316cf6d0b..ab0b10777 100644 --- a/frontend/src/app/main/ui/workspace/viewport/widgets.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/widgets.cljs @@ -166,16 +166,16 @@ :y -11 :width (max 0 (- text-width text-pos-x)) :height 20 - :class "workspace-frame-label" + :class (stl/css :workspace-frame-label-wrapper) :style {:fill color} - :visibility (if show-artboard-names? "visible" "hidden") - :on-pointer-down on-pointer-down - :on-double-click on-double-click - :on-context-menu on-context-menu - :on-pointer-enter on-pointer-enter - :on-pointer-leave on-pointer-leave} + :visibility (if show-artboard-names? "visible" "hidden")} [:div {:class (stl/css :workspace-frame-label) - :style {:color color}} + :style {:color color} + :on-pointer-down on-pointer-down + :on-double-click on-double-click + :on-context-menu on-context-menu + :on-pointer-enter on-pointer-enter + :on-pointer-leave on-pointer-leave} (if show-id? (dm/str (dm/str (:id frame)) " - " (:name frame)) (:name frame))]]]))) diff --git a/frontend/src/app/main/ui/workspace/viewport/widgets.scss b/frontend/src/app/main/ui/workspace/viewport/widgets.scss index 326057ce1..19d5e467f 100644 --- a/frontend/src/app/main/ui/workspace/viewport/widgets.scss +++ b/frontend/src/app/main/ui/workspace/viewport/widgets.scss @@ -63,10 +63,16 @@ } } +.workspace-frame-label-wrapper { + pointer-events: none; +} + .workspace-frame-label { font-size: $fs-12; color: black; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; + max-width: fit-content; + pointer-events: all; } diff --git a/frontend/translations/en.po b/frontend/translations/en.po index f26593180..be4499c87 100644 --- a/frontend/translations/en.po +++ b/frontend/translations/en.po @@ -5074,6 +5074,9 @@ msgstr "Gradient" msgid "media.choose-image" msgstr "Choose image" +msgid "media.keep-aspect-ratio" +msgstr "Keep aspect ratio" + msgid "workspace.options.guides.title" msgstr "Guides" diff --git a/frontend/translations/es.po b/frontend/translations/es.po index 4fe0c535e..c121150b3 100644 --- a/frontend/translations/es.po +++ b/frontend/translations/es.po @@ -5158,6 +5158,9 @@ msgstr "Gradiente" msgid "media.choose-image" msgstr "Elegir imagen" +msgid "media.keep-aspect-ratio" +msgstr "Mantener la proporción" + msgid "workspace.options.guides.title" msgstr "Guías"