소스 검색

Fix svg image rotation

Popov72 5 년 전
부모
커밋
a2230b2528
2개의 변경된 파일76개의 추가작업 그리고 8개의 파일을 삭제
  1. 66 0
      gui/src/2D/controls/image.ts
  2. 10 8
      gui/src/2D/controls/sliders/imageScrollBar.ts

+ 66 - 0
gui/src/2D/controls/image.ts

@@ -24,6 +24,8 @@ export class Image extends Control {
     private _sourceTop = 0;
     private _sourceWidth = 0;
     private _sourceHeight = 0;
+    private _svgAttributesComputationCompleted: boolean = false;
+    private _isSVG: boolean = false;
 
     private _cellWidth: number = 0;
     private _cellHeight: number = 0;
@@ -225,6 +227,16 @@ export class Image extends Control {
         this._markAsDirty();
     }
 
+    /** Indicates if the format of the image is SVG */
+    public get isSVG(): boolean {
+        return this._isSVG;
+    }
+
+    /** Gets the status of the SVG attributes computation (sourceLeft, sourceTop, sourceWidth, sourceHeight) */
+    public get svgAttributesComputationCompleted(): boolean {
+        return this._svgAttributesComputationCompleted;
+    }
+
     /**
      * Gets or sets a boolean indicating if the image can force its container to adapt its size
      * @see http://doc.babylonjs.com/how_to/gui#image
@@ -287,10 +299,62 @@ export class Image extends Control {
             rotatedImage._cellHeight = n % 1 ? this._cellWidth : this._cellHeight;
         }
 
+        this._handleRotationForSVGImage(this, rotatedImage, n);
 
         return rotatedImage;
     }
 
+    private _handleRotationForSVGImage(srcImage: Image, dstImage: Image, n: number): void {
+        if (!srcImage._isSVG) {
+            return;
+        }
+
+        if (srcImage._svgAttributesComputationCompleted) {
+            this._rotate90SourceProperties(srcImage, dstImage, n);
+            this._markAsDirty();
+        } else {
+            srcImage.onSVGAttributesComputedObservable.addOnce(() => {
+                this._rotate90SourceProperties(srcImage, dstImage, n);
+                this._markAsDirty();
+            });
+        }
+    }
+
+    private _rotate90SourceProperties(srcImage: Image, dstImage: Image, n: number): void {
+        let srcLeft = srcImage.sourceLeft,
+            srcTop = srcImage.sourceTop,
+            srcWidth = srcImage.domImage.width,
+            srcHeight = srcImage.domImage.height;
+
+        let dstLeft = srcLeft,
+            dstTop = srcTop,
+            dstWidth = srcImage.sourceWidth,
+            dstHeight = srcImage.sourceHeight;
+
+        if (n != 0) {
+            let mult = n < 0 ? -1 : 1;
+            n = n % 4;
+            for (let i = 0; i < Math.abs(n); ++i) {
+                dstLeft = -(srcTop - srcHeight / 2) * mult + srcHeight / 2;
+                dstTop = (srcLeft - srcWidth / 2) * mult + srcWidth / 2;
+                [dstWidth, dstHeight] = [dstHeight, dstWidth];
+                if (n < 0) {
+                    dstTop -= dstHeight;
+                } else {
+                    dstLeft -= dstWidth;
+                }
+                srcLeft = dstLeft;
+                srcTop = dstTop;
+                [srcWidth, srcHeight] = [srcHeight, srcWidth];
+            }
+        }
+
+        dstImage.sourceLeft = dstLeft;
+        dstImage.sourceTop = dstTop;
+        dstImage.sourceWidth = dstWidth;
+        dstImage.sourceHeight = dstHeight;
+    }
+
     /**
      * Gets or sets the internal DOM image used to render the control
      */
@@ -410,6 +474,7 @@ export class Image extends Control {
      */
     private _svgCheck(value: string): string {
         if (window.SVGSVGElement && (value.search(/.svg#/gi) !== -1) && (value.indexOf("#") === value.lastIndexOf("#"))) {
+            this._isSVG = true;
             var svgsrc = value.split('#')[0];
             var elemid = value.split('#')[1];
             // check if object alr exist in document
@@ -486,6 +551,7 @@ export class Image extends Control {
                 this.sourceTop = ((elem_matrix_d * elem_bbox.y + elem_matrix_f) * docheight) / vb_height;
                 this.sourceWidth = (elem_bbox.width * elem_matrix_a) * (docwidth / vb_width);
                 this.sourceHeight = (elem_bbox.height * elem_matrix_d) * (docheight / vb_height);
+                this._svgAttributesComputationCompleted = true;
                 this.onSVGAttributesComputedObservable.notifyObservers(this);
             }
         }

+ 10 - 8
gui/src/2D/controls/sliders/imageScrollBar.ts

@@ -32,9 +32,9 @@ export class ImageScrollBar extends BaseSlider {
         this._backgroundBaseImage = value;
 
         if (this.isVertical) {
-            if (value && !value.isLoaded) {
+            if (!value.isLoaded) {
                 value.onImageLoadedObservable.addOnce(() => {
-                    const rotatedValue = value._rotate90(1);
+                    const rotatedValue = value._rotate90(1, true);
                     this._backgroundImage = rotatedValue;
                     if (!rotatedValue.isLoaded) {
                         rotatedValue.onImageLoadedObservable.addOnce(() => {
@@ -43,9 +43,10 @@ export class ImageScrollBar extends BaseSlider {
                     }
                     this._markAsDirty();
                 });
+            } else {
+                this._backgroundImage = value._rotate90(1, true);
+                this._markAsDirty();
             }
-            this._backgroundImage = value._rotate90(1);
-            this._markAsDirty();
         }
         else {
             this._backgroundImage = value;
@@ -74,9 +75,9 @@ export class ImageScrollBar extends BaseSlider {
         this._thumbBaseImage = value;
 
         if (this.isVertical) {
-            if (value && !value.isLoaded) {
+            if (!value.isLoaded) {
                 value.onImageLoadedObservable.addOnce(() => {
-                    var rotatedValue = value._rotate90(-1);
+                    var rotatedValue = value._rotate90(-1, true);
                     this._thumbImage = rotatedValue;
                     if (!rotatedValue.isLoaded) {
                         rotatedValue.onImageLoadedObservable.addOnce(() => {
@@ -85,9 +86,10 @@ export class ImageScrollBar extends BaseSlider {
                     }
                     this._markAsDirty();
                 });
+            } else {
+                this._thumbImage = value._rotate90(-1, true);
+                this._markAsDirty();
             }
-            this._thumbImage = value._rotate90(-1);
-            this._markAsDirty();
         }
         else {
             this._thumbImage = value;