]> source.dussan.org Git - svg.js.git/commitdiff
fixing dmove for nested svgs (https://github.com/svgdotjs/svg.draggable.js/issues...
authorUlrich-Matthias Schäfer <ulima.ums@googlemail.com>
Thu, 27 Jun 2024 09:57:42 +0000 (11:57 +0200)
committerUlrich-Matthias Schäfer <ulima.ums@googlemail.com>
Thu, 27 Jun 2024 09:57:42 +0000 (11:57 +0200)
spec/spec/modules/core/containerGeometry.js
src/modules/core/containerGeometry.js

index 011d9a83f1fae4ee201b36bbfbef7a6578712c80..2bb2fcaf3d2dd332a141b800af0f008c2fbdd4fb 100644 (file)
@@ -47,6 +47,60 @@ describe('containerGeometry.js', () => {
       expect(newBox.h).toBeCloseTo(oldBox.h, 4)
     })
 
+    it('moves nested svgs in a group correctly when calling dmove', () => {
+      const canvas = SVG().addTo(container)
+      const g = canvas.group()
+      const s1 = g.nested().size(100, 100).move(100, 100)
+      s1.rect(100, 100).move(50, 50).rotate(10)
+
+      const oldBox = g.bbox()
+
+      g.dmove(10, 10)
+
+      const newBox = g.bbox()
+
+      expect(newBox.x).toBeCloseTo(oldBox.x + 10, 4)
+      expect(newBox.y).toBeCloseTo(oldBox.y + 10, 4)
+      expect(newBox.w).toBeCloseTo(oldBox.w, 4)
+      expect(newBox.h).toBeCloseTo(oldBox.h, 4)
+    })
+
+    it('moves nested svgs in a group correctly when calling dmove (2)', () => {
+      const canvas = SVG().addTo(container)
+      const g = canvas.group()
+      const s1 = g.nested().move(100, 100)
+      s1.rect(100, 100).move(50, 50).rotate(10)
+
+      const oldBox = g.bbox()
+
+      g.dmove(10, 10)
+
+      const newBox = g.bbox()
+
+      expect(newBox.x).toBeCloseTo(oldBox.x + 10, 4)
+      expect(newBox.y).toBeCloseTo(oldBox.y + 10, 4)
+      expect(newBox.w).toBeCloseTo(oldBox.w, 4)
+      expect(newBox.h).toBeCloseTo(oldBox.h, 4)
+    })
+
+    it('moves nested svgs in a group correctly when calling dmove (3)', () => {
+      const canvas = SVG().addTo(container)
+      const g = canvas.group()
+      const s1 = g.nested()
+      s1.rect(100, 100).move(50, 50).rotate(10)
+
+      const oldBox = g.bbox()
+
+      g.dmove(10, 10)
+
+      const newBox = g.bbox()
+
+      expect(newBox.x).toBeCloseTo(oldBox.x + 10, 4)
+      expect(newBox.y).toBeCloseTo(oldBox.y + 10, 4)
+      expect(newBox.w).toBeCloseTo(oldBox.w, 4)
+      expect(newBox.h).toBeCloseTo(oldBox.h, 4)
+    })
+
     it('it does not fail when hitting elements without bbox', () => {
       const canvas = SVG().addTo(container)
       const g = canvas.group()
index 21139e8f1f47c12fcbeda31dc5cf270f9e9a0b89..32a3c8eceaa614f485b95293820c16c094ed7541 100644 (file)
@@ -1,6 +1,8 @@
 import Matrix from '../../types/Matrix.js'
 import Point from '../../types/Point.js'
+import Box from '../../types/Box.js'
 import { proportionalSize } from '../../utils/utils.js'
+import { getWindow } from '../../utils/window.js'
 
 export function dmove(dx, dy) {
   this.children().forEach((child) => {
@@ -10,7 +12,12 @@ export function dmove(dx, dy) {
     // e.g. title and other descriptive elements
     try {
       // Get the childs bbox
-      bbox = child.bbox()
+      // Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1905039
+      // Because bbox for nested svgs returns the contents bbox in the coordinate space of the svg itself (weird!), we cant use bbox for svgs
+      // Therefore we have to use getBoundingClientRect. But THAT is broken (as explained in the bug).
+      // Funnily enough the broken behavior would work for us but that breaks it in chrome
+      // So we have to replicate the broken behavior of FF by just reading the attributes of the svg itself
+      bbox = child.node instanceof getWindow().SVGSVGElement ? new Box(child.attr(['x', 'y', 'width', 'height'])) : child.bbox()
     } catch (e) {
       return
     }