mirror of
https://github.com/penpot/penpot.git
synced 2025-05-16 20:46:11 +02:00
✨ Add support for WASM transforms
This commit is contained in:
parent
a3a757f842
commit
1bb337c3dd
18 changed files with 658 additions and 153 deletions
|
@ -28,6 +28,8 @@
|
|||
[app.main.data.workspace.guides :as-alias dwg]
|
||||
[app.main.data.workspace.shapes :as dwsh]
|
||||
[app.main.data.workspace.undo :as dwu]
|
||||
[app.main.features :as features]
|
||||
[app.render-wasm.api :as wasm.api]
|
||||
[beicon.v2.core :as rx]
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
|
@ -160,8 +162,13 @@
|
|||
change-to-fixed?
|
||||
(assoc :grow-type :fixed))))
|
||||
|
||||
(defn- clear-local-transform []
|
||||
(defn clear-local-transform []
|
||||
(ptk/reify ::clear-local-transform
|
||||
ptk/EffectEvent
|
||||
(effect [_ state _]
|
||||
(when (features/active-feature? state "render-wasm/v1")
|
||||
(wasm.api/set-modifiers nil)))
|
||||
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(-> state
|
||||
|
@ -391,6 +398,7 @@
|
|||
(update [_ state]
|
||||
(update state :workspace-modifiers calculate-update-modifiers state ignore-constraints ignore-snap-pixel modif-tree)))))
|
||||
|
||||
|
||||
(defn set-modifiers
|
||||
([modif-tree]
|
||||
(set-modifiers modif-tree false))
|
||||
|
@ -409,6 +417,37 @@
|
|||
modifiers (calculate-modifiers state ignore-constraints ignore-snap-pixel modif-tree page-id params)]
|
||||
(assoc state :workspace-modifiers modifiers))))))
|
||||
|
||||
(defn set-wasm-modifiers
|
||||
([modif-tree]
|
||||
(set-wasm-modifiers modif-tree false))
|
||||
|
||||
([modif-tree ignore-constraints]
|
||||
(set-wasm-modifiers modif-tree ignore-constraints false))
|
||||
|
||||
([modif-tree ignore-constraints ignore-snap-pixel]
|
||||
(set-wasm-modifiers modif-tree ignore-constraints ignore-snap-pixel nil))
|
||||
|
||||
([modif-tree _ignore-constraints _ignore-snap-pixel _params]
|
||||
(ptk/reify ::set-wasm-modifiers
|
||||
ptk/EffectEvent
|
||||
(effect [_ _ _]
|
||||
(let [entries
|
||||
(->> modif-tree
|
||||
(mapv (fn [[id data]]
|
||||
{:id id
|
||||
:transform (ctm/modifiers->transform (:modifiers data))})))
|
||||
|
||||
modifiers-new
|
||||
(wasm.api/propagate-modifiers entries)]
|
||||
(wasm.api/set-modifiers modifiers-new))))))
|
||||
|
||||
(defn set-selrect-transform
|
||||
[modifiers]
|
||||
(ptk/reify ::set-selrect-transform
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(assoc state :workspace-selrect-transform (ctm/modifiers->transform modifiers)))))
|
||||
|
||||
(def ^:private
|
||||
xf-rotation-shape
|
||||
(comp
|
||||
|
@ -418,6 +457,33 @@
|
|||
|
||||
;; Rotation use different algorithm to calculate children
|
||||
;; modifiers (and do not use child constraints).
|
||||
(defn set-wasm-rotation-modifiers
|
||||
([angle shapes]
|
||||
(set-wasm-rotation-modifiers angle shapes (-> shapes gsh/shapes->rect grc/rect->center)))
|
||||
|
||||
([angle shapes center]
|
||||
(ptk/reify ::set-wasm-rotation-modifiers
|
||||
ptk/EffectEvent
|
||||
(effect [_ state _]
|
||||
(let [objects (dsh/lookup-page-objects state)
|
||||
ids (sequence xf-rotation-shape shapes)
|
||||
|
||||
get-modifier
|
||||
(fn [shape]
|
||||
(ctm/rotation-modifiers shape center angle))
|
||||
|
||||
modif-tree
|
||||
(-> (build-modif-tree ids objects get-modifier)
|
||||
(gm/set-objects-modifiers objects))
|
||||
|
||||
modifiers
|
||||
(->> modif-tree
|
||||
(map (fn [[id {:keys [modifiers]}]]
|
||||
{:id id
|
||||
:transform (ctm/modifiers->transform modifiers)})))]
|
||||
|
||||
(wasm.api/set-modifiers modifiers))))))
|
||||
|
||||
(defn set-rotation-modifiers
|
||||
([angle shapes]
|
||||
(set-rotation-modifiers angle shapes (-> shapes gsh/shapes->rect grc/rect->center)))
|
||||
|
@ -575,3 +641,4 @@
|
|||
(if undo-transation?
|
||||
(rx/of (dwu/commit-undo-transaction undo-id))
|
||||
(rx/empty))))))))
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
[app.main.data.workspace.modifiers :as dwm]
|
||||
[app.main.data.workspace.selection :as dws]
|
||||
[app.main.data.workspace.undo :as dwu]
|
||||
[app.main.features :as features]
|
||||
[app.main.snap :as snap]
|
||||
[app.main.streams :as ms]
|
||||
[app.util.array :as array]
|
||||
|
@ -132,7 +133,9 @@
|
|||
(ptk/reify ::finish-transform
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(update state :workspace-local dissoc :transform :duplicate-move-started? false))))
|
||||
(-> state
|
||||
(update :workspace-local dissoc :transform :duplicate-move-started?)
|
||||
(dissoc :workspace-selrect-transform)))))
|
||||
|
||||
;; -- Resize --------------------------------------------------------
|
||||
|
||||
|
@ -217,27 +220,23 @@
|
|||
(not (mth/close? (dm/get-prop scalev :x) 1))
|
||||
|
||||
set-fix-height?
|
||||
(not (mth/close? (dm/get-prop scalev :y) 1))
|
||||
(not (mth/close? (dm/get-prop scalev :y) 1))]
|
||||
|
||||
modifiers (cond-> (ctm/empty)
|
||||
(some? displacement)
|
||||
(ctm/move displacement)
|
||||
(cond-> (ctm/empty)
|
||||
(some? displacement)
|
||||
(ctm/move displacement)
|
||||
|
||||
:always
|
||||
(ctm/resize scalev resize-origin shape-transform shape-transform-inverse)
|
||||
:always
|
||||
(ctm/resize scalev resize-origin shape-transform shape-transform-inverse)
|
||||
|
||||
^boolean set-fix-width?
|
||||
(ctm/change-property :layout-item-h-sizing :fix)
|
||||
^boolean set-fix-width?
|
||||
(ctm/change-property :layout-item-h-sizing :fix)
|
||||
|
||||
^boolean set-fix-height?
|
||||
(ctm/change-property :layout-item-v-sizing :fix)
|
||||
^boolean set-fix-height?
|
||||
(ctm/change-property :layout-item-v-sizing :fix)
|
||||
|
||||
^boolean scale-text
|
||||
(ctm/scale-content (dm/get-prop scalev :x)))
|
||||
|
||||
modif-tree (dwm/create-modif-tree ids modifiers)]
|
||||
|
||||
(rx/of (dwm/set-modifiers modif-tree scale-text))))
|
||||
^boolean scale-text
|
||||
(ctm/scale-content (dm/get-prop scalev :x)))))
|
||||
|
||||
;; Unifies the instantaneous proportion lock modifier
|
||||
;; activated by Shift key and the shapes own proportion
|
||||
|
@ -264,18 +263,43 @@
|
|||
focus (:workspace-focus-selected state)
|
||||
zoom (dm/get-in state [:workspace-local :zoom] 1)
|
||||
objects (dsh/lookup-page-objects state page-id)
|
||||
shapes (map (d/getf objects) ids)]
|
||||
shapes (map (d/getf objects) ids)
|
||||
|
||||
resize-events-stream
|
||||
(->> ms/mouse-position
|
||||
(rx/filter some?)
|
||||
(rx/with-latest-from ms/mouse-position-shift ms/mouse-position-alt)
|
||||
(rx/map normalize-proportion-lock)
|
||||
(rx/switch-map
|
||||
(fn [[point _ _ :as current]]
|
||||
(->> (snap/closest-snap-point page-id shapes objects layout zoom focus point)
|
||||
(rx/map #(conj current %)))))
|
||||
(rx/map #(resize shape initial-position layout %))
|
||||
(rx/share))]
|
||||
|
||||
(rx/concat
|
||||
(->> ms/mouse-position
|
||||
(rx/filter some?)
|
||||
(rx/with-latest-from ms/mouse-position-shift ms/mouse-position-alt)
|
||||
(rx/map normalize-proportion-lock)
|
||||
(rx/switch-map (fn [[point _ _ :as current]]
|
||||
(->> (snap/closest-snap-point page-id shapes objects layout zoom focus point)
|
||||
(rx/map #(conj current %)))))
|
||||
(rx/mapcat (partial resize shape initial-position layout))
|
||||
(rx/take-until stopper))
|
||||
(rx/merge
|
||||
(->> resize-events-stream
|
||||
(rx/mapcat
|
||||
(fn [modifiers]
|
||||
(let [modif-tree (dwm/create-modif-tree ids modifiers)]
|
||||
(if (features/active-feature? state "render-wasm/v1")
|
||||
(rx/of
|
||||
(dwm/set-selrect-transform modifiers)
|
||||
(dwm/set-wasm-modifiers modif-tree (contains? layout :scale-text)))
|
||||
|
||||
(rx/of (dwm/set-modifiers modif-tree (contains? layout :scale-text)))))))
|
||||
(rx/take-until stopper))
|
||||
|
||||
;; The last event we need to use the old method so the elements are correctly positioned until
|
||||
;; all the logic is implemented in wasm
|
||||
(if (features/active-feature? state "render-wasm/v1")
|
||||
(->> resize-events-stream
|
||||
(rx/take-until stopper)
|
||||
(rx/last)
|
||||
(rx/map #(dwm/set-modifiers (dwm/create-modif-tree ids %) (contains? layout :scale-text))))
|
||||
(rx/empty)))
|
||||
|
||||
(rx/of (dwm/apply-modifiers)
|
||||
(finish-transform))))))))
|
||||
|
||||
|
@ -371,7 +395,7 @@
|
|||
(assoc-in [:workspace-local :transform] :rotate)))
|
||||
|
||||
ptk/WatchEvent
|
||||
(watch [_ _ stream]
|
||||
(watch [_ state stream]
|
||||
(let [stopper (mse/drag-stopper stream)
|
||||
group (gsh/shapes->rect shapes)
|
||||
group-center (grc/rect->center group)
|
||||
|
@ -390,15 +414,29 @@
|
|||
angle (if shift?
|
||||
(* (mth/floor (/ angle 15)) 15)
|
||||
angle)]
|
||||
angle))]
|
||||
angle))
|
||||
|
||||
angle-stream
|
||||
(->> ms/mouse-position
|
||||
(rx/with-latest-from ms/mouse-position-mod ms/mouse-position-shift)
|
||||
(rx/map
|
||||
(fn [[pos mod? shift?]]
|
||||
(calculate-angle pos mod? shift?)))
|
||||
(rx/share))]
|
||||
(rx/concat
|
||||
(->> ms/mouse-position
|
||||
(rx/with-latest-from ms/mouse-position-mod ms/mouse-position-shift)
|
||||
(rx/map
|
||||
(fn [[pos mod? shift?]]
|
||||
(let [delta-angle (calculate-angle pos mod? shift?)]
|
||||
(dwm/set-rotation-modifiers delta-angle shapes group-center))))
|
||||
(rx/take-until stopper))
|
||||
(rx/merge
|
||||
(->> angle-stream
|
||||
(rx/map
|
||||
#(if (features/active-feature? state "render-wasm/v1")
|
||||
(dwm/set-wasm-rotation-modifiers % shapes group-center)
|
||||
(dwm/set-rotation-modifiers % shapes group-center)))
|
||||
(rx/take-until stopper))
|
||||
(if (features/active-feature? state "render-wasm/v1")
|
||||
(->> angle-stream
|
||||
(rx/take-until stopper)
|
||||
(rx/last)
|
||||
(rx/map #(dwm/set-rotation-modifiers % shapes group-center)))
|
||||
(rx/empty)))
|
||||
(rx/of (dwm/apply-modifiers)
|
||||
(finish-transform)))))))
|
||||
|
||||
|
@ -536,16 +574,17 @@
|
|||
position (->> ms/mouse-position
|
||||
(rx/map #(gpt/to-vec from-position %)))
|
||||
|
||||
snap-delta (rx/concat
|
||||
;; We send the nil first so the stream is not waiting for the first value
|
||||
(rx/of nil)
|
||||
(->> position
|
||||
;; FIXME: performance throttle
|
||||
(rx/throttle 20)
|
||||
(rx/switch-map
|
||||
(fn [pos]
|
||||
(->> (snap/closest-snap-move page-id shapes objects layout zoom focus pos)
|
||||
(rx/map #(array pos %)))))))]
|
||||
snap-delta
|
||||
(rx/concat
|
||||
;; We send the nil first so the stream is not waiting for the first value
|
||||
(rx/of nil)
|
||||
(->> position
|
||||
;; FIXME: performance throttle
|
||||
(rx/throttle 20)
|
||||
(rx/switch-map
|
||||
(fn [pos]
|
||||
(->> (snap/closest-snap-move page-id shapes objects layout zoom focus pos)
|
||||
(rx/map #(array pos %)))))))]
|
||||
(if (empty? shapes)
|
||||
(rx/of (finish-transform))
|
||||
(let [move-stream
|
||||
|
@ -570,29 +609,45 @@
|
|||
cell-data (when (and grid-layout? (not mod?)) (gslg/get-drop-cell target-frame objects position))]
|
||||
(array move-vector target-frame drop-index cell-data))))
|
||||
|
||||
(rx/take-until stopper))]
|
||||
(rx/take-until stopper))
|
||||
|
||||
modifiers-stream
|
||||
(->> move-stream
|
||||
(rx/with-latest-from array/conj ms/mouse-position-shift)
|
||||
(rx/map
|
||||
(fn [[move-vector target-frame drop-index cell-data shift?]]
|
||||
(let [x-disp? (> (mth/abs (:x move-vector)) (mth/abs (:y move-vector)))
|
||||
[move-vector snap-ignore-axis]
|
||||
(cond
|
||||
(and shift? x-disp?)
|
||||
[(assoc move-vector :y 0) :y]
|
||||
|
||||
shift?
|
||||
[(assoc move-vector :x 0) :x]
|
||||
|
||||
:else
|
||||
[move-vector nil])]
|
||||
[(-> (dwm/create-modif-tree ids (ctm/move-modifiers move-vector))
|
||||
(dwm/build-change-frame-modifiers objects selected target-frame drop-index cell-data))
|
||||
snap-ignore-axis])))
|
||||
(rx/share))]
|
||||
|
||||
(rx/merge
|
||||
;; Temporary modifiers stream
|
||||
(->> move-stream
|
||||
(rx/with-latest-from array/conj ms/mouse-position-shift)
|
||||
(->> modifiers-stream
|
||||
(rx/map
|
||||
(fn [[move-vector target-frame drop-index cell-data shift?]]
|
||||
(let [x-disp? (> (mth/abs (:x move-vector)) (mth/abs (:y move-vector)))
|
||||
[move-vector snap-ignore-axis]
|
||||
(cond
|
||||
(and shift? x-disp?)
|
||||
[(assoc move-vector :y 0) :y]
|
||||
(fn [[modifiers snap-ignore-axis]]
|
||||
(if (features/active-feature? state "render-wasm/v1")
|
||||
(dwm/set-wasm-modifiers modifiers false false {:snap-ignore-axis snap-ignore-axis})
|
||||
(dwm/set-modifiers modifiers false false {:snap-ignore-axis snap-ignore-axis})))))
|
||||
|
||||
shift?
|
||||
[(assoc move-vector :x 0) :x]
|
||||
|
||||
:else
|
||||
[move-vector nil])]
|
||||
|
||||
(-> (dwm/create-modif-tree ids (ctm/move-modifiers move-vector))
|
||||
(dwm/build-change-frame-modifiers objects selected target-frame drop-index cell-data)
|
||||
(dwm/set-modifiers false false {:snap-ignore-axis snap-ignore-axis}))))))
|
||||
(if (features/active-feature? state "render-wasm/v1")
|
||||
(->> modifiers-stream
|
||||
(rx/last)
|
||||
(rx/map
|
||||
(fn [[modifiers snap-ignore-axis]]
|
||||
(dwm/set-modifiers modifiers false false {:snap-ignore-axis snap-ignore-axis}))))
|
||||
(rx/empty))
|
||||
|
||||
(->> move-stream
|
||||
(rx/with-latest-from ms/mouse-position-alt)
|
||||
|
|
|
@ -125,6 +125,9 @@
|
|||
(def workspace-drawing
|
||||
(l/derived :workspace-drawing st/state))
|
||||
|
||||
(def workspace-selrect-transform
|
||||
(l/derived :workspace-selrect-transform st/state))
|
||||
|
||||
;; TODO: rename to workspace-selected (?)
|
||||
;; Don't use directly from components, this is a proxy to improve performance of selected-shapes
|
||||
(def ^:private selected-shapes-data
|
||||
|
|
|
@ -318,7 +318,13 @@
|
|||
[{:keys [shape zoom color on-move-selected on-context-menu disable-handlers]}]
|
||||
(let [selrect (dm/get-prop shape :selrect)
|
||||
transform-type (mf/deref refs/current-transform)
|
||||
transform (gsh/transform-str shape)]
|
||||
sr-transform (mf/deref refs/workspace-selrect-transform)
|
||||
|
||||
transform
|
||||
(dm/str
|
||||
(cond->> (gsh/transform-matrix shape)
|
||||
(some? sr-transform)
|
||||
(gmt/multiply sr-transform)))]
|
||||
|
||||
(when (and (some? selrect)
|
||||
(not (or (= transform-type :move)
|
||||
|
@ -336,13 +342,18 @@
|
|||
{::mf/wrap-props false}
|
||||
[{:keys [shape zoom color on-resize on-rotate disable-handlers]}]
|
||||
(let [transform-type (mf/deref refs/current-transform)
|
||||
sr-transform (mf/deref refs/workspace-selrect-transform)
|
||||
|
||||
read-only? (mf/use-ctx ctx/workspace-read-only?)
|
||||
|
||||
layout (mf/deref refs/workspace-layout)
|
||||
scale-text? (contains? layout :scale-text)
|
||||
|
||||
selrect (dm/get-prop shape :selrect)
|
||||
transform (gsh/transform-matrix shape)
|
||||
|
||||
transform (cond->> (gsh/transform-matrix shape)
|
||||
(some? sr-transform)
|
||||
(gmt/multiply sr-transform))
|
||||
|
||||
rotation (-> (gpt/point 1 0)
|
||||
(gpt/transform (:transform shape))
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
[app.common.data.macros :as dm]
|
||||
[app.common.files.helpers :as cfh]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.types.shape :as cts]
|
||||
[app.common.types.shape-tree :as ctt]
|
||||
[app.common.types.shape.layout :as ctl]
|
||||
[app.main.data.workspace.modifiers :as dwm]
|
||||
|
@ -112,9 +111,7 @@
|
|||
text-modifiers (mf/deref refs/workspace-text-modifier)
|
||||
|
||||
objects-modified (mf/with-memo [base-objects text-modifiers modifiers]
|
||||
(binding [cts/*wasm-sync* true]
|
||||
(-> (into selected (keys modifiers))
|
||||
(apply-modifiers-to-selected base-objects text-modifiers modifiers))))
|
||||
(apply-modifiers-to-selected selected base-objects text-modifiers modifiers))
|
||||
|
||||
selected-shapes (keep (d/getf objects-modified) selected)
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
(:require
|
||||
["react-dom/server" :as rds]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.geom.matrix :as gmt]
|
||||
[app.common.math :as mth]
|
||||
[app.common.svg.path :as path]
|
||||
[app.common.uuid :as uuid]
|
||||
|
@ -563,12 +564,107 @@
|
|||
(rx/reduce conj [])
|
||||
(rx/subs! request-render)))))
|
||||
|
||||
(defn uuid->u8
|
||||
[id]
|
||||
(let [buffer (uuid/get-u32 id)
|
||||
u32-arr (js/Uint32Array. 4)]
|
||||
(doseq [i (range 0 4)]
|
||||
(aset u32-arr i (aget buffer i)))
|
||||
(js/Uint8Array. (.-buffer u32-arr))))
|
||||
|
||||
(defn matrix->u8
|
||||
[{:keys [a b c d e f]}]
|
||||
(let [f32-arr (js/Float32Array. 6)]
|
||||
(aset f32-arr 0 a)
|
||||
(aset f32-arr 1 b)
|
||||
(aset f32-arr 2 c)
|
||||
(aset f32-arr 3 d)
|
||||
(aset f32-arr 4 e)
|
||||
(aset f32-arr 5 f)
|
||||
(js/Uint8Array. (.-buffer f32-arr))))
|
||||
|
||||
(defn data->entry
|
||||
[data offset]
|
||||
(let [id1 (.getUint32 data (+ offset 0) true)
|
||||
id2 (.getUint32 data (+ offset 4) true)
|
||||
id3 (.getUint32 data (+ offset 8) true)
|
||||
id4 (.getUint32 data (+ offset 12) true)
|
||||
|
||||
a (.getFloat32 data (+ offset 16) true)
|
||||
b (.getFloat32 data (+ offset 20) true)
|
||||
c (.getFloat32 data (+ offset 24) true)
|
||||
d (.getFloat32 data (+ offset 28) true)
|
||||
e (.getFloat32 data (+ offset 32) true)
|
||||
f (.getFloat32 data (+ offset 36) true)
|
||||
|
||||
id (uuid/from-unsigned-parts id1 id2 id3 id4)]
|
||||
|
||||
{:id id
|
||||
:transform (gmt/matrix a b c d e f)}))
|
||||
|
||||
(defn propagate-modifiers
|
||||
[entries]
|
||||
(let [entry-size 40
|
||||
ptr (h/call internal-module "_alloc_bytes" (* entry-size (count entries)))
|
||||
|
||||
heap
|
||||
(js/Uint8Array.
|
||||
(.-buffer (gobj/get ^js internal-module "HEAPU8"))
|
||||
ptr
|
||||
(* entry-size (count entries)))]
|
||||
|
||||
(loop [entries (seq entries)
|
||||
offset 0]
|
||||
(when-not (empty? entries)
|
||||
(let [{:keys [id transform]} (first entries)]
|
||||
(.set heap (uuid->u8 id) offset)
|
||||
(.set heap (matrix->u8 transform) (+ offset 16))
|
||||
(recur (rest entries) (+ offset entry-size)))))
|
||||
|
||||
(let [result-ptr (h/call internal-module "_propagate_modifiers")
|
||||
heap (js/DataView. (.-buffer (gobj/get ^js internal-module "HEAPU8")))
|
||||
len (.getUint32 heap result-ptr true)
|
||||
result
|
||||
(->> (range 0 len)
|
||||
(mapv #(data->entry heap (+ result-ptr 4 (* % entry-size)))))]
|
||||
(h/call internal-module "_free_bytes")
|
||||
|
||||
result)))
|
||||
|
||||
(defn set-canvas-background
|
||||
[background]
|
||||
(let [rgba (rgba-from-hex background 1)]
|
||||
(h/call internal-module "_set_canvas_background" rgba)
|
||||
(request-render "set-canvas-background")))
|
||||
|
||||
(defn set-modifiers
|
||||
[modifiers]
|
||||
(if (empty? modifiers)
|
||||
(h/call internal-module "_clean_modifiers")
|
||||
|
||||
(let [ENTRY_SIZE 40
|
||||
|
||||
ptr
|
||||
(h/call internal-module "_alloc_bytes" (* ENTRY_SIZE (count modifiers)))
|
||||
|
||||
heap
|
||||
(js/Uint8Array.
|
||||
(.-buffer (gobj/get ^js internal-module "HEAPU8"))
|
||||
ptr
|
||||
(* ENTRY_SIZE (count modifiers)))]
|
||||
|
||||
(loop [entries (seq modifiers)
|
||||
offset 0]
|
||||
(when-not (empty? entries)
|
||||
(let [{:keys [id transform]} (first entries)]
|
||||
(.set heap (uuid->u8 id) offset)
|
||||
(.set heap (matrix->u8 transform) (+ offset 16))
|
||||
(recur (rest entries) (+ offset ENTRY_SIZE)))))
|
||||
|
||||
(h/call internal-module "_set_modifiers")
|
||||
|
||||
(request-render "set-modifiers"))))
|
||||
|
||||
(defn initialize
|
||||
[base-objects zoom vbox background]
|
||||
(let [rgba (rgba-from-hex background 1)]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue