Переглянути джерело

Merge pull request #9797 from Pryme8/p8/NinePatchPatch

P8/nine patch patch
David Catuhe 4 роки тому
батько
коміт
8cb4ad7dc4
2 змінених файлів з 215 додано та 227 видалено
  1. 123 122
      dist/preview release/what's new.md
  2. 92 105
      gui/src/2D/controls/image.ts

+ 123 - 122
dist/preview release/what's new.md

@@ -1,122 +1,123 @@
-# 5.0.0
-
-## Major updates
-
-- Infinite Morph Targets: When supported (WebGL2+) you are no more limited to 4 morph targets per mesh ([Deltakosh](https://github.com/deltakosh))
-
-## Updates
-
-### General
-
-- Added static CenterToRef for vectors 2/3/4  ([aWeirdo](https://github.com/aWeirdo))
-- Added ability to view images (ktx2, png, jpg) to the sandbox. ([bghgary](https://github.com/bghgary))
-- Added optional smoothed normals for extruded procedural polygons. ([snagy](https://github.com/snagy))
-- Added support for infinite perspective cameras ([Deltakosh](https://github.com/deltakosh))
-- Added ability to enable/disable ArcRotateCamera zoom on multiTouch event ([NicolasBuecher](https://github.com/NicolasBuecher))
-- Moving button to shared uI folder.([msDestiny14](https://github.com/msDestiny14))
-- Moved sharedUI component to shared UI folder. ([msDestiny14](https://github.com/msDestiny14))
-- Added encapsulate and encapsulateBoundingInfo methods to BoundingInfo. ([Tolo789](https://github.com/Tolo789))
-- Added onLoadObservable to the textureDome class(es) ([RaananW](https://github.com/RaananW))
-- Modified InputManager to use DeviceInputSystem ([PolygonalSun](https://github.com/PolygonalSun))
-
-### Engine
-
-- Moved all instance data from Geometry to Mesh such that the same Geometry objects can be used by many meshes with instancing. Reduces memory consumption on CPU/GPU. ([breakin](https://github.com/breakin)
-
-### Loaders
-
-- Added support for EXT_meshopt_compression for glTF loader. ([zeux](https://github.com/zeux))
-- Increased KHR_materials_transmission render target texture default size. ([Drigax](https://github.com/drigax))
-- Changed glTF loader to remove empty animation groups if there are no animation channels loaded with the given options. ([bghgary](https://github.com/bghgary))
-- Update glTF validator to `2.0.0-dev.3.3`. ([bghgary](https://github.com/bghgary))
-- Added support for KHR_xmp_json_ld for glTF loader. ([Sebavan](https://github.com/sebavan/), [bghgary](https://github.com/bghgary))
-- Added a `OptimizeNormals` option to the OBJ loader to smooth lighting ([Popov72](https://github.com/Popov72))
-
-### Navigation
-
-- Added support for thin instances in navigation mesh creation ([CedricGuillemet](https://github.com/CedricGuillemet))
-- Added recast.d.ts definition file for recast.js ([CedricGuillemet](https://github.com/CedricGuillemet))
-
-### Materials
-
-- Added an `OcclusionMaterial` to simplify depth-only rendering of geometry ([rgerd](https://github.com/rgerd))
-- PrePass can now be used in `RenderTargets` speeding up effects like SSAO2 or MotionBlur ([CraigFeldspar](https://github.com/CraigFeldspar))
-- Added support for morph targets to `ShaderMaterial` ([Popov72](https://github.com/Popov72))
-
-### Inspector
-
-- Increased float precision to 4([msDestiny14](https://github.com/msDestiny14))
-- Added support for sounds in the inspector ([Deltakosh](https://github.com/deltakosh))
-
-### NME
-
-- Increased float precision to 4([msDestiny14](https://github.com/msDestiny14))
-- Added ability to make input node's properties visible in the properties of a custom frame ([msDestiny14](https://github.com/msDestiny14))
-
-### GUIEditor
-
-- Added GUI Editor project to master. ([msDestiny14](https://github.com/msDestiny14))
-- Moving GUI property tab components into GUIEditor. ([msDestiny14](https://github.com/msDestiny14))
-
-### GUI
-
-- Added a `FocusableButton` gui control to simplify creating menus with keyboard navigation ([Flux159](https://github.com/Flux159))
-- Added `focus()` and `blur()` functions for controls that implement `IFocusableControl` ([Flux159](https://github.com/Flux159))
-- Added `ToggleButton` GUI control ([kintz09](https://github.com/kintz09))
-- Added shorthand methods which set all padding values at once, named `setPadding` and `setPaddingInPixels`, to the control class  ([kintz09](https://github.com/kintz09))
-- Added two touch-enabled GUI controls, `TouchMeshButton3D` and `TouchHolographicButton`, added option on the WebXR hand tracking feature for enabling touch collisions ([rickfromwork](https://github.com/rickfromwork), [satyapoojasama](https://github.com/satyapoojasama))
-
-### WebXR
-
-- A browser error preventing the emulator to render scene is now correctly dealt with ([RaananW](https://github.com/RaananW))
-- Added a way to extend the XRSessionInit Object from inside of a feature ([RaananW](https://github.com/RaananW))
-- Added image tracking feature ([RaananW](https://github.com/RaananW))
-- Pointer Events of WebXR controllers have pointerType `xr` ([RaananW](https://github.com/RaananW))
-- better support for custom hand meshes ([RaananW](https://github.com/RaananW))
-- Allow disabling of the WebXRControllerPointerSelection feature as part of the WebXR Default Experience ([rgerd](https://github.com/rgerd))
-- Added two touch-enabled GUI controls, `TouchMeshButton3D` and `TouchHolographicButton`, added option on the WebXR hand tracking feature for enabling touch collisions ([rickfromwork](https://github.com/rickfromwork), [satyapoojasama](https://github.com/satyapoojasama))
-
-### Viewer
-
-- Fixed an issue with dual callback binding in case of a forced redraw ([#9608](https://github.com/BabylonJS/Babylon.js/issues/9608)) ([RaananW](https://github.com/RaananW))
-
-## Bugs
-
-- Fix issue with the Promise polyfill where a return value was expected from resolve() ([Deltakosh](https://github.com/deltakosh))
-- Fix ArcRotateCamera panning with axis decomposition ([CedricGuillemet](https://github.com/CedricGuillemet))
-- Fix an issue with keyboard control (re)attachment. ([#9411](https://github.com/BabylonJS/Babylon.js/issues/9411)) ([RaananW](https://github.com/RaananW))
-- Fix issue where PBRSpecularGlossiness materials were excluded from export [#9423](https://github.com/BabylonJS/Babylon.js/issues/9423)([Drigax](https://github.com/drigax))
-- Fix issue when scaling is reapplied with BoundingBoxGizmo and GizmoManager ([CedricGuillemet](https://github.com/CedricGuillemet))
-- Fix direct loading of a glTF string that has base64-encoded URI. ([bghgary](https://github.com/bghgary))
-- Fix capsule impostor size computation for ammojs ([CedricGuillemet](https://github.com/CedricGuillemet))
-- Fix crash of some node materials using instances on iOS ([Popov72](https://github.com/Popov72))
-- Fix the code generated for the NME gradient block ([Popov72](https://github.com/Popov72))
-- Fix ssao2RenderingPipeline for orthographic cameras ([Kesshi](https://github.com/Kesshi))
-- Fix mipmaps creation in the KTX2 decoder for non square textures ([Popov72](https://github.com/Popov72))
-- Fix detail map not working in WebGL1 ([Popov72](https://github.com/Popov72))
-- Fix ArcRotateCamera behaviour when panning is disabled on multiTouch event ([NicolasBuecher](https://github.com/NicolasBuecher))
-- Fix vertically interlaced stereoscopic rendering (`RIG_MODE_STEREOSCOPIC_INTERLACED`) not working (follow-up [#7425](https://github.com/BabylonJS/Babylon.js/issues/7425), [#8000](https://github.com/BabylonJS/Babylon.js/issues/8000)) ([foxxyz](https://github.com/foxxyz))
-- Fix accessibility of BaseCameraMouseWheelInput and BaseCameraPointersInput. They appear in documentation but were not available for include. ([mrdunk](https://github.com/mrdunk))
-- Fix function creation inside regularly called freeCameraMouseWheelInput method leading to excessive GC load. ([mrdunk](https://github.com/mrdunk))
-- Fix clip plane not reset to the rigth value when using mirrors ([Popov72](https://github.com/Popov72))
-- Fix lens flares not working in right handed system ([Popov72](https://github.com/Popov72))
-- Fix canvas not resized correctly in a multi-canvas scenario ([Popov72](https://github.com/Popov72))
-- Fix NaN values returned by `GetAngleBetweenVectors` when vectors are the same or directly opposite ([Popov72](https://github.com/Popov72))
-- Fix 404 occurring on some pictures in some cases when using particle systems ([Popov72](https://github.com/Popov72))
-- Fix PrePass bugs with transparency ([CraigFeldspar](https://github.com/CraigFeldspar))
-- Fix PrePass bugs with layers ([CraigFeldspar](https://github.com/CraigFeldspar))
-- Fix SSAO2 with PrePass sometimes causing colors brighter than they should be ([CraigFeldspar](https://github.com/CraigFeldspar))
-- Fix PostProcess sharing between cameras/renderTargets, that would create/destroy a texture on every frame ([CraigFeldspar](https://github.com/CraigFeldspar))
-- Fix for DualSense gamepads being incorrectly read as DualShock gamepads ([PolygonalSun](https://github.com/PolygonalSun))
-- Fix for warning in chrome about passive wheel events ([#9777](https://github.com/BabylonJS/Babylon.js/pull/9777)) ([kaliatech](https://github.com/kaliatech))
-- Fix crash when cloning material in `AssetContainer.instantiateModelsToScene` when mesh is an instanced mesh ([Popov72](https://github.com/Popov72))
-
-## Breaking changes
-
-- [List of breaking changes introduced by ou compatibility with WebGPU](https://doc.babylonjs.com/advanced_topics/webGPU/webGPUBreakingChanges)
-  - [ReadPixels and ProceduralTexture.getContent are now async](https://doc.babylonjs.com/advanced_topics/webGPU/webGPUBreakingChanges#readpixels-is-now-asynchronous)
-  - [Shader support differences](https://doc.babylonjs.com/advanced_topics/webGPU/webGPUBreakingChanges#shader-code-differences)
-- Use both `mesh.visibility` and `material.alpha` values to compute the global alpha value used by the soft transparent shadow rendering code. Formerly was only using `mesh.visibility` ([Popov72](https://github.com/Popov72))
-- Depth renderer: don't render mesh if `infiniteDistance = true` or if `material.disableDepthWrite = true` ([Popov72](https://github.com/Popov72))
-- Mesh.createInstance no longer make a unique Geometry for the Mesh so updating one Geometry can affect more meshes than before. Use Mesh.makeUniqueGeometry for old behaviour. ([breakin](https://github.com/breakin))
-- Ammo.js needs to be initialized before creating the plugin with `await Ammo();` since Ammo introduced an async init in their library. ([sebavan](https://github.com/sebavan))
+# 5.0.0
+
+## Major updates
+
+- Infinite Morph Targets: When supported (WebGL2+) you are no more limited to 4 morph targets per mesh ([Deltakosh](https://github.com/deltakosh))
+
+## Updates
+
+### General
+
+- Added static CenterToRef for vectors 2/3/4  ([aWeirdo](https://github.com/aWeirdo))
+- Added ability to view images (ktx2, png, jpg) to the sandbox. ([bghgary](https://github.com/bghgary))
+- Added optional smoothed normals for extruded procedural polygons. ([snagy](https://github.com/snagy))
+- Added support for infinite perspective cameras ([Deltakosh](https://github.com/deltakosh))
+- Added ability to enable/disable ArcRotateCamera zoom on multiTouch event ([NicolasBuecher](https://github.com/NicolasBuecher))
+- Moving button to shared uI folder.([msDestiny14](https://github.com/msDestiny14))
+- Moved sharedUI component to shared UI folder. ([msDestiny14](https://github.com/msDestiny14))
+- Added encapsulate and encapsulateBoundingInfo methods to BoundingInfo. ([Tolo789](https://github.com/Tolo789))
+- Added onLoadObservable to the textureDome class(es) ([RaananW](https://github.com/RaananW))
+- Modified InputManager to use DeviceInputSystem ([PolygonalSun](https://github.com/PolygonalSun))
+
+### Engine
+
+- Moved all instance data from Geometry to Mesh such that the same Geometry objects can be used by many meshes with instancing. Reduces memory consumption on CPU/GPU. ([breakin](https://github.com/breakin)
+
+### Loaders
+
+- Added support for EXT_meshopt_compression for glTF loader. ([zeux](https://github.com/zeux))
+- Increased KHR_materials_transmission render target texture default size. ([Drigax](https://github.com/drigax))
+- Changed glTF loader to remove empty animation groups if there are no animation channels loaded with the given options. ([bghgary](https://github.com/bghgary))
+- Update glTF validator to `2.0.0-dev.3.3`. ([bghgary](https://github.com/bghgary))
+- Added support for KHR_xmp_json_ld for glTF loader. ([Sebavan](https://github.com/sebavan/), [bghgary](https://github.com/bghgary))
+- Added a `OptimizeNormals` option to the OBJ loader to smooth lighting ([Popov72](https://github.com/Popov72))
+
+### Navigation
+
+- Added support for thin instances in navigation mesh creation ([CedricGuillemet](https://github.com/CedricGuillemet))
+- Added recast.d.ts definition file for recast.js ([CedricGuillemet](https://github.com/CedricGuillemet))
+
+### Materials
+
+- Added an `OcclusionMaterial` to simplify depth-only rendering of geometry ([rgerd](https://github.com/rgerd))
+- PrePass can now be used in `RenderTargets` speeding up effects like SSAO2 or MotionBlur ([CraigFeldspar](https://github.com/CraigFeldspar))
+- Added support for morph targets to `ShaderMaterial` ([Popov72](https://github.com/Popov72))
+
+### Inspector
+
+- Increased float precision to 4([msDestiny14](https://github.com/msDestiny14))
+- Added support for sounds in the inspector ([Deltakosh](https://github.com/deltakosh))
+
+### NME
+
+- Increased float precision to 4([msDestiny14](https://github.com/msDestiny14))
+- Added ability to make input node's properties visible in the properties of a custom frame ([msDestiny14](https://github.com/msDestiny14))
+
+### GUIEditor
+
+- Added GUI Editor project to master. ([msDestiny14](https://github.com/msDestiny14))
+- Moving GUI property tab components into GUIEditor. ([msDestiny14](https://github.com/msDestiny14))
+
+### GUI
+
+- Added a `FocusableButton` gui control to simplify creating menus with keyboard navigation ([Flux159](https://github.com/Flux159))
+- Added `focus()` and `blur()` functions for controls that implement `IFocusableControl` ([Flux159](https://github.com/Flux159))
+- Added `ToggleButton` GUI control ([kintz09](https://github.com/kintz09))
+- Added shorthand methods which set all padding values at once, named `setPadding` and `setPaddingInPixels`, to the control class  ([kintz09](https://github.com/kintz09))
+- Added two touch-enabled GUI controls, `TouchMeshButton3D` and `TouchHolographicButton`, added option on the WebXR hand tracking feature for enabling touch collisions ([rickfromwork](https://github.com/rickfromwork), [satyapoojasama](https://github.com/satyapoojasama))
+
+### WebXR
+
+- A browser error preventing the emulator to render scene is now correctly dealt with ([RaananW](https://github.com/RaananW))
+- Added a way to extend the XRSessionInit Object from inside of a feature ([RaananW](https://github.com/RaananW))
+- Added image tracking feature ([RaananW](https://github.com/RaananW))
+- Pointer Events of WebXR controllers have pointerType `xr` ([RaananW](https://github.com/RaananW))
+- better support for custom hand meshes ([RaananW](https://github.com/RaananW))
+- Allow disabling of the WebXRControllerPointerSelection feature as part of the WebXR Default Experience ([rgerd](https://github.com/rgerd))
+- Added two touch-enabled GUI controls, `TouchMeshButton3D` and `TouchHolographicButton`, added option on the WebXR hand tracking feature for enabling touch collisions ([rickfromwork](https://github.com/rickfromwork), [satyapoojasama](https://github.com/satyapoojasama))
+
+### Viewer
+
+- Fixed an issue with dual callback binding in case of a forced redraw ([#9608](https://github.com/BabylonJS/Babylon.js/issues/9608)) ([RaananW](https://github.com/RaananW))
+
+## Bugs
+
+- Fix issue with the Promise polyfill where a return value was expected from resolve() ([Deltakosh](https://github.com/deltakosh))
+- Fix ArcRotateCamera panning with axis decomposition ([CedricGuillemet](https://github.com/CedricGuillemet))
+- Fix an issue with keyboard control (re)attachment. ([#9411](https://github.com/BabylonJS/Babylon.js/issues/9411)) ([RaananW](https://github.com/RaananW))
+- Fix issue where PBRSpecularGlossiness materials were excluded from export [#9423](https://github.com/BabylonJS/Babylon.js/issues/9423)([Drigax](https://github.com/drigax))
+- Fix issue when scaling is reapplied with BoundingBoxGizmo and GizmoManager ([CedricGuillemet](https://github.com/CedricGuillemet))
+- Fix direct loading of a glTF string that has base64-encoded URI. ([bghgary](https://github.com/bghgary))
+- Fix capsule impostor size computation for ammojs ([CedricGuillemet](https://github.com/CedricGuillemet))
+- Fix crash of some node materials using instances on iOS ([Popov72](https://github.com/Popov72))
+- Fix the code generated for the NME gradient block ([Popov72](https://github.com/Popov72))
+- Fix ssao2RenderingPipeline for orthographic cameras ([Kesshi](https://github.com/Kesshi))
+- Fix mipmaps creation in the KTX2 decoder for non square textures ([Popov72](https://github.com/Popov72))
+- Fix detail map not working in WebGL1 ([Popov72](https://github.com/Popov72))
+- Fix ArcRotateCamera behaviour when panning is disabled on multiTouch event ([NicolasBuecher](https://github.com/NicolasBuecher))
+- Fix vertically interlaced stereoscopic rendering (`RIG_MODE_STEREOSCOPIC_INTERLACED`) not working (follow-up [#7425](https://github.com/BabylonJS/Babylon.js/issues/7425), [#8000](https://github.com/BabylonJS/Babylon.js/issues/8000)) ([foxxyz](https://github.com/foxxyz))
+- Fix accessibility of BaseCameraMouseWheelInput and BaseCameraPointersInput. They appear in documentation but were not available for include. ([mrdunk](https://github.com/mrdunk))
+- Fix function creation inside regularly called freeCameraMouseWheelInput method leading to excessive GC load. ([mrdunk](https://github.com/mrdunk))
+- Fix clip plane not reset to the rigth value when using mirrors ([Popov72](https://github.com/Popov72))
+- Fix lens flares not working in right handed system ([Popov72](https://github.com/Popov72))
+- Fix canvas not resized correctly in a multi-canvas scenario ([Popov72](https://github.com/Popov72))
+- Fix NaN values returned by `GetAngleBetweenVectors` when vectors are the same or directly opposite ([Popov72](https://github.com/Popov72))
+- Fix 404 occurring on some pictures in some cases when using particle systems ([Popov72](https://github.com/Popov72))
+- Fix PrePass bugs with transparency ([CraigFeldspar](https://github.com/CraigFeldspar))
+- Fix PrePass bugs with layers ([CraigFeldspar](https://github.com/CraigFeldspar))
+- Fix SSAO2 with PrePass sometimes causing colors brighter than they should be ([CraigFeldspar](https://github.com/CraigFeldspar))
+- Fix PostProcess sharing between cameras/renderTargets, that would create/destroy a texture on every frame ([CraigFeldspar](https://github.com/CraigFeldspar))
+- Fix for DualSense gamepads being incorrectly read as DualShock gamepads ([PolygonalSun](https://github.com/PolygonalSun))
+- Fix for warning in chrome about passive wheel events ([#9777](https://github.com/BabylonJS/Babylon.js/pull/9777)) ([kaliatech](https://github.com/kaliatech))
+- Fix crash when cloning material in `AssetContainer.instantiateModelsToScene` when mesh is an instanced mesh ([Popov72](https://github.com/Popov72))
+- Fix issue with NinePatch displaying half pixel gaps between slices on Firefox browsers. ([Pryme8](https://github.com/Pryme8))
+
+## Breaking changes
+
+- [List of breaking changes introduced by ou compatibility with WebGPU](https://doc.babylonjs.com/advanced_topics/webGPU/webGPUBreakingChanges)
+  - [ReadPixels and ProceduralTexture.getContent are now async](https://doc.babylonjs.com/advanced_topics/webGPU/webGPUBreakingChanges#readpixels-is-now-asynchronous)
+  - [Shader support differences](https://doc.babylonjs.com/advanced_topics/webGPU/webGPUBreakingChanges#shader-code-differences)
+- Use both `mesh.visibility` and `material.alpha` values to compute the global alpha value used by the soft transparent shadow rendering code. Formerly was only using `mesh.visibility` ([Popov72](https://github.com/Popov72))
+- Depth renderer: don't render mesh if `infiniteDistance = true` or if `material.disableDepthWrite = true` ([Popov72](https://github.com/Popov72))
+- Mesh.createInstance no longer make a unique Geometry for the Mesh so updating one Geometry can affect more meshes than before. Use Mesh.makeUniqueGeometry for old behaviour. ([breakin](https://github.com/breakin))
+- Ammo.js needs to be initialized before creating the plugin with `await Ammo();` since Ammo introduced an async init in their library. ([sebavan](https://github.com/sebavan))

+ 92 - 105
gui/src/2D/controls/image.ts

@@ -32,12 +32,13 @@ export class Image extends Control {
     private _cellHeight: number = 0;
     private _cellId: number = -1;
 
-    private _populateNinePatchSlicesFromImage = false;
     private _sliceLeft: number;
     private _sliceRight: number;
     private _sliceTop: number;
     private _sliceBottom: number;
 
+    private _populateNinePatchSlicesFromImage = false;
+
     private _detectPointerOnOpaqueOnly: boolean;
 
     private _imageDataCache: {
@@ -63,26 +64,6 @@ export class Image extends Control {
     }
 
     /**
-     * Gets or sets a boolean indicating if nine patch slices (left, top, right, bottom) should be read from image data
-     */
-    @serialize()
-    public get populateNinePatchSlicesFromImage(): boolean {
-        return this._populateNinePatchSlicesFromImage;
-    }
-
-    public set populateNinePatchSlicesFromImage(value: boolean) {
-        if (this._populateNinePatchSlicesFromImage === value) {
-            return;
-        }
-
-        this._populateNinePatchSlicesFromImage = value;
-
-        if (this._populateNinePatchSlicesFromImage && this._loaded) {
-            this._extractNinePatchSliceDataFromImage();
-        }
-    }
-
-    /**
      * Gets or sets a boolean indicating if pointers should only be validated on pixels with alpha > 0.
      * Beware using this as this will comsume more memory as the image has to be stored twice
      */
@@ -243,6 +224,26 @@ export class Image extends Control {
         this._markAsDirty();
     }
 
+    /**
+    * Gets or sets a boolean indicating if nine patch slices (left, top, right, bottom) should be read from image data
+    */
+    @serialize()
+    public get populateNinePatchSlicesFromImage(): boolean {
+        return this._populateNinePatchSlicesFromImage;
+    }
+
+    public set populateNinePatchSlicesFromImage(value: boolean) {
+        if (this._populateNinePatchSlicesFromImage === value) {
+            return;
+        }
+
+        this._populateNinePatchSlicesFromImage = value;
+
+        if (this._populateNinePatchSlicesFromImage && this._loaded) {
+            this._extractNinePatchSliceDataFromImage();
+        }
+    }
+
     /** Indicates if the format of the image is SVG */
     public get isSVG(): boolean {
         return this._isSVG;
@@ -375,46 +376,6 @@ export class Image extends Control {
         dstImage.sourceHeight = dstHeight;
     }
 
-    /**
-     * Gets or sets the internal DOM image used to render the control
-     */
-    public set domImage(value: HTMLImageElement) {
-        this._domImage = value;
-        this._loaded = false;
-        this._imageDataCache.data = null;
-
-        if (this._domImage.width) {
-            this._onImageLoaded();
-        } else {
-            this._domImage.onload = () => {
-                this._onImageLoaded();
-            };
-        }
-    }
-
-    public get domImage(): HTMLImageElement {
-        return this._domImage;
-    }
-
-    private _onImageLoaded(): void {
-        this._imageDataCache.data = null;
-        this._imageWidth = this._domImage.width;
-        this._imageHeight = this._domImage.height;
-        this._loaded = true;
-
-        if (this._populateNinePatchSlicesFromImage) {
-            this._extractNinePatchSliceDataFromImage();
-        }
-
-        if (this._autoScale) {
-            this.synchronizeSizeWithContent();
-        }
-
-        this.onImageLoadedObservable.notifyObservers(this);
-
-        this._markAsDirty();
-    }
-
     private _extractNinePatchSliceDataFromImage() {
         if (!this._workingCanvas) {
             this._workingCanvas = document.createElement("canvas");
@@ -466,6 +427,46 @@ export class Image extends Control {
     }
 
     /**
+     * Gets or sets the internal DOM image used to render the control
+     */
+    public set domImage(value: HTMLImageElement) {
+        this._domImage = value;
+        this._loaded = false;
+        this._imageDataCache.data = null;
+
+        if (this._domImage.width) {
+            this._onImageLoaded();
+        } else {
+            this._domImage.onload = () => {
+                this._onImageLoaded();
+            };
+        }
+    }
+
+    public get domImage(): HTMLImageElement {
+        return this._domImage;
+    }
+
+    private _onImageLoaded(): void {
+        this._imageDataCache.data = null;
+        this._imageWidth = this._domImage.width;
+        this._imageHeight = this._domImage.height;
+        this._loaded = true;
+
+        if (this._populateNinePatchSlicesFromImage) {
+            this._extractNinePatchSliceDataFromImage();
+        }
+
+        if (this._autoScale) {
+            this.synchronizeSizeWithContent();
+        }
+
+        this.onImageLoadedObservable.notifyObservers(this);
+
+        this._markAsDirty();
+    }
+
+    /**
      * Gets the image source url
      */
     @serialize()
@@ -644,7 +645,6 @@ export class Image extends Control {
      */
     constructor(public name?: string, url: Nullable<string> = null) {
         super(name);
-
         this.source = url;
     }
 
@@ -818,51 +818,38 @@ export class Image extends Control {
         context.restore();
     }
 
-    private _renderCornerPatch(context: CanvasRenderingContext2D, x: number, y: number, width: number, height: number, targetX: number, targetY: number): void {
-        this._drawImage(context, x, y, width, height, this._currentMeasure.left + targetX, this._currentMeasure.top + targetY, width, height);
-    }
-
     private _renderNinePatch(context: CanvasRenderingContext2D): void {
-        let height = this._imageHeight;
-        let leftWidth = this._sliceLeft;
-        let topHeight = this._sliceTop;
-        let bottomHeight = this._imageHeight - this._sliceBottom;
-        let rightWidth = this._imageWidth - this._sliceRight;
-        let left = 0;
-        let top = 0;
-
-        if (this._populateNinePatchSlicesFromImage) {
-            left = 1;
-            top = 1;
-            height -= 2;
-            leftWidth -= 1;
-            topHeight -= 1;
-            bottomHeight -= 1;
-            rightWidth -= 1;
-        }
-
+        const leftWidth = this._sliceLeft;
+        const topHeight = this._sliceTop;
+        const bottomHeight = this._imageHeight - this._sliceBottom;
+        const rightWidth = this._imageWidth - this._sliceRight;
         const centerWidth = this._sliceRight - this._sliceLeft;
-        const targetCenterWidth = this._currentMeasure.width - rightWidth - this.sliceLeft;
-        const targetTopHeight = this._currentMeasure.height - height + this._sliceBottom;
-
-        // Corners
-        this._renderCornerPatch(context, left, top, leftWidth, topHeight, 0, 0);
-        this._renderCornerPatch(context, left, this._sliceBottom, leftWidth, height - this._sliceBottom, 0, targetTopHeight);
-
-        this._renderCornerPatch(context, this._sliceRight, top, rightWidth, topHeight, this._currentMeasure.width - rightWidth, 0);
-        this._renderCornerPatch(context, this._sliceRight, this._sliceBottom, rightWidth, height - this._sliceBottom, this._currentMeasure.width - rightWidth, targetTopHeight);
-
+        const centerHeight = this._sliceBottom - this._sliceTop;
+        const targetCenterWidth = (this._currentMeasure.width - rightWidth - leftWidth) + 2;
+        const targetCenterHeight = (this._currentMeasure.height - bottomHeight - topHeight) + 2;
+        const centerLeftOffset = this._currentMeasure.left + leftWidth - 1;
+        const centerTopOffset = this._currentMeasure.top + topHeight - 1;
+        const rightOffset = this._currentMeasure.left + this._currentMeasure.width - rightWidth;
+        const bottomOffset = this._currentMeasure.top + this._currentMeasure.height - bottomHeight;
+
+        //Top Left
+        this._drawImage(context, 0, 0, leftWidth, topHeight, this._currentMeasure.left, this._currentMeasure.top, leftWidth, topHeight);
+        //Top
+        this._drawImage(context, this._sliceLeft, 0, centerWidth, topHeight, centerLeftOffset, this._currentMeasure.top, targetCenterWidth, topHeight);
+        //Top Right
+        this._drawImage(context, this.sliceRight, 0, rightWidth, topHeight, rightOffset, this._currentMeasure.top, rightWidth, topHeight);
+        //Left
+        this._drawImage(context, 0, this._sliceTop, leftWidth, centerHeight, this._currentMeasure.left, centerTopOffset, leftWidth, targetCenterHeight);
         // Center
-        this._drawImage(context, this._sliceLeft, this._sliceTop, centerWidth, this._sliceBottom - this._sliceTop, this._currentMeasure.left + leftWidth, this._currentMeasure.top + topHeight, targetCenterWidth, targetTopHeight - topHeight);
-
-        // Borders
-        this._drawImage(context, left, this._sliceTop, leftWidth, this._sliceBottom - this._sliceTop, this._currentMeasure.left, this._currentMeasure.top + topHeight, leftWidth, targetTopHeight - topHeight);
-
-        this._drawImage(context, this._sliceRight, this._sliceTop, leftWidth, this._sliceBottom - this._sliceTop, this._currentMeasure.left + this._currentMeasure.width - rightWidth, this._currentMeasure.top + topHeight, leftWidth, targetTopHeight - topHeight);
-
-        this._drawImage(context, this._sliceLeft, top, centerWidth, topHeight, this._currentMeasure.left + leftWidth, this._currentMeasure.top, targetCenterWidth, topHeight);
-
-        this._drawImage(context, this._sliceLeft, this._sliceBottom, centerWidth, bottomHeight, this._currentMeasure.left + leftWidth, this._currentMeasure.top + targetTopHeight, targetCenterWidth, bottomHeight);
+        this._drawImage(context, this._sliceLeft, this._sliceTop, centerWidth, centerHeight, centerLeftOffset, centerTopOffset, targetCenterWidth, targetCenterHeight);
+        //Right
+        this._drawImage(context, this._sliceRight, this._sliceTop, rightWidth, centerHeight, rightOffset, centerTopOffset, rightWidth, targetCenterHeight);
+        //Bottom Left
+        this._drawImage(context, 0, this._sliceBottom, leftWidth, bottomHeight, this._currentMeasure.left, bottomOffset, leftWidth, bottomHeight);
+        //Bottom
+        this._drawImage(context, this.sliceLeft, this._sliceBottom, centerWidth, bottomHeight, centerLeftOffset, bottomOffset, targetCenterWidth, bottomHeight);
+        //Bottom Right
+        this._drawImage(context, this._sliceRight, this._sliceBottom, rightWidth, bottomHeight, rightOffset, bottomOffset, rightWidth, bottomHeight);
     }
 
     public dispose() {
@@ -883,4 +870,4 @@ export class Image extends Control {
     /** NINE_PATCH */
     public static readonly STRETCH_NINE_PATCH = 4;
 }
-_TypeStore.RegisteredTypes["BABYLON.GUI.Image"] = Image;
+_TypeStore.RegisteredTypes["BABYLON.GUI.Image"] = Image;