diff --git a/frontend/src/app/main/data/workspace/thumbnails.cljs b/frontend/src/app/main/data/workspace/thumbnails.cljs index 64f1b4c03..2019b340b 100644 --- a/frontend/src/app/main/data/workspace/thumbnails.cljs +++ b/frontend/src/app/main/data/workspace/thumbnails.cljs @@ -40,7 +40,7 @@ (rx/take 1))] ;; renders #svg image (if (some? node) - (->> (rx/from (js/createImageBitmap node)) + (->> (rx/from (wapi/create-image-bitmap-with-workaround node)) (rx/switch-map #(uw/ask! {:cmd :thumbnails/render-offscreen-canvas} %)) (rx/map :result)) diff --git a/frontend/src/app/main/ui/workspace/shapes/frame/thumbnail_render.cljs b/frontend/src/app/main/ui/workspace/shapes/frame/thumbnail_render.cljs index 348497b65..ca6a815e4 100644 --- a/frontend/src/app/main/ui/workspace/shapes/frame/thumbnail_render.cljs +++ b/frontend/src/app/main/ui/workspace/shapes/frame/thumbnail_render.cljs @@ -10,7 +10,6 @@ [app.common.data.macros :as dm] [app.common.geom.rect :as grc] [app.common.geom.shapes :as gsh] - [app.common.math :as mth] [app.config :as cf] [app.main.data.workspace.thumbnails :as dwt] [app.main.refs :as refs] @@ -18,6 +17,7 @@ [app.main.ui.hooks :as hooks] [app.main.ui.shapes.frame :as frame] [app.util.dom :as dom] + [app.util.thumbnails :as th] [app.util.timers :as ts] [app.util.webapi :as wapi] [beicon.core :as rx] @@ -46,12 +46,7 @@ ;; Calculate the fixed width and height ;; We don't want to generate thumbnails ;; bigger than 2000px - [fixed-width fixed-height] - (if (> width height) - [(mth/clamp width 250 2000) - (/ (* height (mth/clamp width 250 2000)) width)] - [(/ (* width (mth/clamp height 250 2000)) height) - (mth/clamp height 250 2000)]) + [fixed-width fixed-height] (th/get-proportional-size width height) ;; This is way faster than creating a node ;; through the DOM API diff --git a/frontend/src/app/util/thumbnails.cljs b/frontend/src/app/util/thumbnails.cljs new file mode 100644 index 000000000..e44a7be3e --- /dev/null +++ b/frontend/src/app/util/thumbnails.cljs @@ -0,0 +1,29 @@ +;; 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) KALEIDOS INC + +(ns app.util.thumbnails + (:require + [app.common.math :as mth])) + +(def ^:const min-size 250) +(def ^:const max-size 2000) + +(defn get-proportional-size + "Returns a proportional size given a width and height and some size constraints." + ([width height] + (get-proportional-size width height min-size max-size min-size max-size)) + ([width height min-size max-size] + (get-proportional-size width height min-size max-size min-size max-size)) + ([width height min-width max-width min-height max-height] + (let [[fixed-width fixed-height] + (if (> width height) + [(mth/clamp width min-width max-width) + (/ (* height (mth/clamp width min-width max-width)) width)] + [(/ (* width (mth/clamp height min-height max-height)) height) + (mth/clamp height min-height max-height)])] + [fixed-width fixed-height]))) + + diff --git a/frontend/src/app/util/webapi.cljs b/frontend/src/app/util/webapi.cljs index 183573c13..db5fd1146 100644 --- a/frontend/src/app/util/webapi.cljs +++ b/frontend/src/app/util/webapi.cljs @@ -11,6 +11,7 @@ [app.common.exceptions :as ex] [app.common.logging :as log] [app.util.object :as obj] + [app.util.thumbnails :as th] [beicon.core :as rx] [cuerdas.core :as str] [promesa.core :as p])) @@ -130,12 +131,40 @@ (map #(.item ^js file-list %)) (filter #(str/starts-with? (.-type %) "image/")))))) +(defn create-canvas-element + [width height] + (let [canvas (.createElement js/document "canvas")] + (obj/set! canvas "width" width) + (obj/set! canvas "height" height) + canvas)) + +(defn create-offscreen-canvas + [width height] + (if (obj/in? js/window "OffscreenCanvas") + (js/OffscreenCanvas. width height) + (create-canvas-element width height))) + (defn create-image-bitmap ([image] (js/createImageBitmap image)) ([image options] (js/createImageBitmap image options))) +;; Why this? Because as described in https://bugs.chromium.org/p/chromium/issues/detail?id=1463435 +;; the createImageBitmap seems to apply premultiplied alpha multiples times on the same image +;; which results in harsh borders around text being rendered. This is a workaround to avoid this issue. +(defn create-image-bitmap-with-workaround + ([image] + (create-image-bitmap-with-workaround image nil)) + ([image options] + (let [width (.-value (.-baseVal (.-width image))) + height (.-value (.-baseVal (.-height image))) + [width height] (th/get-proportional-size width height) + offscreen-canvas (create-offscreen-canvas width height) + offscreen-context (.getContext offscreen-canvas "2d")] + (.drawImage offscreen-context image 0 0) + (create-image-bitmap offscreen-canvas options)))) + (defn request-fullscreen [el] (cond