@@ -222,68 +222,94 @@ export default abstract class Shape extends Observable {
222222 @percentLengthProperty ( { nonPaintProp : true } ) width : PercentLength ;
223223 @percentLengthProperty ( { nonPaintProp : true } ) height : PercentLength ;
224224
225-
226225 @percentLengthProperty ( { nonPaintProp : true } ) paddingLeft : PercentLength ;
227226 @percentLengthProperty ( { nonPaintProp : true } ) paddingRight : PercentLength ;
228227 @percentLengthProperty ( { nonPaintProp : true } ) paddingBottom : PercentLength ;
229228 @percentLengthProperty ( { nonPaintProp : true } ) paddingTop : PercentLength ;
230229
231- @percentLengthProperty ( { nonPaintProp : true } ) marginLeft : PercentLength ;
232- @percentLengthProperty ( { nonPaintProp : true } ) marginRight : PercentLength ;
233- @percentLengthProperty ( { nonPaintProp : true } ) marginTop : PercentLength ;
234- @percentLengthProperty ( { nonPaintProp : true } ) marginBottom : PercentLength ;
230+ @percentLengthProperty ( { nonPaintProp : true } ) translateX : PercentLength = 0 ;
231+ @percentLengthProperty ( { nonPaintProp : true } ) translateY : PercentLength = 0 ;
232+ @numberProperty ( { nonPaintProp : true } ) rotate : number = 0 ;
233+ @numberProperty ( { nonPaintProp : true } ) scaleX : number = 1 ;
234+ @numberProperty ( { nonPaintProp : true } ) scaleY : number = 1 ;
235235
236236 protected handleAlignment = false ;
237237
238238 abstract drawOnCanvas ( canvas : Canvas , parent : CanvasView ) : void ;
239239
240240 getWidth ( availableWidth : number , availableHeight : number ) {
241- return this . width ? Utils . layout . toDeviceIndependentPixels ( PercentLength . toDevicePixels ( this . width , 0 , availableWidth ) ) : 0 ;
241+ return this . width ? Utils . layout . toDeviceIndependentPixels ( PercentLength . toDevicePixels ( this . width , 0 , availableWidth ) ) : 0 ;
242242 }
243243 getHeight ( availableWidth : number , availableHeight : number ) {
244- return this . height ? Utils . layout . toDeviceIndependentPixels ( PercentLength . toDevicePixels ( this . height , 0 , availableHeight ) ) : 0 ;
245-
244+ return this . height ? Utils . layout . toDeviceIndependentPixels ( PercentLength . toDevicePixels ( this . height , 0 , availableHeight ) ) : 0 ;
246245 }
247246
248247 drawMyShapeOnCanvas ( canvas : Canvas , parent : CanvasView , width : number , height : number ) {
249248 if ( this . visibility !== 'visible' ) {
250249 return ;
251250 }
251+
252+ const availableWidth = Utils . layout . toDevicePixels ( canvas . getWidth ( ) ) ;
253+ const availableHeight = Utils . layout . toDevicePixels ( canvas . getHeight ( ) ) ;
254+ let dx = 0 ;
255+ let dy = 0 ;
256+ if ( this . translateX ) {
257+ dx += Utils . layout . toDeviceIndependentPixels ( PercentLength . toDevicePixels ( this . translateX , 0 , availableWidth ) ) ;
258+ }
259+ if ( this . translateY ) {
260+ dy += Utils . layout . toDeviceIndependentPixels ( PercentLength . toDevicePixels ( this . translateY , 0 , availableHeight ) ) ;
261+ }
252262 if ( ! this . handleAlignment ) {
253- const availableWidth = Utils . layout . toDevicePixels ( canvas . getWidth ( ) ) ;
254- const availableHeight = Utils . layout . toDevicePixels ( canvas . getHeight ( ) ) ;
255- const paddingLeft = Utils . layout . toDeviceIndependentPixels ( parent . effectivePaddingLeft + PercentLength . toDevicePixels ( this . paddingLeft , 0 , availableWidth ) + parent . effectiveBorderLeftWidth ) ;
256- const paddingRight = Utils . layout . toDeviceIndependentPixels ( parent . effectivePaddingRight + PercentLength . toDevicePixels ( this . paddingRight , 0 , availableWidth ) + parent . effectiveBorderRightWidth ) ;
257- const paddingTop = Utils . layout . toDeviceIndependentPixels ( parent . effectivePaddingTop + PercentLength . toDevicePixels ( this . paddingTop , 0 , availableHeight ) + parent . effectiveBorderTopWidth ) ;
258- const paddingBottom = Utils . layout . toDeviceIndependentPixels ( parent . effectivePaddingBottom + PercentLength . toDevicePixels ( this . paddingBottom , 0 , availableHeight ) + parent . effectiveBorderBottomWidth ) ;
259- canvas . save ( ) ;
263+ const paddingLeft = Utils . layout . toDeviceIndependentPixels (
264+ parent . effectivePaddingLeft + PercentLength . toDevicePixels ( this . paddingLeft , 0 , availableWidth ) + parent . effectiveBorderLeftWidth
265+ ) ;
266+ const paddingRight = Utils . layout . toDeviceIndependentPixels (
267+ parent . effectivePaddingRight + PercentLength . toDevicePixels ( this . paddingRight , 0 , availableWidth ) + parent . effectiveBorderRightWidth
268+ ) ;
269+ const paddingTop = Utils . layout . toDeviceIndependentPixels ( parent . effectivePaddingTop + PercentLength . toDevicePixels ( this . paddingTop , 0 , availableHeight ) + parent . effectiveBorderTopWidth ) ;
270+ const paddingBottom = Utils . layout . toDeviceIndependentPixels (
271+ parent . effectivePaddingBottom + PercentLength . toDevicePixels ( this . paddingBottom , 0 , availableHeight ) + parent . effectiveBorderBottomWidth
272+ ) ;
260273 if ( paddingLeft > 0 ) {
261- canvas . translate ( paddingLeft , 0 ) ;
274+ dx += paddingLeft ;
262275 }
263276 if ( this . horizontalAlignment && this . horizontalAlignment !== 'left' && paddingRight > 0 ) {
264- canvas . translate ( - paddingRight , 0 ) ;
277+ dx -= paddingRight ;
265278 }
266279 if ( paddingTop > 0 ) {
267- canvas . translate ( 0 , paddingTop ) ;
280+ dy += paddingTop ;
268281 }
269282 if ( this . verticalAlignment && this . verticalAlignment !== 'top' && paddingBottom > 0 ) {
270- canvas . translate ( 0 , - paddingBottom ) ;
283+ dy -= paddingBottom ;
271284 }
272285 if ( this . horizontalAlignment === 'right' ) {
273286 const sWidth = this . getWidth ( availableWidth , availableHeight ) ;
274- canvas . translate ( width - sWidth , 0 ) ;
287+ dx += width - sWidth ;
275288 } else if ( this . horizontalAlignment === 'center' || this . horizontalAlignment === 'middle' ) {
276289 const sWidth = this . getWidth ( availableWidth , availableHeight ) ;
277- canvas . translate ( width / 2 - sWidth / 2 , 0 ) ;
290+ dx += width / 2 - sWidth / 2 ;
278291 }
279292 if ( this . verticalAlignment === 'bottom' ) {
280293 const sHeight = this . getHeight ( availableWidth , availableHeight ) ;
281- canvas . translate ( 0 , height - sHeight ) ;
294+ dy += height - sHeight ;
282295 } else if ( this . verticalAlignment === 'center' || this . verticalAlignment === 'middle' ) {
283296 const sHeight = this . getHeight ( availableWidth , availableHeight ) ;
284- canvas . translate ( 0 , height / 2 - sHeight / 2 ) ;
297+ dy += height / 2 - sHeight / 2 ;
285298 }
286299 }
300+ const needsSave = dx !== 0 || dy !== 0 || this . rotate !== 0 ;
301+ if ( needsSave ) {
302+ canvas . save ( ) ;
303+ }
304+ if ( dx !== 0 || dy !== 0 ) {
305+ canvas . translate ( dx , dy ) ;
306+ }
307+ if ( this . rotate !== 0 ) {
308+ canvas . rotate ( this . rotate ) ;
309+ }
310+ if ( this . scaleX !== 1 || this . scaleY !== 1 ) {
311+ canvas . scale ( this . scaleX , this . scaleY ) ;
312+ }
287313
288314 const paint = this . paint ;
289315 // console.log('drawMyShapeOnCanvas', paint.getColor(), this.strokeColor, this.fillColor);
@@ -315,7 +341,7 @@ export default abstract class Shape extends Observable {
315341 } else {
316342 this . drawOnCanvas ( canvas , parent ) ;
317343 }
318- if ( ! this . handleAlignment ) {
344+ if ( needsSave ) {
319345 canvas . restore ( ) ;
320346 }
321347 }
0 commit comments