mirror of
https://github.com/penpot/penpot.git
synced 2025-05-22 08:36:11 +02:00
Merge pull request #490 from penpot/fixes/more-performance-fixes
Performance fixes
This commit is contained in:
commit
1a4f3f0e18
18 changed files with 199 additions and 105 deletions
|
@ -121,8 +121,37 @@
|
||||||
(gpr/join-selrects)))
|
(gpr/join-selrects)))
|
||||||
|
|
||||||
(defn translate-to-frame
|
(defn translate-to-frame
|
||||||
[shape {:keys [x y]}]
|
[{:keys [type x y] :as shape} {:keys [x y]}]
|
||||||
(move shape (gpt/point (- x) (- y))))
|
(let [move-point
|
||||||
|
(fn [point]
|
||||||
|
(-> point
|
||||||
|
(update :x - x)
|
||||||
|
(update :y - y)))
|
||||||
|
|
||||||
|
move-segment
|
||||||
|
(fn [segment]
|
||||||
|
(-> segment
|
||||||
|
(d/update-in-when [:params :x] - x)
|
||||||
|
(d/update-in-when [:params :y] - y)
|
||||||
|
(d/update-in-when [:params :c1x] - x)
|
||||||
|
(d/update-in-when [:params :c1y] - y)
|
||||||
|
(d/update-in-when [:params :c2x] - x)
|
||||||
|
(d/update-in-when [:params :c2y] - y)))]
|
||||||
|
|
||||||
|
(-> shape
|
||||||
|
(d/update-when :x - x)
|
||||||
|
(d/update-when :y - y)
|
||||||
|
(update-in [:selrect :x] - x)
|
||||||
|
(update-in [:selrect :y] - y)
|
||||||
|
(update-in [:selrect :x1] - x)
|
||||||
|
(update-in [:selrect :y1] - y)
|
||||||
|
(update-in [:selrect :x2] - x)
|
||||||
|
(update-in [:selrect :y2] - y)
|
||||||
|
|
||||||
|
(d/update-when :points #(map move-point %))
|
||||||
|
|
||||||
|
(cond-> (= :path type)
|
||||||
|
(d/update-when :content #(map move-segment %))))))
|
||||||
|
|
||||||
|
|
||||||
;; --- Helpers
|
;; --- Helpers
|
||||||
|
|
|
@ -131,10 +131,17 @@ gulp.task("scss", function() {
|
||||||
.pipe(gulp.dest(paths.output + "css/"));
|
.pipe(gulp.dest(paths.output + "css/"));
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task("svg:sprite", function() {
|
gulp.task("svg:sprite:icons", function() {
|
||||||
return gulp.src(paths.resources + "images/icons/*.svg")
|
return gulp.src(paths.resources + "images/icons/*.svg")
|
||||||
.pipe(gulpRename({prefix: "icon-"}))
|
.pipe(gulpRename({prefix: "icon-"}))
|
||||||
.pipe(svgSprite({mode:{symbol: {inline: true}}}))
|
.pipe(svgSprite({mode:{symbol: {inline: true, sprite: "icons.svg"}}}))
|
||||||
|
.pipe(gulp.dest(paths.output + "images/sprites/"));
|
||||||
|
});
|
||||||
|
|
||||||
|
gulp.task("svg:sprite:cursors", function() {
|
||||||
|
return gulp.src(paths.resources + "images/cursors/*.svg")
|
||||||
|
.pipe(gulpRename({prefix: "cursor-"}))
|
||||||
|
.pipe(svgSprite({mode:{symbol: {inline: true, sprite: "cursors.svg"}}}))
|
||||||
.pipe(gulp.dest(paths.output + "images/sprites/"));
|
.pipe(gulp.dest(paths.output + "images/sprites/"));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -143,7 +150,7 @@ gulp.task("template:main", templatePipeline({
|
||||||
output: paths.output
|
output: paths.output
|
||||||
}));
|
}));
|
||||||
|
|
||||||
gulp.task("templates", gulp.series("svg:sprite", "template:main"));
|
gulp.task("templates", gulp.series("svg:sprite:icons", "svg:sprite:cursors", "template:main"));
|
||||||
|
|
||||||
gulp.task("polyfills", function() {
|
gulp.task("polyfills", function() {
|
||||||
return gulp.src(paths.resources + "polyfills/*.js")
|
return gulp.src(paths.resources + "polyfills/*.js")
|
||||||
|
|
|
@ -130,14 +130,11 @@
|
||||||
grid-template-columns: 20px 1fr;
|
grid-template-columns: 20px 1fr;
|
||||||
|
|
||||||
.viewport {
|
.viewport {
|
||||||
|
cursor: var(--cursor);
|
||||||
grid-column: 1 / span 2;
|
grid-column: 1 / span 2;
|
||||||
grid-row: 1 / span 2;
|
grid-row: 1 / span 2;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
&.drawing {
|
|
||||||
cursor: cell;
|
|
||||||
}
|
|
||||||
|
|
||||||
rect.selection-rect {
|
rect.selection-rect {
|
||||||
fill: rgba(235, 215, 92, 0.1);
|
fill: rgba(235, 215, 92, 0.1);
|
||||||
stroke: #000000;
|
stroke: #000000;
|
||||||
|
|
|
@ -23,7 +23,8 @@
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
{{>../public/images/sprites/symbol/svg/sprite.symbol.svg}}
|
{{>../public/images/sprites/symbol/icons.svg}}
|
||||||
|
{{>../public/images/sprites/symbol/cursors.svg}}
|
||||||
<section id="app" tabindex="1"></section>
|
<section id="app" tabindex="1"></section>
|
||||||
<section id="modal"></section>
|
<section id="modal"></section>
|
||||||
{{# manifest}}
|
{{# manifest}}
|
||||||
|
|
|
@ -108,7 +108,7 @@
|
||||||
(let [page-id (:current-page-id state)]
|
(let [page-id (:current-page-id state)]
|
||||||
(rx/concat
|
(rx/concat
|
||||||
(when (some :page-id changes)
|
(when (some :page-id changes)
|
||||||
(rx/of (update-indices page-id)))
|
(rx/of (update-indices page-id changes)))
|
||||||
|
|
||||||
(when (and save-undo? (seq undo-changes))
|
(when (and save-undo? (seq undo-changes))
|
||||||
(let [entry {:undo-changes undo-changes
|
(let [entry {:undo-changes undo-changes
|
||||||
|
@ -174,14 +174,13 @@
|
||||||
(rx/map (constantly ::index-initialized)))))))
|
(rx/map (constantly ::index-initialized)))))))
|
||||||
|
|
||||||
(defn update-indices
|
(defn update-indices
|
||||||
[page-id]
|
[page-id changes]
|
||||||
(ptk/reify ::update-indices
|
(ptk/reify ::update-indices
|
||||||
ptk/EffectEvent
|
ptk/EffectEvent
|
||||||
(effect [_ state stream]
|
(effect [_ state stream]
|
||||||
(let [objects (lookup-page-objects state page-id)]
|
(uw/ask! {:cmd :update-page-indices
|
||||||
(uw/ask! {:cmd :update-page-indices
|
:page-id page-id
|
||||||
:page-id page-id
|
:changes changes}))))
|
||||||
:objects objects})))))
|
|
||||||
|
|
||||||
;; --- Common Helpers & Events
|
;; --- Common Helpers & Events
|
||||||
|
|
||||||
|
|
|
@ -57,10 +57,10 @@
|
||||||
stoper (rx/filter stoper? stream)
|
stoper (rx/filter stoper? stream)
|
||||||
initial @ms/mouse-position
|
initial @ms/mouse-position
|
||||||
|
|
||||||
|
|
||||||
page-id (:current-page-id state)
|
page-id (:current-page-id state)
|
||||||
objects (dwc/lookup-page-objects state page-id)
|
objects (dwc/lookup-page-objects state page-id)
|
||||||
layout (get state :workspace-layout)
|
layout (get state :workspace-layout)
|
||||||
|
zoom (get-in state [:workspace-local :zoom] 1)
|
||||||
|
|
||||||
frames (cp/select-frames objects)
|
frames (cp/select-frames objects)
|
||||||
fid (or (->> frames
|
fid (or (->> frames
|
||||||
|
@ -80,7 +80,7 @@
|
||||||
(rx/of #(assoc-in state [:workspace-drawing :object] shape))
|
(rx/of #(assoc-in state [:workspace-drawing :object] shape))
|
||||||
|
|
||||||
;; Initial SNAP
|
;; Initial SNAP
|
||||||
(->> (snap/closest-snap-point page-id [shape] layout initial)
|
(->> (snap/closest-snap-point page-id [shape] layout zoom initial)
|
||||||
(rx/map move-drawing))
|
(rx/map move-drawing))
|
||||||
|
|
||||||
(->> ms/mouse-position
|
(->> ms/mouse-position
|
||||||
|
@ -88,7 +88,7 @@
|
||||||
(rx/with-latest vector ms/mouse-position-ctrl)
|
(rx/with-latest vector ms/mouse-position-ctrl)
|
||||||
(rx/switch-map
|
(rx/switch-map
|
||||||
(fn [[point :as current]]
|
(fn [[point :as current]]
|
||||||
(->> (snap/closest-snap-point page-id [shape] layout point)
|
(->> (snap/closest-snap-point page-id [shape] layout zoom point)
|
||||||
(rx/map #(conj current %)))))
|
(rx/map #(conj current %)))))
|
||||||
(rx/map
|
(rx/map
|
||||||
(fn [[_ ctrl? point]]
|
(fn [[_ ctrl? point]]
|
||||||
|
|
|
@ -206,7 +206,7 @@
|
||||||
(rx/merge
|
(rx/merge
|
||||||
(rx/of (dwp/shapes-changes-persisted file-id msg))
|
(rx/of (dwp/shapes-changes-persisted file-id msg))
|
||||||
(when (seq page-ids)
|
(when (seq page-ids)
|
||||||
(rx/from (map dwc/update-indices page-ids))))))))
|
(rx/from (map dwc/update-indices page-ids changes))))))))
|
||||||
|
|
||||||
(s/def ::library-change-event
|
(s/def ::library-change-event
|
||||||
(s/keys :req-un [::type
|
(s/keys :req-un [::type
|
||||||
|
|
|
@ -140,6 +140,7 @@
|
||||||
stoper (rx/filter ms/mouse-up? stream)
|
stoper (rx/filter ms/mouse-up? stream)
|
||||||
layout (:workspace-layout state)
|
layout (:workspace-layout state)
|
||||||
page-id (:current-page-id state)
|
page-id (:current-page-id state)
|
||||||
|
zoom (get-in state [:workspace-local :zoom] 1)
|
||||||
objects (dwc/lookup-page-objects state page-id)
|
objects (dwc/lookup-page-objects state page-id)
|
||||||
resizing-shapes (map #(get objects %) ids)
|
resizing-shapes (map #(get objects %) ids)
|
||||||
text-shapes-ids (->> resizing-shapes
|
text-shapes-ids (->> resizing-shapes
|
||||||
|
@ -151,7 +152,7 @@
|
||||||
(rx/with-latest vector ms/mouse-position-shift)
|
(rx/with-latest vector ms/mouse-position-shift)
|
||||||
(rx/map normalize-proportion-lock)
|
(rx/map normalize-proportion-lock)
|
||||||
(rx/switch-map (fn [[point :as current]]
|
(rx/switch-map (fn [[point :as current]]
|
||||||
(->> (snap/closest-snap-point page-id resizing-shapes layout point)
|
(->> (snap/closest-snap-point page-id resizing-shapes layout zoom point)
|
||||||
(rx/map #(conj current %)))))
|
(rx/map #(conj current %)))))
|
||||||
(rx/mapcat (partial resize shape initial-position resizing-shapes))
|
(rx/mapcat (partial resize shape initial-position resizing-shapes))
|
||||||
(rx/take-until stoper))
|
(rx/take-until stoper))
|
||||||
|
@ -284,6 +285,7 @@
|
||||||
shapes (mapv #(get objects %) ids)
|
shapes (mapv #(get objects %) ids)
|
||||||
stopper (rx/filter ms/mouse-up? stream)
|
stopper (rx/filter ms/mouse-up? stream)
|
||||||
layout (get state :workspace-layout)
|
layout (get state :workspace-layout)
|
||||||
|
zoom (get-in state [:workspace-local :zoom] 1)
|
||||||
|
|
||||||
|
|
||||||
position (->> ms/mouse-position
|
position (->> ms/mouse-position
|
||||||
|
@ -291,7 +293,7 @@
|
||||||
(rx/map #(gpt/to-vec from-position %)))
|
(rx/map #(gpt/to-vec from-position %)))
|
||||||
|
|
||||||
snap-delta (->> position
|
snap-delta (->> position
|
||||||
(rx/switch-map #(snap/closest-snap-move page-id shapes objects layout %)))]
|
(rx/switch-map #(snap/closest-snap-move page-id shapes objects layout zoom %)))]
|
||||||
(rx/concat
|
(rx/concat
|
||||||
(->> snap-delta
|
(->> snap-delta
|
||||||
(rx/with-latest vector position)
|
(rx/with-latest vector position)
|
||||||
|
|
|
@ -50,8 +50,8 @@
|
||||||
(-> rect
|
(-> rect
|
||||||
(update :x to-finite 0)
|
(update :x to-finite 0)
|
||||||
(update :y to-finite 0)
|
(update :y to-finite 0)
|
||||||
(update :width to-finite 10000)
|
(update :width to-finite 100000)
|
||||||
(update :height to-finite 10000))))
|
(update :height to-finite 100000))))
|
||||||
|
|
||||||
(declare shape-wrapper-factory)
|
(declare shape-wrapper-factory)
|
||||||
|
|
||||||
|
|
|
@ -69,8 +69,9 @@
|
||||||
(rx/map flatten-to-points))))
|
(rx/map flatten-to-points))))
|
||||||
|
|
||||||
(defn- search-snap
|
(defn- search-snap
|
||||||
[page-id frame-id points coord filter-shapes]
|
[page-id frame-id points coord filter-shapes zoom]
|
||||||
(let [ranges (->> points
|
(let [snap-accuracy (/ snap-accuracy zoom)
|
||||||
|
ranges (->> points
|
||||||
(map coord)
|
(map coord)
|
||||||
(mapv #(vector (- % snap-accuracy)
|
(mapv #(vector (- % snap-accuracy)
|
||||||
(+ % snap-accuracy))))]
|
(+ % snap-accuracy))))]
|
||||||
|
@ -90,9 +91,9 @@
|
||||||
(gpt/to-vec from to))))
|
(gpt/to-vec from to))))
|
||||||
|
|
||||||
(defn- closest-snap
|
(defn- closest-snap
|
||||||
[page-id frame-id points filter-shapes]
|
[page-id frame-id points filter-shapes zoom]
|
||||||
(let [snap-x (search-snap page-id frame-id points :x filter-shapes)
|
(let [snap-x (search-snap page-id frame-id points :x filter-shapes zoom)
|
||||||
snap-y (search-snap page-id frame-id points :y filter-shapes)]
|
snap-y (search-snap page-id frame-id points :y filter-shapes zoom)]
|
||||||
;; snap-x is the second parameter because is the "source" to combine
|
;; snap-x is the second parameter because is the "source" to combine
|
||||||
(rx/combine-latest snap->vector snap-y snap-x)))
|
(rx/combine-latest snap->vector snap-y snap-x)))
|
||||||
|
|
||||||
|
@ -114,8 +115,9 @@
|
||||||
(and (>= s1c1 s2c1) (<= s1c1 s2c2))
|
(and (>= s1c1 s2c1) (<= s1c1 s2c2))
|
||||||
(and (>= s1c2 s2c1) (<= s1c2 s2c2)))))
|
(and (>= s1c2 s2c1) (<= s1c2 s2c2)))))
|
||||||
|
|
||||||
(defn calculate-snap [coord selrect shapes-lt shapes-gt]
|
(defn calculate-snap [coord selrect shapes-lt shapes-gt zoom]
|
||||||
(let [dist-lt (fn [other] (sr-distance coord (:selrect other) selrect))
|
(let [snap-distance-accuracy (/ snap-distance-accuracy zoom)
|
||||||
|
dist-lt (fn [other] (sr-distance coord (:selrect other) selrect))
|
||||||
dist-gt (fn [other] (sr-distance coord selrect (:selrect other)))
|
dist-gt (fn [other] (sr-distance coord selrect (:selrect other)))
|
||||||
|
|
||||||
;; Calculates the snap distance when in the middle of two shapes
|
;; Calculates the snap distance when in the middle of two shapes
|
||||||
|
@ -142,7 +144,7 @@
|
||||||
(fn [acc val]
|
(fn [acc val]
|
||||||
;; Using a number is faster than accesing the variable.
|
;; Using a number is faster than accesing the variable.
|
||||||
;; Keep up to date with `snap-distance-accuracy`
|
;; Keep up to date with `snap-distance-accuracy`
|
||||||
(if (and (<= val 10) (>= val (- 10)))
|
(if (and (<= val snap-distance-accuracy) (>= val (- snap-distance-accuracy)))
|
||||||
(min acc val)
|
(min acc val)
|
||||||
acc))
|
acc))
|
||||||
|
|
||||||
|
@ -171,11 +173,11 @@
|
||||||
|
|
||||||
(if (mth/finite? min-snap) [0 min-snap] nil)))
|
(if (mth/finite? min-snap) [0 min-snap] nil)))
|
||||||
|
|
||||||
(defn search-snap-distance [selrect coord shapes-lt shapes-gt]
|
(defn search-snap-distance [selrect coord shapes-lt shapes-gt zoom]
|
||||||
(->> shapes-lt
|
(->> shapes-lt
|
||||||
(rx/combine-latest vector shapes-gt)
|
(rx/combine-latest vector shapes-gt)
|
||||||
(rx/map (fn [[shapes-lt shapes-gt]]
|
(rx/map (fn [[shapes-lt shapes-gt]]
|
||||||
(calculate-snap coord selrect shapes-lt shapes-gt)))))
|
(calculate-snap coord selrect shapes-lt shapes-gt zoom)))))
|
||||||
|
|
||||||
(defn select-shapes-area
|
(defn select-shapes-area
|
||||||
[page-id shapes objects area-selrect]
|
[page-id shapes objects area-selrect]
|
||||||
|
@ -187,7 +189,7 @@
|
||||||
(rx/map (fn [ids] (map #(get objects %) ids)))))
|
(rx/map (fn [ids] (map #(get objects %) ids)))))
|
||||||
|
|
||||||
(defn closest-distance-snap
|
(defn closest-distance-snap
|
||||||
[page-id shapes objects movev]
|
[page-id shapes objects zoom movev]
|
||||||
(let [frame-id (snap-frame-id shapes)
|
(let [frame-id (snap-frame-id shapes)
|
||||||
frame (get objects frame-id)
|
frame (get objects frame-id)
|
||||||
selrect (->> shapes (map #(gsh/move % movev)) gsh/selection-rect)]
|
selrect (->> shapes (map #(gsh/move % movev)) gsh/selection-rect)]
|
||||||
|
@ -197,12 +199,12 @@
|
||||||
(let [areas (->> (gsh/selrect->areas (or (:selrect frame)
|
(let [areas (->> (gsh/selrect->areas (or (:selrect frame)
|
||||||
(gsh/rect->selrect @refs/vbox)) selrect)
|
(gsh/rect->selrect @refs/vbox)) selrect)
|
||||||
(d/mapm #(select-shapes-area page-id shapes objects %2)))
|
(d/mapm #(select-shapes-area page-id shapes objects %2)))
|
||||||
snap-x (search-snap-distance selrect :x (:left areas) (:right areas))
|
snap-x (search-snap-distance selrect :x (:left areas) (:right areas) zoom)
|
||||||
snap-y (search-snap-distance selrect :y (:top areas) (:bottom areas))]
|
snap-y (search-snap-distance selrect :y (:top areas) (:bottom areas) zoom)]
|
||||||
(rx/combine-latest snap->vector snap-y snap-x)))))))
|
(rx/combine-latest snap->vector snap-y snap-x)))))))
|
||||||
|
|
||||||
(defn closest-snap-point
|
(defn closest-snap-point
|
||||||
[page-id shapes layout point]
|
[page-id shapes layout zoom point]
|
||||||
(let [frame-id (snap-frame-id shapes)
|
(let [frame-id (snap-frame-id shapes)
|
||||||
filter-shapes (into #{} (map :id shapes))
|
filter-shapes (into #{} (map :id shapes))
|
||||||
filter-shapes (fn [id] (if (= id :layout)
|
filter-shapes (fn [id] (if (= id :layout)
|
||||||
|
@ -210,12 +212,12 @@
|
||||||
(not (contains? layout :snap-grid)))
|
(not (contains? layout :snap-grid)))
|
||||||
(or (filter-shapes id)
|
(or (filter-shapes id)
|
||||||
(not (contains? layout :dynamic-alignment)))))]
|
(not (contains? layout :dynamic-alignment)))))]
|
||||||
(->> (closest-snap page-id frame-id [point] filter-shapes)
|
(->> (closest-snap page-id frame-id [point] filter-shapes zoom)
|
||||||
(rx/map #(or % (gpt/point 0 0)))
|
(rx/map #(or % (gpt/point 0 0)))
|
||||||
(rx/map #(gpt/add point %)))))
|
(rx/map #(gpt/add point %)))))
|
||||||
|
|
||||||
(defn closest-snap-move
|
(defn closest-snap-move
|
||||||
[page-id shapes objects layout movev]
|
[page-id shapes objects layout zoom movev]
|
||||||
(let [frame-id (snap-frame-id shapes)
|
(let [frame-id (snap-frame-id shapes)
|
||||||
filter-shapes (into #{} (map :id shapes))
|
filter-shapes (into #{} (map :id shapes))
|
||||||
filter-shapes (fn [id] (if (= id :layout)
|
filter-shapes (fn [id] (if (= id :layout)
|
||||||
|
@ -232,9 +234,9 @@
|
||||||
;; Move the points in the translation vector
|
;; Move the points in the translation vector
|
||||||
(map #(gpt/add % movev)))]
|
(map #(gpt/add % movev)))]
|
||||||
|
|
||||||
(->> (rx/merge (closest-snap page-id frame-id shapes-points filter-shapes)
|
(->> (rx/merge (closest-snap page-id frame-id shapes-points filter-shapes zoom)
|
||||||
(when (contains? layout :dynamic-alignment)
|
(when (contains? layout :dynamic-alignment)
|
||||||
(closest-distance-snap page-id shapes objects movev)))
|
(closest-distance-snap page-id shapes objects zoom movev)))
|
||||||
(rx/reduce gpt/min)
|
(rx/reduce gpt/min)
|
||||||
(rx/map #(or % (gpt/point 0 0))))))
|
(rx/map #(or % (gpt/point 0 0))))))
|
||||||
|
|
||||||
|
|
|
@ -121,8 +121,8 @@
|
||||||
:id (:id shape)
|
:id (:id shape)
|
||||||
:data-colors (retrieve-colors shape)
|
:data-colors (retrieve-colors shape)
|
||||||
:transform (geom/transform-matrix shape)
|
:transform (geom/transform-matrix shape)
|
||||||
:width (if (#{:auto-width} grow-type) 10000 width)
|
:width (if (#{:auto-width} grow-type) 100000 width)
|
||||||
:height (if (#{:auto-height :auto-width} grow-type) 10000 height)
|
:height (if (#{:auto-height :auto-width} grow-type) 100000 height)
|
||||||
:ref ref}
|
:ref ref}
|
||||||
[:& text-content {:shape shape
|
[:& text-content {:shape shape
|
||||||
:content (:content shape)
|
:content (:content shape)
|
||||||
|
|
|
@ -89,7 +89,9 @@
|
||||||
(:selected local)))]
|
(:selected local)))]
|
||||||
(l/derived moving-shapes refs/workspace-local)))
|
(l/derived moving-shapes refs/workspace-local)))
|
||||||
|
|
||||||
(mf/defc frame-grid [{:keys [zoom]}]
|
(mf/defc frame-grid
|
||||||
|
{::mf/wrap [mf/memo]}
|
||||||
|
[{:keys [zoom]}]
|
||||||
(let [frames (mf/deref refs/workspace-frames)
|
(let [frames (mf/deref refs/workspace-frames)
|
||||||
shapes-moving (mf/deref shapes-moving-ref)]
|
shapes-moving (mf/deref shapes-moving-ref)]
|
||||||
[:g.grid-display {:style {:pointer-events "none"}}
|
[:g.grid-display {:style {:pointer-events "none"}}
|
||||||
|
|
|
@ -11,7 +11,8 @@
|
||||||
(:require
|
(:require
|
||||||
[rumext.alpha :as mf]
|
[rumext.alpha :as mf]
|
||||||
[app.common.math :as mth]
|
[app.common.math :as mth]
|
||||||
[app.util.object :as obj]))
|
[app.util.object :as obj]
|
||||||
|
[app.util.timers :as timers]))
|
||||||
|
|
||||||
(defn- calculate-step-size
|
(defn- calculate-step-size
|
||||||
[zoom]
|
[zoom]
|
||||||
|
@ -34,49 +35,52 @@
|
||||||
(defn draw-rule!
|
(defn draw-rule!
|
||||||
[dctx {:keys [zoom size start count type] :or {count 200}}]
|
[dctx {:keys [zoom size start count type] :or {count 200}}]
|
||||||
(when start
|
(when start
|
||||||
(let [txfm (- (* (- 0 start) zoom) 20)
|
(let [txfm (- (* (- 0 start) zoom) 20)
|
||||||
minv (max (mth/round start) -10000)
|
step (calculate-step-size zoom)
|
||||||
maxv (min (mth/round (+ start (/ size zoom))) 10000)
|
|
||||||
step (calculate-step-size zoom)]
|
|
||||||
|
|
||||||
(if (= type :horizontal)
|
minv (max (mth/round start) -100000)
|
||||||
(.translate dctx txfm 0)
|
minv (* (mth/ceil (/ minv step)) step)
|
||||||
(.translate dctx 0 txfm))
|
|
||||||
|
|
||||||
(obj/set! dctx "font" "12px worksans")
|
maxv (min (mth/round (+ start (/ size zoom))) 100000)
|
||||||
(obj/set! dctx "fillStyle" "#7B7D85")
|
maxv (* (mth/floor (/ maxv step)) step)
|
||||||
(obj/set! dctx "strokeStyle" "#7B7D85")
|
|
||||||
(obj/set! dctx "textAlign" "center")
|
|
||||||
|
|
||||||
(loop [i minv]
|
path (js/Path2D.)]
|
||||||
(when (< i maxv)
|
|
||||||
(let [pos (+ (* i zoom) 0)]
|
|
||||||
(when (= (mod i step) 0)
|
|
||||||
(.save dctx)
|
|
||||||
(if (= type :horizontal)
|
|
||||||
(do
|
|
||||||
(.fillText dctx (str i) pos 13))
|
|
||||||
(do
|
|
||||||
(.translate dctx 12 pos)
|
|
||||||
(.rotate dctx (/ (* 270 js/Math.PI) 180))
|
|
||||||
(.fillText dctx (str i) 0 0)))
|
|
||||||
(.restore dctx))
|
|
||||||
(recur (inc i)))))
|
|
||||||
|
|
||||||
(let [path (js/Path2D.)]
|
(if (= type :horizontal)
|
||||||
(loop [i minv]
|
(.translate dctx txfm 0)
|
||||||
(if (> i maxv)
|
(.translate dctx 0 txfm))
|
||||||
(.stroke dctx path)
|
|
||||||
(let [pos (+ (* i zoom) 0)]
|
(obj/set! dctx "font" "12px worksans")
|
||||||
(when (= (mod i step) 0)
|
(obj/set! dctx "fillStyle" "#7B7D85")
|
||||||
(if (= type :horizontal)
|
(obj/set! dctx "strokeStyle" "#7B7D85")
|
||||||
(do
|
(obj/set! dctx "textAlign" "center")
|
||||||
(.moveTo path pos 17)
|
|
||||||
(.lineTo path pos 20))
|
(loop [i minv]
|
||||||
(do
|
(if (<= i maxv)
|
||||||
(.moveTo path 17 pos)
|
(let [pos (+ (* i zoom) 0)]
|
||||||
(.lineTo path 20 pos))))
|
(.save dctx)
|
||||||
(recur (inc i)))))))))
|
(if (= type :horizontal)
|
||||||
|
(do
|
||||||
|
;; Write the rule numbers
|
||||||
|
(.fillText dctx (str i) pos 13)
|
||||||
|
|
||||||
|
;; Build the rules lines
|
||||||
|
(.moveTo path pos 17)
|
||||||
|
(.lineTo path pos 20))
|
||||||
|
(do
|
||||||
|
;; Write the rule numbers
|
||||||
|
(.translate dctx 12 pos)
|
||||||
|
(.rotate dctx (/ (* 270 js/Math.PI) 180))
|
||||||
|
(.fillText dctx (str i) 0 0)
|
||||||
|
|
||||||
|
;; Build the rules lines
|
||||||
|
(.moveTo path 17 pos)
|
||||||
|
(.lineTo path 20 pos)))
|
||||||
|
(.restore dctx)
|
||||||
|
(recur (+ i step)))
|
||||||
|
|
||||||
|
;; Put the path in the canvas
|
||||||
|
(.stroke dctx path))))))
|
||||||
|
|
||||||
|
|
||||||
(mf/defc horizontal-rule
|
(mf/defc horizontal-rule
|
||||||
|
|
|
@ -60,6 +60,7 @@
|
||||||
edition (mf/deref refs/selected-edition)
|
edition (mf/deref refs/selected-edition)
|
||||||
label-pos (gpt/point x (- y (/ 10 zoom)))
|
label-pos (gpt/point x (- y (/ 10 zoom)))
|
||||||
handle-click (use-select-shape frame edition)
|
handle-click (use-select-shape frame edition)
|
||||||
|
handle-mouse-down (we/use-mouse-down frame)
|
||||||
handle-pointer-enter (we/use-pointer-enter frame)
|
handle-pointer-enter (we/use-pointer-enter frame)
|
||||||
handle-pointer-leave (we/use-pointer-leave frame)]
|
handle-pointer-leave (we/use-pointer-leave frame)]
|
||||||
[:text {:x 0
|
[:text {:x 0
|
||||||
|
@ -68,7 +69,8 @@
|
||||||
:height 20
|
:height 20
|
||||||
:class "workspace-frame-label"
|
:class "workspace-frame-label"
|
||||||
:transform (text-transform label-pos zoom)
|
:transform (text-transform label-pos zoom)
|
||||||
:on-mouse-down handle-click
|
:on-click handle-click
|
||||||
|
:on-mouse-down handle-mouse-down
|
||||||
:on-pointer-over handle-pointer-enter
|
:on-pointer-over handle-pointer-enter
|
||||||
:on-pointer-out handle-pointer-leave}
|
:on-pointer-out handle-pointer-leave}
|
||||||
(:name frame)]))
|
(:name frame)]))
|
||||||
|
|
|
@ -269,7 +269,7 @@
|
||||||
{:keys [x y width height grow-type]} shape]
|
{:keys [x y width height grow-type]} shape]
|
||||||
[:foreignObject {:transform (gsh/transform-matrix shape)
|
[:foreignObject {:transform (gsh/transform-matrix shape)
|
||||||
:x x :y y
|
:x x :y y
|
||||||
:width (if (#{:auto-width} grow-type) 10000 width)
|
:width (if (#{:auto-width} grow-type) 100000 width)
|
||||||
:height (if (#{:auto-height :auto-width} grow-type) 10000 height)}
|
:height (if (#{:auto-height :auto-width} grow-type) 100000 height)}
|
||||||
|
|
||||||
[:& text-shape-edit-html {:shape shape}]]))
|
[:& text-shape-edit-html {:shape shape}]]))
|
||||||
|
|
|
@ -242,12 +242,6 @@
|
||||||
page-id (mf/use-ctx ctx/current-page-id)
|
page-id (mf/use-ctx ctx/current-page-id)
|
||||||
|
|
||||||
selected-objects (mf/deref refs/selected-objects)
|
selected-objects (mf/deref refs/selected-objects)
|
||||||
selrect-orig (->> selected-objects
|
|
||||||
(gsh/selection-rect))
|
|
||||||
selrect (->> selected-objects
|
|
||||||
(map #(assoc % :modifiers (:modifiers local)))
|
|
||||||
(map gsh/transform-shape)
|
|
||||||
(gsh/selection-rect))
|
|
||||||
|
|
||||||
alt? (mf/use-state false)
|
alt? (mf/use-state false)
|
||||||
cursor (mf/use-state cur/pointer-inner)
|
cursor (mf/use-state cur/pointer-inner)
|
||||||
|
@ -617,9 +611,12 @@
|
||||||
@alt? cur/duplicate
|
@alt? cur/duplicate
|
||||||
:else cur/pointer-inner)]
|
:else cur/pointer-inner)]
|
||||||
|
|
||||||
|
;; Chrome BUG: https://bugs.chromium.org/p/chromium/issues/detail?id=664066
|
||||||
|
;; Right now this is a performance concern but cannot find a better alternative
|
||||||
(when (not= @cursor new-cursor)
|
(when (not= @cursor new-cursor)
|
||||||
(timers/raf
|
(timers/raf
|
||||||
#(reset! cursor new-cursor))))))
|
#(dom/set-css-property (dom/get-root) "--cursor" new-cursor))
|
||||||
|
(reset! cursor new-cursor)))))
|
||||||
|
|
||||||
(mf/use-layout-effect (mf/deps layout) on-resize)
|
(mf/use-layout-effect (mf/deps layout) on-resize)
|
||||||
(hooks/use-stream ms/keyboard-alt #(reset! alt? %))
|
(hooks/use-stream ms/keyboard-alt #(reset! alt? %))
|
||||||
|
@ -650,8 +647,7 @@
|
||||||
:view-box (format-viewbox vbox)
|
:view-box (format-viewbox vbox)
|
||||||
:ref viewport-ref
|
:ref viewport-ref
|
||||||
:class (when drawing-tool "drawing")
|
:class (when drawing-tool "drawing")
|
||||||
:style {:cursor @cursor
|
:style {:background-color (get options :background "#E8E9EA")}
|
||||||
:background-color (get options :background "#E8E9EA")}
|
|
||||||
:on-context-menu on-context-menu
|
:on-context-menu on-context-menu
|
||||||
:on-click on-click
|
:on-click on-click
|
||||||
:on-double-click on-double-click
|
:on-double-click on-double-click
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
(ns app.util.debug
|
(ns app.util.debug
|
||||||
"Debugging utils"
|
"Debugging utils"
|
||||||
(:require [cljs.pprint :refer [pprint]]))
|
(:require
|
||||||
|
[app.util.timers :as timers]
|
||||||
|
[app.util.object :as obj]
|
||||||
|
[app.common.math :as mth]
|
||||||
|
[cljs.pprint :refer [pprint]]))
|
||||||
|
|
||||||
(def debug-options #{:bounding-boxes :group :events :rotation-handler :resize-handler :selection-center #_:simple-selection})
|
(def debug-options #{:bounding-boxes :group :events :rotation-handler :resize-handler :selection-center #_:simple-selection})
|
||||||
|
|
||||||
|
@ -51,3 +55,41 @@
|
||||||
(set! (.-dbg ^js js/window) clj->js)
|
(set! (.-dbg ^js js/window) clj->js)
|
||||||
(set! (.-pp ^js js/window) pprint))
|
(set! (.-pp ^js js/window) pprint))
|
||||||
|
|
||||||
|
|
||||||
|
(defonce widget-style "
|
||||||
|
background: black;
|
||||||
|
bottom: 10px;
|
||||||
|
color: white;
|
||||||
|
height: 20px;
|
||||||
|
padding-left: 8px;
|
||||||
|
position: absolute;
|
||||||
|
right: 10px;
|
||||||
|
width: 40px;
|
||||||
|
z-index: 99999;
|
||||||
|
opacity: 0.5;
|
||||||
|
")
|
||||||
|
|
||||||
|
(defn ^:export fps
|
||||||
|
"Adds a widget to keep track of the average FPS's"
|
||||||
|
[]
|
||||||
|
(let [last (volatile! (.now js/performance))
|
||||||
|
avg (volatile! 0)
|
||||||
|
node (-> (.createElement js/document "div")
|
||||||
|
(obj/set! "id" "fps")
|
||||||
|
(obj/set! "style" widget-style))
|
||||||
|
body (obj/get js/document "body")
|
||||||
|
|
||||||
|
do-thing (fn do-thing []
|
||||||
|
(timers/raf
|
||||||
|
(fn []
|
||||||
|
(let [cur (.now js/performance)
|
||||||
|
ts (/ 1000 (* (- cur @last)))
|
||||||
|
val (+ @avg (* (- ts @avg) 0.1))]
|
||||||
|
|
||||||
|
(obj/set! node "innerText" (mth/precision val 0))
|
||||||
|
(vreset! last cur)
|
||||||
|
(vreset! avg val)
|
||||||
|
(do-thing)))))]
|
||||||
|
|
||||||
|
(.appendChild body node)
|
||||||
|
(do-thing)))
|
||||||
|
|
|
@ -7,10 +7,13 @@
|
||||||
(ns app.worker.impl
|
(ns app.worker.impl
|
||||||
(:require
|
(:require
|
||||||
[okulary.core :as l]
|
[okulary.core :as l]
|
||||||
[app.util.transit :as t]))
|
[app.util.transit :as t]
|
||||||
|
[app.common.pages.changes :as ch]))
|
||||||
|
|
||||||
(enable-console-print!)
|
(enable-console-print!)
|
||||||
|
|
||||||
|
(defonce state (l/atom {:pages-index {}}))
|
||||||
|
|
||||||
;; --- Handler
|
;; --- Handler
|
||||||
|
|
||||||
(defmulti handler :cmd)
|
(defmulti handler :cmd)
|
||||||
|
@ -24,15 +27,23 @@
|
||||||
message)
|
message)
|
||||||
|
|
||||||
(defmethod handler :initialize-indices
|
(defmethod handler :initialize-indices
|
||||||
[message]
|
[{:keys [data] :as message}]
|
||||||
|
|
||||||
|
(reset! state data)
|
||||||
|
|
||||||
(handler (-> message
|
(handler (-> message
|
||||||
(assoc :cmd :selection/initialize-index)))
|
(assoc :cmd :selection/initialize-index)))
|
||||||
(handler (-> message
|
(handler (-> message
|
||||||
(assoc :cmd :snaps/initialize-index))))
|
(assoc :cmd :snaps/initialize-index))))
|
||||||
|
|
||||||
(defmethod handler :update-page-indices
|
(defmethod handler :update-page-indices
|
||||||
[message]
|
[{:keys [page-id changes] :as message}]
|
||||||
(handler (-> message
|
|
||||||
(assoc :cmd :selection/update-index)))
|
(swap! state ch/process-changes changes false)
|
||||||
(handler (-> message
|
|
||||||
(assoc :cmd :snaps/update-index))))
|
(let [objects (get-in @state [:pages-index page-id :objects])
|
||||||
|
message (assoc message :objects objects)]
|
||||||
|
(handler (-> message
|
||||||
|
(assoc :cmd :selection/update-index)))
|
||||||
|
(handler (-> message
|
||||||
|
(assoc :cmd :snaps/update-index)))))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue