Simplify stage passepartout control
This commit is contained in:
parent
981bef98f9
commit
ee603a351b
4 changed files with 25 additions and 37 deletions
|
|
@ -164,7 +164,7 @@
|
|||
:on-click #(rf/dispatch [::set k (stepped k z false)])} "+"]]))
|
||||
|
||||
|
||||
(rf/reg-sub ::mat (fn [db _] (merge {:margin 100 :opacity 0.55} (get-in db [:ui :passepartout]))))
|
||||
(rf/reg-sub ::mat (fn [db _] (merge {:opacity 0.55} (get-in db [:ui :passepartout]))))
|
||||
(rf/reg-event-db ::mat (fn [db [_ k v]] (assoc-in db [:ui :passepartout k] v)))
|
||||
|
||||
(defn fit-stage! []
|
||||
|
|
@ -177,17 +177,12 @@
|
|||
(js/requestAnimationFrame #(do (set! (.-scrollLeft area) 0) (set! (.-scrollTop area) 0)))))))
|
||||
|
||||
(defn stage-controls []
|
||||
(let [{:keys [margin opacity]} @(rf/subscribe [::mat])]
|
||||
(let [{:keys [opacity]} @(rf/subscribe [::mat])]
|
||||
[:<>
|
||||
[:button {:on-click fit-stage! :title "Fit stage and surrounding workspace in view"} "fit"]
|
||||
[:details.passepartout-controls
|
||||
[:summary "passepartout"]
|
||||
[:div.view-popout
|
||||
[:label "Outside margin (px)"
|
||||
[:input {:type "number" :min 0 :max 1000 :value margin
|
||||
:on-change #(let [v (js/parseInt (.. % -target -value))]
|
||||
(when (js/Number.isFinite v) (rf/dispatch [::mat :margin (max 0 (min 1000 v))])))}]]
|
||||
[:label "Shade outside export bounds"
|
||||
[:label "Passepartout"
|
||||
[:input {:type "range" :min 0 :max 1 :step 0.05 :value opacity
|
||||
:on-change #(rf/dispatch [::mat :opacity (js/parseFloat (.. % -target -value))])}]]
|
||||
[:p "Draw outside the rectangle. Exports trim to the symbol’s dimensions."]]]]))
|
||||
:on-change #(rf/dispatch [::mat :opacity (js/parseFloat (.. % -target -value))])}]]]]]))
|
||||
|
|
|
|||
|
|
@ -261,14 +261,6 @@
|
|||
(as-> ops (reduce #(clip/in-layer %1 target (poly (outline/join %2) {:color 0 :knock knock}))
|
||||
ops rings)))))
|
||||
|
||||
(defn- shifted-op [op margin]
|
||||
(cond-> op
|
||||
(:pts op) (assoc :pts (let [pts (:pts op) n (* 2 (:n op)) shifted (js/Float64Array. n)]
|
||||
(dotimes [i n] (aset shifted i (+ margin (aget pts i))))
|
||||
shifted))
|
||||
(:cx op) (update :cx + margin)
|
||||
(:cy op) (update :cy + margin)))
|
||||
|
||||
(defn paint!
|
||||
"Resolve `f` and put it on the canvas. `ops` are consumed here and only here —
|
||||
the resolver reuses its point buffers between frames, so they have to be
|
||||
|
|
@ -284,8 +276,7 @@
|
|||
;; THE STAGE IS THE CLIP'S, not a constant. Project dimensions are
|
||||
;; independent of the footage, so the size the frame is rasterised at comes
|
||||
;; out of the document like everything else.
|
||||
(let [margin (:margin mat 100)
|
||||
ras (raster-for (+ width (* 2 margin)) (+ height (* 2 margin)))
|
||||
(let [ras (raster-for width height)
|
||||
{traces true picture false} (group-by #(= :trace (:kind %)) (resolver f))
|
||||
;; A layer switched off, or all of them, is not on the stage at all:
|
||||
;; not painted and not there to be clicked.
|
||||
|
|
@ -296,10 +287,10 @@
|
|||
(swap! state assoc :ops (into (vec picture) traces))
|
||||
(-> ras
|
||||
(raster/clear! bg)
|
||||
(raster/draw-ops! (map #(shifted-op % margin) (with-previews picture palette active))))
|
||||
(raster/draw-ops! (with-previews picture palette active)))
|
||||
(js/performance.mark "arthur/blit:start")
|
||||
(canvas/blit! canvas ras (pal/effective-ramp palette active))
|
||||
(tracing/paint! traces (assoc tracing :width (+ width (* 2 margin)) :origin margin :playing? playing?) repaint!))
|
||||
(tracing/paint! traces (assoc tracing :width width :origin 0 :playing? playing?) repaint!))
|
||||
(js/performance.measure "arthur/resolve+draw" "arthur/paint:start" "arthur/blit:start")
|
||||
(js/performance.measure "arthur/paint" "arthur/paint:start")
|
||||
;; User Timing entries otherwise accumulate forever in the browser's
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
[re-frame.core :as rf]
|
||||
[reagent.core :as r]))
|
||||
|
||||
;; Pointer coordinates come from the SVG transform, including the outside margin.
|
||||
;; Pointer coordinates come from the SVG transform, in stage pixels.
|
||||
|
||||
(defn- event-point [element event]
|
||||
(let [svg (if (= "svg" (.-tagName element)) element (.querySelector element "svg.paint-overlay"))
|
||||
|
|
@ -415,8 +415,7 @@
|
|||
(when (and (some? c) (not (symbol/knockout? c)) (or all? (= c start)))
|
||||
q))))
|
||||
(get-in document [:symbols sid :nodes]))))
|
||||
m (outline/stamp! (let [margin (:margin @(rf/subscribe [::layout/mat]))]
|
||||
(assoc (outline/mask (+ (:w ctx) (* 2 margin)) (+ (:h ctx) (* 2 margin))) :origin [(- margin) (- margin)])) p p size)
|
||||
m (outline/stamp! (outline/mask (:w ctx) (:h ctx)) p p size)
|
||||
s (cond
|
||||
;; The brush's target is the creation target, which the player
|
||||
;; reads for itself.
|
||||
|
|
@ -499,7 +498,7 @@
|
|||
[:circle {:class (str "first" (when (and hover (closes? draft hover)) " closing"))
|
||||
:cx fx :cy fy :r 1.8}]])))
|
||||
|
||||
(defn- overlay [w h zoom margin opacity]
|
||||
(defn- overlay [w h zoom opacity]
|
||||
(let [tool @(rf/subscribe [::sub/tool])
|
||||
draft @(rf/subscribe [::sub/draft])
|
||||
hover @(rf/subscribe [::sub/hover])
|
||||
|
|
@ -528,8 +527,8 @@
|
|||
mark @marquee]
|
||||
[:svg {:class (str "paint-overlay tool-" (name tool)
|
||||
(when (and pen? hover (closes? draft hover)) " closing"))
|
||||
:width (* zoom (+ w (* 2 margin))) :height (* zoom (+ h (* 2 margin)))
|
||||
:view-box (str (- margin) " " (- margin) " " (+ w (* 2 margin)) " " (+ h (* 2 margin)))
|
||||
:width (* zoom 3 w) :height (* zoom 3 h)
|
||||
:view-box (str (- w) " " (- h) " " (* 3 w) " " (* 3 h))
|
||||
:tab-index -1
|
||||
:on-pointer-down
|
||||
(fn [^js event]
|
||||
|
|
@ -615,9 +614,8 @@
|
|||
(reset! dragging nil) (reset! marquee nil)
|
||||
(reset! painting nil) (player/stroke! nil)
|
||||
(let-go! false))}
|
||||
[:path {:d (str "M" (- margin) " " (- margin) "h" (+ w (* 2 margin)) "v" (+ h (* 2 margin)) "h" (- (+ w (* 2 margin))) "z M0 0v" h "h" w "v" (- h) "z")
|
||||
[:path {:d (str "M" (- w) " " (- h) "h" (* 3 w) "v" (* 3 h) "h" (* -3 w) "z M0 0v" h "h" w "v" (- h) "z")
|
||||
:fill "#000" :fill-rule "evenodd" :opacity opacity :pointer-events "none"}]
|
||||
[:rect {:x 0 :y 0 :width w :height h :fill "none" :stroke "#aaa" :vector-effect "non-scaling-stroke" :pointer-events "none"}]
|
||||
[ghost]
|
||||
(when (seq selected-pts)
|
||||
[:polygon.selected-paint-outline
|
||||
|
|
@ -723,8 +721,7 @@
|
|||
destination-name (when-let [sid (:sid destination)]
|
||||
(clip/symbol-name clip sid))
|
||||
zoom @(rf/subscribe [::layout/zoom :stage])
|
||||
{:keys [margin opacity]} @(rf/subscribe [::layout/mat])
|
||||
vw (+ w (* 2 margin)) vh (+ h (* 2 margin))]
|
||||
{:keys [opacity]} @(rf/subscribe [::layout/mat])]
|
||||
[:div.stage-area
|
||||
(navigation)
|
||||
[:div.stage-wrap
|
||||
|
|
@ -733,7 +730,7 @@
|
|||
;; `dragenter` is cancelled as well as `dragover`: a drop target has to
|
||||
;; accept on BOTH, and the element under the pointer changes whenever the
|
||||
;; preview re-renders beneath it, which fires a fresh `dragenter`.
|
||||
{:data-width vw :data-height vh
|
||||
{:data-width w :data-height h
|
||||
:on-drag-enter (fn [^js event] (when (drag/accepts?) (.preventDefault event)))
|
||||
:on-drag-over (fn [^js event]
|
||||
(when (drag/accepts?)
|
||||
|
|
@ -746,12 +743,12 @@
|
|||
(.preventDefault event)
|
||||
(drag/land! frame (stage-point event w h)))}
|
||||
[:canvas.stage {:ref #(player/set-canvas! %)
|
||||
:width vw :height vh
|
||||
:style {:width (str (* zoom vw) "px")
|
||||
:height (str (* zoom vh) "px")}}]
|
||||
:width w :height h
|
||||
:style {:width (str (* zoom w) "px")
|
||||
:height (str (* zoom h) "px")}}]
|
||||
[:canvas.tracing {:ref #(tracing/set-canvas! %)
|
||||
:width (* zoom vw) :height (* zoom vh)}]
|
||||
[overlay w h zoom margin opacity]]
|
||||
:width (* zoom w) :height (* zoom h)}]
|
||||
[:div.stage-overlay-wrap [overlay w h zoom opacity]]]
|
||||
(when destination-name
|
||||
[:div.stage-target "creating in " [:strong destination-name]])
|
||||
[tools/adjust-last]]))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue