Przeglądaj źródła

Merge branch 'master' of https://github.com/BabylonJS/Babylon.js

David Catuhe 5 lat temu
rodzic
commit
ae1026b485

+ 2 - 0
dist/preview release/what's new.md

@@ -312,6 +312,8 @@
 - Fixed an issue with isSessionSupported return value being ignored ([#7501](https://github.com/BabylonJS/Babylon.js/issues/7501)) ([RaananW](https://github.com/RaananW/))
 - Added isRigCamera to rig cameras so they can be detected. Used to fix a bug with utility layer and WebXR ([#7517](https://github.com/BabylonJS/Babylon.js/issues/7517)) ([RaananW](https://github.com/RaananW/))
 - Fixed bug in the `ScrollViewer` GUI class when setting a `idealWidth` or `idealHeight` on the ADT ([Popov72](https://github.com/Popov72))
+- Fixed bug in the `Image` GUI class where some properties were lost after a rotation by n x 90° ([Popov72](https://github.com/Popov72))
+- Fixed bug in the `Image` GUI class when rotating a SVG picture ([Popov72](https://github.com/Popov72))
 
 ## Breaking changes
 

+ 76 - 1
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
@@ -261,7 +273,7 @@ export class Image extends Control {
     }
 
     /** @hidden */
-    public _rotate90(n: number): Image {
+    public _rotate90(n: number, preserveProperties: boolean = false): Image {
         let canvas = document.createElement('canvas');
 
         const context = canvas.getContext('2d')!;
@@ -279,9 +291,70 @@ export class Image extends Control {
         const dataUrl: string = canvas.toDataURL("image/jpg");
         const rotatedImage = new Image(this.name + "rotated", dataUrl);
 
+        if (preserveProperties) {
+            rotatedImage._stretch = this._stretch;
+            rotatedImage._autoScale = this._autoScale;
+            rotatedImage._cellId = this._cellId;
+            rotatedImage._cellWidth = n % 1 ? this._cellHeight : this._cellWidth;
+            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
      */
@@ -401,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
@@ -477,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);
             }
         }

+ 28 - 24
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;
@@ -187,21 +189,21 @@ export class ImageScrollBar extends BaseSlider {
         var width = this._renderWidth;
         var height = this._renderHeight;
 
-       // Background
-       if (this._backgroundImage) {
-        this._tempMeasure.copyFromFloats(left, top, width, height);
-        if (this.isVertical) {
-            this._tempMeasure.copyFromFloats(left + width * (1 - this._barImageHeight) * 0.5, this._currentMeasure.top, width * this._barImageHeight, height);
-            this._tempMeasure.height += this._effectiveThumbThickness;
-            this._backgroundImage._currentMeasure.copyFrom(this._tempMeasure);
-        }
-        else {
-            this._tempMeasure.copyFromFloats(this._currentMeasure.left, top + height * (1 - this._barImageHeight) * 0.5, width, height * this._barImageHeight);
-            this._tempMeasure.width += this._effectiveThumbThickness;
-            this._backgroundImage._currentMeasure.copyFrom(this._tempMeasure);
+        // Background
+        if (this._backgroundImage) {
+            this._tempMeasure.copyFromFloats(left, top, width, height);
+            if (this.isVertical) {
+                this._tempMeasure.copyFromFloats(left + width * (1 - this._barImageHeight) * 0.5, this._currentMeasure.top, width * this._barImageHeight, height);
+                this._tempMeasure.height += this._effectiveThumbThickness;
+                this._backgroundImage._currentMeasure.copyFrom(this._tempMeasure);
+            }
+            else {
+                this._tempMeasure.copyFromFloats(this._currentMeasure.left, top + height * (1 - this._barImageHeight) * 0.5, width, height * this._barImageHeight);
+                this._tempMeasure.width += this._effectiveThumbThickness;
+                this._backgroundImage._currentMeasure.copyFrom(this._tempMeasure);
+            }
+            this._backgroundImage._draw(context);
         }
-        this._backgroundImage._draw(context);
-    }
 
         // Thumb
         if (this.isVertical) {
@@ -211,8 +213,10 @@ export class ImageScrollBar extends BaseSlider {
             this._tempMeasure.copyFromFloats(this._currentMeasure.left + thumbPosition, this._currentMeasure.top + this._currentMeasure.height * (1 - this._thumbHeight) * 0.5, this._effectiveThumbThickness, this._currentMeasure.height * this._thumbHeight);
         }
 
-        this._thumbImage._currentMeasure.copyFrom(this._tempMeasure);
-        this._thumbImage._draw(context);
+        if (this._thumbImage) {
+            this._thumbImage._currentMeasure.copyFrom(this._tempMeasure);
+            this._thumbImage._draw(context);
+        }
 
         context.restore();
     }