diff --git a/common/src/app/common/geom/shapes/common.cljc b/common/src/app/common/geom/shapes/common.cljc index aa0a655ec..0cd9d4704 100644 --- a/common/src/app/common/geom/shapes/common.cljc +++ b/common/src/app/common/geom/shapes/common.cljc @@ -70,9 +70,11 @@ ([points matrix] (transform-points points nil matrix)) ([points center matrix] - (let [prev (if center (gmt/translate-matrix center) (gmt/matrix)) - post (if center (gmt/translate-matrix (gpt/negate center)) (gmt/matrix)) + (if (some? matrix) + (let [prev (if center (gmt/translate-matrix center) (gmt/matrix)) + post (if center (gmt/translate-matrix (gpt/negate center)) (gmt/matrix)) - tr-point (fn [point] - (gpt/transform point (gmt/multiply prev matrix post)))] - (mapv tr-point points)))) + tr-point (fn [point] + (gpt/transform point (gmt/multiply prev matrix post)))] + (mapv tr-point points)) + points))) diff --git a/common/src/app/common/geom/shapes/intersect.cljc b/common/src/app/common/geom/shapes/intersect.cljc index 7b8925dc0..a61bd96f7 100644 --- a/common/src/app/common/geom/shapes/intersect.cljc +++ b/common/src/app/common/geom/shapes/intersect.cljc @@ -9,8 +9,10 @@ [app.common.data :as d] [app.common.geom.matrix :as gmt] [app.common.geom.point :as gpt] + [app.common.geom.shapes.common :as gco] [app.common.geom.shapes.path :as gpp] [app.common.geom.shapes.rect :as gpr] + [app.common.geom.shapes.text :as gte] [app.common.math :as mth])) (defn orientation @@ -283,6 +285,23 @@ (is-point-inside-ellipse? (first rect-points) ellipse-data) (intersects-lines-ellipse? rect-lines ellipse-data)))) +(defn overlaps-text? + [{:keys [position-data] :as shape} rect] + + (if (and (some? position-data) (d/not-empty? position-data)) + (let [center (gco/center-shape shape) + + transform-rect + (fn [rect-points] + (gco/transform-points rect-points center (:transform shape)))] + + (->> position-data + (map (comp transform-rect + gpr/rect->points + gte/position-data->rect)) + (some #(overlaps-rect-points? rect %)))) + (overlaps-rect-points? rect (:points shape)))) + (defn overlaps? "General case to check for overlapping between shapes and a rectangle" [shape rect] @@ -291,14 +310,25 @@ (update :x - stroke-width) (update :y - stroke-width) (update :width + (* 2 stroke-width)) - (update :height + (* 2 stroke-width)) - )] + (update :height + (* 2 stroke-width)))] (or (not shape) (let [path? (= :path (:type shape)) - circle? (= :circle (:type shape))] - (and (overlaps-rect-points? rect (:points shape)) - (or (not path?) (overlaps-path? shape rect)) - (or (not circle?) (overlaps-ellipse? shape rect))))))) + circle? (= :circle (:type shape)) + text? (= :text (:type shape))] + (cond + path? + (and (overlaps-rect-points? rect (:points shape)) + (overlaps-path? shape rect)) + + circle? + (and (overlaps-rect-points? rect (:points shape)) + (overlaps-ellipse? shape rect)) + + text? + (overlaps-text? shape rect) + + :else + (overlaps-rect-points? rect (:points shape))))))) (defn has-point-rect? [rect point] diff --git a/common/src/app/common/geom/shapes/text.cljc b/common/src/app/common/geom/shapes/text.cljc new file mode 100644 index 000000000..6058324ea --- /dev/null +++ b/common/src/app/common/geom/shapes/text.cljc @@ -0,0 +1,27 @@ +;; 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) UXBOX Labs SL + +(ns app.common.geom.shapes.text + (:require + [app.common.geom.shapes.common :as gco] + [app.common.geom.shapes.rect :as gpr] + [app.common.geom.shapes.transforms :as gtr])) + +(defn position-data->rect + [{:keys [x y width height]}] + {:x x + :y (- y height) + :width width + :height height}) + +(defn position-data-bounding-box + [{:keys [position-data] :as shape}] + (let [points (->> position-data + (mapcat (comp gpr/rect->points position-data->rect))) + transform (gtr/transform-matrix shape) + points (gco/transform-points points transform)] + (gpr/points->selrect points))) + diff --git a/frontend/src/app/main/ui/shapes/attrs.cljs b/frontend/src/app/main/ui/shapes/attrs.cljs index 3a30cf7f3..c969e2f4e 100644 --- a/frontend/src/app/main/ui/shapes/attrs.cljs +++ b/frontend/src/app/main/ui/shapes/attrs.cljs @@ -82,7 +82,7 @@ (defn add-fill ([attrs shape render-id] - (add-fill attrs shape render-id 0)) + (add-fill attrs shape render-id nil)) ([attrs shape render-id index] (let [fill-attrs @@ -92,7 +92,7 @@ {:fill (str/format "url(#%s)" fill-image-id)}) (contains? shape :fill-color-gradient) - (let [fill-color-gradient-id (str "fill-color-gradient_" render-id "_" index)] + (let [fill-color-gradient-id (str "fill-color-gradient_" render-id (if index (str "_" index) ""))] {:fill (str/format "url(#%s)" fill-color-gradient-id)}) (contains? shape :fill-color) diff --git a/frontend/src/app/main/ui/workspace/viewport/hooks.cljs b/frontend/src/app/main/ui/workspace/viewport/hooks.cljs index 81a9352ba..8af6c2aad 100644 --- a/frontend/src/app/main/ui/workspace/viewport/hooks.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/hooks.cljs @@ -98,16 +98,6 @@ (some #(cph/is-parent? objects % group-id)) (not)))) -(defn check-text-collision? - "Checks if he current position `pos` overlaps any of the text-nodes for the given `text-id`" - [objects pos text-id] - (and (= :text (get-in objects [text-id :type])) - (let [collisions - (->> (dom/query-all (str "#shape-" text-id " .text-node")) - (map dom/get-bounding-rect) - (map dom/bounding-rect->rect))] - (not (some #(gshr/contains-point? % pos) collisions))))) - (defn setup-hover-shapes [page-id move-stream raw-position-ref objects transform selected ctrl? hover hover-ids hover-disabled? zoom] (let [;; We use ref so we don't recreate the stream on a change zoom-ref (mf/use-ref zoom) @@ -180,9 +170,6 @@ remove-xfm (mapcat #(cph/get-parent-ids objects %)) remove-id? (cond-> (into #{} remove-xfm selected) - :always - (into (filter #(check-text-collision? objects (mf/ref-val raw-position-ref) %)) ids) - (not @ctrl?) (into (filter #(group-empty-space? % objects ids)) ids) diff --git a/frontend/src/app/worker/selection.cljs b/frontend/src/app/worker/selection.cljs index 30879d60b..74abc06dc 100644 --- a/frontend/src/app/worker/selection.cljs +++ b/frontend/src/app/worker/selection.cljs @@ -8,6 +8,7 @@ (:require [app.common.data :as d] [app.common.geom.shapes :as gsh] + [app.common.geom.shapes.text :as gte] [app.common.pages :as cp] [app.common.pages.helpers :as cph] [app.common.uuid :as uuid] @@ -23,7 +24,15 @@ (defn index-shape [objects parents-index clip-parents-index] (fn [index shape] - (let [{:keys [x y width height]} (gsh/points->selrect (:points shape)) + (let [{:keys [x y width height]} + (cond + (and (= :text (:type shape)) + (some? (:position-data shape)) + (d/not-empty? (:position-data shape))) + (gte/position-data-bounding-box shape) + + :else + (gsh/points->selrect (:points shape))) shape-bound #js {:x x :y y :width width :height height} parents (get parents-index (:id shape))