diff --git a/projects/demo/src/app/app.component.ts b/projects/demo/src/app/app.component.ts
index 75931e6..a299457 100644
--- a/projects/demo/src/app/app.component.ts
+++ b/projects/demo/src/app/app.component.ts
@@ -23,5 +23,6 @@ export class AppComponent {
{ label: 'Shapes', route: 'shapes' },
{ label: 'Star', route: 'star' },
{ label: 'Styles', route: 'styles' },
+ { label: 'Transform', route: 'transform' },
];
}
diff --git a/projects/demo/src/app/app.routes.ts b/projects/demo/src/app/app.routes.ts
index 8d82b07..4fdd9af 100644
--- a/projects/demo/src/app/app.routes.ts
+++ b/projects/demo/src/app/app.routes.ts
@@ -39,5 +39,12 @@ export const routes: Routes = [
(c) => c.StylesExampleComponent
),
},
+ {
+ path: 'transform',
+ loadComponent: () =>
+ import('./examples/transform.component').then(
+ (c) => c.TransformExampleComponent
+ ),
+ },
{ path: '**', pathMatch: 'full', redirectTo: 'animation' },
];
diff --git a/projects/demo/src/app/examples/transform.component.ts b/projects/demo/src/app/examples/transform.component.ts
new file mode 100644
index 0000000..ba46e45
--- /dev/null
+++ b/projects/demo/src/app/examples/transform.component.ts
@@ -0,0 +1,108 @@
+import { AfterViewInit, Component, ViewChild } from '@angular/core';
+import { CoreShapeComponent, StageComponent } from 'ng2-konva';
+import { StageConfig } from 'konva/lib/Stage';
+import { Rect, RectConfig } from 'konva/lib/shapes/Rect';
+import { TextConfig } from 'konva/lib/shapes/Text';
+import { Transformer } from 'konva/lib/shapes/Transformer';
+
+@Component({
+ selector: 'app-transform-example',
+ template: `
+
+
+ `,
+ standalone: true,
+ imports: [CoreShapeComponent, StageComponent],
+})
+export class TransformExampleComponent implements AfterViewInit {
+ @ViewChild('rect') rect: CoreShapeComponent;
+ @ViewChild('transformer') transformer: CoreShapeComponent;
+
+ public configStage: Partial = {
+ width: 500,
+ height: 400,
+ };
+
+ public configRect: RectConfig = {
+ width: 100,
+ height: 100,
+ x: 200,
+ y: 150,
+ fill: 'red',
+ stroke: 'black',
+ strokeWidth: 4,
+ name: 'rect',
+ draggable: true,
+ };
+
+ public configText: TextConfig = {
+ x: 10,
+ y: 10,
+ fontFamily: 'Calibri',
+ fontSize: 24,
+ text: '',
+ fill: 'black',
+ };
+
+ private initialSize = {
+ width: 100,
+ height: 100,
+ };
+
+ ngAfterViewInit(): void {
+ const rect = this.rect.getStage() as Rect;
+ const transformer = this.transformer.getStage() as Transformer;
+ transformer.nodes([rect]);
+ }
+
+ handleTransformStart(): void {
+ const rect = this.transformer.getStage();
+ this.initialSize = {
+ width: Math.round(rect.width()),
+ height: Math.round(rect.height()),
+ };
+ this.writeMessage(
+ `Initial: ${this.initialSize.width}x${this.initialSize.height}`
+ );
+ }
+
+ handleTransform(): void {
+ const rect = this.transformer.getStage();
+
+ const currentWidth = Math.round(rect.width());
+ const currentHeight = Math.round(rect.height());
+
+ this.writeMessage(
+ `Initial: ${this.initialSize.width}x${this.initialSize.height}
+Current: ${currentWidth}x${currentHeight}`
+ );
+ }
+
+ handleTransformEnd(): void {
+ const rect = this.transformer.getStage();
+
+ const currentWidth = Math.round(rect.width());
+ const currentHeight = Math.round(rect.height());
+
+ this.writeMessage(`Current: ${currentWidth}x${currentHeight}`);
+ }
+
+ writeMessage(message: string): void {
+ this.configText = { ...this.configText, text: message };
+ }
+}
diff --git a/projects/ng2-konva/src/lib/components/core-shape.component.ts b/projects/ng2-konva/src/lib/components/core-shape.component.ts
index c8c67e2..ea1effe 100644
--- a/projects/ng2-konva/src/lib/components/core-shape.component.ts
+++ b/projects/ng2-konva/src/lib/components/core-shape.component.ts
@@ -99,6 +99,12 @@ export class CoreShapeComponent
new EventEmitter>();
@Output() dragend: EventEmitter> =
new EventEmitter>();
+ @Output() transformstart: EventEmitter> =
+ new EventEmitter>();
+ @Output() transform: EventEmitter> =
+ new EventEmitter>();
+ @Output() transformend: EventEmitter> =
+ new EventEmitter>();
public nameNode: keyof typeof ShapeTypes | 'Shape' | 'Sprite' = getName(
inject(ElementRef).nativeElement.localName
diff --git a/projects/ng2-konva/src/lib/interfaces/ko-component.interface.ts b/projects/ng2-konva/src/lib/interfaces/ko-component.interface.ts
index 48d5b10..91e08d4 100644
--- a/projects/ng2-konva/src/lib/interfaces/ko-component.interface.ts
+++ b/projects/ng2-konva/src/lib/interfaces/ko-component.interface.ts
@@ -71,4 +71,7 @@ export abstract class KonvaComponent extends Component {
dragstart?: EventEmitter>;
dragmove?: EventEmitter>;
dragend?: EventEmitter>;
+ transformstart?: EventEmitter>;
+ transform?: EventEmitter>;
+ transformend?: EventEmitter>;
}
diff --git a/projects/ng2-konva/src/lib/utils/index.ts b/projects/ng2-konva/src/lib/utils/index.ts
index 4839183..965fa6e 100644
--- a/projects/ng2-konva/src/lib/utils/index.ts
+++ b/projects/ng2-konva/src/lib/utils/index.ts
@@ -3,6 +3,7 @@ import applyNodeProps from './applyNodeProps';
import { KonvaComponent } from '../interfaces/ko-component.interface';
import { EventEmitter } from '@angular/core';
import { ListenerRecord } from './types';
+import { StageComponent } from '../components/stage.component';
function camelize(str: string): string {
return str
@@ -23,6 +24,12 @@ export function getName(componentTag: string): string {
}
export function createListener(instance: KonvaComponent): ListenerRecord {
+ const unsupportedStageEvents: string[] = [
+ 'transformstart',
+ 'transform',
+ 'transformend',
+ ];
+
const output: ListenerRecord = {};
[
'mouseover',
@@ -44,9 +51,19 @@ export function createListener(instance: KonvaComponent): ListenerRecord {
'dragstart',
'dragmove',
'dragend',
+ 'transformstart',
+ 'transform',
+ 'transformend',
].forEach((eventName) => {
const name: keyof KonvaComponent = eventName;
+ if (
+ instance instanceof StageComponent &&
+ unsupportedStageEvents.includes(name)
+ ) {
+ return;
+ }
+
const eventEmitter: EventEmitter = >(
instance[name]
);