0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-01-10 08:50:57 -05:00

🐛 Fix problems with interactions in view mode

This commit is contained in:
alonso.torres 2021-05-05 16:14:57 +02:00
parent 437a6cf476
commit d965736751

View file

@ -7,37 +7,53 @@
(ns app.main.ui.viewer.shapes (ns app.main.ui.viewer.shapes
"The main container for a frame in viewer mode" "The main container for a frame in viewer mode"
(:require (:require
[rumext.alpha :as mf]
[app.common.data :as d] [app.common.data :as d]
[app.common.geom.matrix :as gmt]
[app.common.geom.point :as gpt]
[app.common.geom.shapes :as geom]
[app.common.pages :as cp] [app.common.pages :as cp]
[app.main.data.viewer :as dv] [app.main.data.viewer :as dv]
[app.main.refs :as refs] [app.main.refs :as refs]
[app.main.store :as st] [app.main.store :as st]
[app.main.ui.shapes.filters :as filters]
[app.main.ui.shapes.circle :as circle] [app.main.ui.shapes.circle :as circle]
[app.main.ui.shapes.filters :as filters]
[app.main.ui.shapes.frame :as frame] [app.main.ui.shapes.frame :as frame]
[app.main.ui.shapes.group :as group] [app.main.ui.shapes.group :as group]
[app.main.ui.shapes.svg-raw :as svg-raw]
[app.main.ui.shapes.image :as image] [app.main.ui.shapes.image :as image]
[app.main.ui.shapes.path :as path] [app.main.ui.shapes.path :as path]
[app.main.ui.shapes.rect :as rect] [app.main.ui.shapes.rect :as rect]
[app.main.ui.shapes.shape :refer [shape-container]]
[app.main.ui.shapes.svg-raw :as svg-raw]
[app.main.ui.shapes.text :as text] [app.main.ui.shapes.text :as text]
[app.util.dom :as dom]
[app.util.object :as obj] [app.util.object :as obj]
[app.common.geom.matrix :as gmt] [rumext.alpha :as mf]))
[app.common.geom.point :as gpt]
[app.common.geom.shapes :as geom]
[app.main.ui.shapes.shape :refer [shape-container]]))
(defn on-mouse-down (defn on-mouse-down
[event {:keys [interactions] :as shape}] [event interactions]
(let [interaction (first (filter #(= (:event-type %) :click) interactions))] (let [interaction (first (filter #(= (:event-type %) :click) interactions))]
(case (:action-type interaction) (case (:action-type interaction)
:navigate :navigate
(let [frame-id (:destination interaction)] (let [frame-id (:destination interaction)]
(dom/stop-propagation event)
(st/emit! (dv/go-to-frame frame-id))) (st/emit! (dv/go-to-frame frame-id)))
nil))) nil)))
(mf/defc interaction
[{:keys [shape interactions show-interactions?]}]
(let [{:keys [x y width height]} shape]
(when-not (empty? interactions)
[:rect {:x (- x 1)
:y (- y 1)
:width (+ width 2)
:height (+ height 2)
:fill "#31EFB8"
:stroke "#31EFB8"
:stroke-width (if show-interactions? 1 0)
:fill-opacity (if show-interactions? 0.2 0)
:style {:pointer-events "none"}}])))
(defn generic-wrapper-factory (defn generic-wrapper-factory
"Wrap some svg shape and add interaction controls" "Wrap some svg shape and add interaction controls"
[component show-interactions?] [component show-interactions?]
@ -45,35 +61,37 @@
{::mf/wrap-props false} {::mf/wrap-props false}
[props] [props]
(let [shape (unchecked-get props "shape") (let [shape (unchecked-get props "shape")
objects (unchecked-get props "objects")
{:keys [x y width height]} (:selrect shape) {:keys [x y width height]} (:selrect shape)
frame? (= :frame (:type shape))
childs (unchecked-get props "childs") childs (unchecked-get props "childs")
frame (unchecked-get props "frame") frame (unchecked-get props "frame")
interactions (->> (:interactions shape)
(filter #(contains? objects (:destination %))))
on-mouse-down (mf/use-callback on-mouse-down (mf/use-callback
(mf/deps shape) (mf/deps interactions)
#(on-mouse-down % shape)) (fn [event]
(on-mouse-down event interactions)))
svg-element? (and (= :svg-raw (:type shape)) svg-element? (and (= :svg-raw (:type shape))
(not= :svg (get-in shape [:content :tag])))] (not= :svg (get-in shape [:content :tag])))]
(if-not svg-element? (if-not svg-element?
[:> shape-container {:shape shape [:> shape-container {:shape shape
:on-mouse-down on-mouse-down :cursor (when-not (empty? interactions) "pointer")
:cursor (when (seq (:interactions shape)) "pointer")} :on-mouse-down on-mouse-down}
[:& component {:shape shape [:& component {:shape shape
:frame frame :frame frame
:childs childs :childs childs
:is-child-selected? true}] :is-child-selected? true}]
(when (:interactions shape)
[:rect {:x (- x 1) [:& interaction {:shape shape
:y (- y 1) :interactions interactions
:width (+ width 2) :show-interactions? show-interactions?}]]
:height (+ height 2)
:fill "#31EFB8"
:stroke "#31EFB8"
:stroke-width (if show-interactions? 1 0)
:fill-opacity (if show-interactions? 0.2 0)}])]
;; Don't wrap svg elements inside a <g> otherwise some can break ;; Don't wrap svg elements inside a <g> otherwise some can break
[:& component {:shape shape [:& component {:shape shape
@ -127,6 +145,7 @@
props (obj/merge! #js {} props props (obj/merge! #js {} props
#js {:shape shape #js {:shape shape
:childs childs :childs childs
:objects objects
:show-interactions? show-interactions?})] :show-interactions? show-interactions?})]
[:> frame-wrapper props])))) [:> frame-wrapper props]))))
@ -141,6 +160,7 @@
childs (mapv #(get objects %) (:shapes shape)) childs (mapv #(get objects %) (:shapes shape))
props (obj/merge! #js {} props props (obj/merge! #js {} props
#js {:childs childs #js {:childs childs
:objects objects
:show-interactions? show-interactions?})] :show-interactions? show-interactions?})]
[:> group-wrapper props])))) [:> group-wrapper props]))))
@ -155,6 +175,7 @@
childs (mapv #(get objects %) (:shapes shape)) childs (mapv #(get objects %) (:shapes shape))
props (obj/merge! #js {} props props (obj/merge! #js {} props
#js {:childs childs #js {:childs childs
:objects objects
:show-interactions? show-interactions?})] :show-interactions? show-interactions?})]
[:> svg-raw-wrapper props])))) [:> svg-raw-wrapper props]))))
@ -179,7 +200,8 @@
(when (and shape (not (:hidden shape))) (when (and shape (not (:hidden shape)))
(let [shape (-> (geom/transform-shape shape) (let [shape (-> (geom/transform-shape shape)
(geom/translate-to-frame frame)) (geom/translate-to-frame frame))
opts #js {:shape shape}] opts #js {:shape shape
:objects objects}]
(case (:type shape) (case (:type shape)
:frame [:g.empty] :frame [:g.empty]
:text [:> text-wrapper opts] :text [:> text-wrapper opts]
@ -187,8 +209,8 @@
:path [:> path-wrapper opts] :path [:> path-wrapper opts]
:image [:> image-wrapper opts] :image [:> image-wrapper opts]
:circle [:> circle-wrapper opts] :circle [:> circle-wrapper opts]
:group [:> group-container {:shape shape :frame frame}] :group [:> group-container {:shape shape :frame frame :objects objects}]
:svg-raw [:> svg-raw-container {:shape shape :frame frame}]))))))) :svg-raw [:> svg-raw-container {:shape shape :frame frame :objects objects}])))))))
(mf/defc frame-svg (mf/defc frame-svg
{::mf/wrap [mf/memo]} {::mf/wrap [mf/memo]}