ngx-image-cropper 8.1.1 → 9.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { signal, EventEmitter, Component, ChangeDetectionStrategy, ViewChild, Input, HostBinding, Output, HostListener } from '@angular/core';
2
+ import { signal, output, Component, ChangeDetectionStrategy, ViewChild, Input, HostBinding, HostListener } from '@angular/core';
3
3
  import { takeUntil, first } from 'rxjs/operators';
4
4
  import { Subject, merge, fromEvent } from 'rxjs';
5
5
  import { NgIf } from '@angular/common';
@@ -82,7 +82,7 @@ function moveCropper(event, moveStart) {
82
82
  };
83
83
  }
84
84
  function resizeCropper(event, moveStart, cropperState) {
85
- const cropperPosition = { ...cropperState.cropper };
85
+ const cropperPosition = { ...cropperState.cropper() };
86
86
  const moveX = getClientX(event) - moveStart.clientX;
87
87
  const moveY = getClientY(event) - moveStart.clientY;
88
88
  switch (moveStart.position) {
@@ -246,6 +246,8 @@ function getClientY(event) {
246
246
 
247
247
  class CropperState {
248
248
  constructor() {
249
+ this.cropper = signal({ x1: 0, x2: 0, y1: 0, y2: 0 });
250
+ this.transform = {};
249
251
  this.options = {
250
252
  format: 'png',
251
253
  output: 'blob',
@@ -272,8 +274,6 @@ class CropperState {
272
274
  cropperFrameAriaLabel: undefined,
273
275
  checkImageType: true
274
276
  };
275
- this.cropper = { x1: 0, x2: 0, y1: 0, y2: 0 };
276
- this.transform = {};
277
277
  // Internal
278
278
  this.cropperScaledMinWidth = 20;
279
279
  this.cropperScaledMinHeight = 20;
@@ -309,7 +309,7 @@ class CropperState {
309
309
  this.setCropperScaledMinSize();
310
310
  this.setCropperScaledMaxSize();
311
311
  if (this.options.maintainAspectRatio && (this.options.resetCropOnAspectRatioChange || !this.aspectRatioIsCorrect())) {
312
- this.cropper = this.maxSizeCropperPosition();
312
+ this.cropper.set(this.maxSizeCropperPosition());
313
313
  positionPossiblyChanged = true;
314
314
  }
315
315
  }
@@ -327,7 +327,7 @@ class CropperState {
327
327
  }
328
328
  }
329
329
  if (positionPossiblyChanged) {
330
- this.cropper = checkCropperPosition(this.cropper, this, false);
330
+ this.cropper.update((cropper) => checkCropperPosition(cropper, this, false));
331
331
  }
332
332
  }
333
333
  validateOptions() {
@@ -386,12 +386,13 @@ class CropperState {
386
386
  }
387
387
  }
388
388
  equalsCropperPosition(cropper) {
389
- return this.cropper == null && cropper == null
390
- || this.cropper != null && cropper != null
391
- && this.cropper.x1.toFixed(3) === cropper.x1.toFixed(3)
392
- && this.cropper.y1.toFixed(3) === cropper.y1.toFixed(3)
393
- && this.cropper.x2.toFixed(3) === cropper.x2.toFixed(3)
394
- && this.cropper.y2.toFixed(3) === cropper.y2.toFixed(3);
389
+ const localCropper = this.cropper();
390
+ return localCropper == null && cropper == null
391
+ || localCropper != null && cropper != null
392
+ && localCropper.x1.toFixed(3) === cropper.x1.toFixed(3)
393
+ && localCropper.y1.toFixed(3) === cropper.y1.toFixed(3)
394
+ && localCropper.x2.toFixed(3) === cropper.x2.toFixed(3)
395
+ && localCropper.y2.toFixed(3) === cropper.y2.toFixed(3);
395
396
  }
396
397
  equalsTransformTranslate(transform) {
397
398
  return (this.transform.translateH ?? 0) === (transform.translateH ?? 0)
@@ -405,20 +406,18 @@ class CropperState {
405
406
  && (this.transform.flipV ?? false) === (transform.flipV ?? false);
406
407
  }
407
408
  aspectRatioIsCorrect() {
408
- const currentCropAspectRatio = (this.cropper.x2 - this.cropper.x1) / (this.cropper.y2 - this.cropper.y1);
409
+ const localCropper = this.cropper();
410
+ const currentCropAspectRatio = (localCropper.x2 - localCropper.x1) / (localCropper.y2 - localCropper.y1);
409
411
  return currentCropAspectRatio === this.options.aspectRatio;
410
412
  }
411
413
  resizeCropperPosition(oldMaxSize) {
412
- if (!this.cropper) {
413
- return;
414
- }
415
414
  if (oldMaxSize.width !== this.maxSize.width || oldMaxSize.height !== this.maxSize.height) {
416
- this.cropper = {
417
- x1: this.cropper.x1 * this.maxSize.width / oldMaxSize.width,
418
- x2: this.cropper.x2 * this.maxSize.width / oldMaxSize.width,
419
- y1: this.cropper.y1 * this.maxSize.height / oldMaxSize.height,
420
- y2: this.cropper.y2 * this.maxSize.height / oldMaxSize.height
421
- };
415
+ this.cropper.update(cropper => ({
416
+ x1: cropper.x1 * this.maxSize.width / oldMaxSize.width,
417
+ x2: cropper.x2 * this.maxSize.width / oldMaxSize.width,
418
+ y1: cropper.y1 * this.maxSize.height / oldMaxSize.height,
419
+ y2: cropper.y2 * this.maxSize.height / oldMaxSize.height
420
+ }));
422
421
  }
423
422
  }
424
423
  maxSizeCropperPosition() {
@@ -545,7 +544,7 @@ class CropService {
545
544
  const result = {
546
545
  width, height,
547
546
  imagePosition,
548
- cropperPosition: { ...cropperState.cropper }
547
+ cropperPosition: { ...cropperState.cropper() }
549
548
  };
550
549
  if (cropperState.options.containWithinAspectRatio) {
551
550
  result.offsetImagePosition = this.getOffsetImagePosition(cropperState);
@@ -593,11 +592,12 @@ class CropService {
593
592
  }
594
593
  getImagePosition(cropperState) {
595
594
  const ratio = this.getRatio(cropperState);
595
+ const cropper = cropperState.cropper();
596
596
  const out = {
597
- x1: Math.round(cropperState.cropper.x1 * ratio),
598
- y1: Math.round(cropperState.cropper.y1 * ratio),
599
- x2: Math.round(cropperState.cropper.x2 * ratio),
600
- y2: Math.round(cropperState.cropper.y2 * ratio)
597
+ x1: Math.round(cropper.x1 * ratio),
598
+ y1: Math.round(cropper.y1 * ratio),
599
+ x2: Math.round(cropper.x2 * ratio),
600
+ y2: Math.round(cropper.y2 * ratio)
601
601
  };
602
602
  if (!cropperState.options.containWithinAspectRatio) {
603
603
  out.x1 = Math.max(out.x1, 0);
@@ -620,11 +620,12 @@ class CropService {
620
620
  offsetX = (cropperState.loadedImage.transformed.size.width - cropperState.loadedImage.original.size.width) / 2;
621
621
  offsetY = (cropperState.loadedImage.transformed.size.height - cropperState.loadedImage.original.size.height) / 2;
622
622
  }
623
+ const cropper = cropperState.cropper();
623
624
  const out = {
624
- x1: Math.round(cropperState.cropper.x1 * ratio) - offsetX,
625
- y1: Math.round(cropperState.cropper.y1 * ratio) - offsetY,
626
- x2: Math.round(cropperState.cropper.x2 * ratio) - offsetX,
627
- y2: Math.round(cropperState.cropper.y2 * ratio) - offsetY
625
+ x1: Math.round(cropper.x1 * ratio) - offsetX,
626
+ y1: Math.round(cropper.y1 * ratio) - offsetY,
627
+ x2: Math.round(cropper.x2 * ratio) - offsetX,
628
+ y2: Math.round(cropper.y2 * ratio) - offsetY
628
629
  };
629
630
  if (!cropperState.options.containWithinAspectRatio) {
630
631
  out.x1 = Math.max(out.x1, 0);
@@ -973,10 +974,8 @@ class ImageCropperComponent {
973
974
  get alignImageStyle() {
974
975
  return this.state.options.alignImage;
975
976
  }
976
- constructor(sanitizer, cd, zone) {
977
+ constructor(sanitizer) {
977
978
  this.sanitizer = sanitizer;
978
- this.cd = cd;
979
- this.zone = zone;
980
979
  this.pinchStart$ = new Subject();
981
980
  this.cropService = new CropService();
982
981
  this.loadImageService = new LoadImageService();
@@ -985,26 +984,27 @@ class ImageCropperComponent {
985
984
  this.moveTypes = MoveTypes;
986
985
  this.state = new CropperState();
987
986
  this.safeImgDataUrl = signal(undefined);
987
+ this.safeTransformStyle = signal(undefined);
988
988
  this.marginLeft = '0px';
989
989
  this.imageVisible = false;
990
990
  this.allowMoveImage = false;
991
991
  this.checkImageType = true;
992
992
  this.disabled = false;
993
993
  this.hidden = false;
994
- this.imageCropped = new EventEmitter();
995
- this.startCropImage = new EventEmitter();
996
- this.imageLoaded = new EventEmitter();
997
- this.cropperReady = new EventEmitter();
998
- this.loadImageFailed = new EventEmitter();
999
- this.transformChange = new EventEmitter();
1000
- this.cropperChange = new EventEmitter();
994
+ this.imageCropped = output();
995
+ this.startCropImage = output();
996
+ this.imageLoaded = output();
997
+ this.cropperReady = output();
998
+ this.loadImageFailed = output();
999
+ this.transformChange = output();
1000
+ this.cropperChange = output();
1001
1001
  this.reset();
1002
1002
  }
1003
1003
  ngOnInit() {
1004
1004
  this.state.stepSize = this.initialStepSize || this.state.stepSize;
1005
1005
  }
1006
1006
  ngOnChanges(changes) {
1007
- const previousCropperPosition = this.state.cropper;
1007
+ const previousCropperPosition = this.state.cropper();
1008
1008
  const previousTransform = this.state.transform;
1009
1009
  const previousBackgroundColor = this.state.options.backgroundColor;
1010
1010
  this.state.setOptionsFromChanges(changes);
@@ -1024,11 +1024,11 @@ class ImageCropperComponent {
1024
1024
  return;
1025
1025
  }
1026
1026
  if (changes['cropper'] && this.cropper) {
1027
- this.state.cropper = checkCropperPosition(this.cropper, this.state, true);
1027
+ this.state.cropper.set(checkCropperPosition(this.cropper, this.state, true));
1028
1028
  }
1029
1029
  const cropperChanged = !this.state.equalsCropperPosition(previousCropperPosition);
1030
1030
  if (cropperChanged && (!this.cropper || !this.state.equalsCropperPosition(this.cropper))) {
1031
- this.cropperChange.emit(this.state.cropper);
1031
+ this.cropperChange.emit(this.state.cropper());
1032
1032
  }
1033
1033
  if (cropperChanged
1034
1034
  || !this.state.equalsTransform(previousTransform)
@@ -1099,10 +1099,10 @@ class ImageCropperComponent {
1099
1099
  }
1100
1100
  setCssTransform() {
1101
1101
  const translateUnit = this.state.transform?.translateUnit || '%';
1102
- this.safeTransformStyle = this.sanitizer.bypassSecurityTrustStyle(`translate(${this.state.transform.translateH || 0}${translateUnit}, ${this.state.transform.translateV || 0}${translateUnit})` +
1102
+ this.safeTransformStyle.set(this.sanitizer.bypassSecurityTrustStyle(`translate(${this.state.transform.translateH || 0}${translateUnit}, ${this.state.transform.translateV || 0}${translateUnit})` +
1103
1103
  ' scaleX(' + (this.state.transform.scale || 1) * (this.state.transform.flipH ? -1 : 1) + ')' +
1104
1104
  ' scaleY(' + (this.state.transform.scale || 1) * (this.state.transform.flipV ? -1 : 1) + ')' +
1105
- ' rotate(' + (this.state.transform.rotate || 0) + 'deg)');
1105
+ ' rotate(' + (this.state.transform.rotate || 0) + 'deg)'));
1106
1106
  }
1107
1107
  imageLoadedInView() {
1108
1108
  if (this.state.loadedImage != null) {
@@ -1118,17 +1118,16 @@ class ImageCropperComponent {
1118
1118
  else if (this.sourceImageLoaded()) {
1119
1119
  this.setMaxSize();
1120
1120
  if (this.cropper && (!this.maintainAspectRatio || this.state.aspectRatioIsCorrect())) {
1121
- this.state.cropper = checkCropperPosition(this.cropper, this.state, true);
1121
+ this.state.cropper.set(checkCropperPosition(this.cropper, this.state, true));
1122
1122
  this.emitCropperPositionChange(this.cropper);
1123
1123
  }
1124
1124
  else {
1125
- this.state.cropper = checkCropperPosition(this.state.maxSizeCropperPosition(), this.state, true);
1126
- this.cropperChange.emit(this.state.cropper);
1125
+ this.state.cropper.set(checkCropperPosition(this.state.maxSizeCropperPosition(), this.state, true));
1126
+ this.cropperChange.emit(this.state.cropper());
1127
1127
  }
1128
1128
  this.imageVisible = true;
1129
1129
  this.cropperReady.emit({ ...this.state.maxSize });
1130
1130
  this.doAutoCrop();
1131
- this.cd.markForCheck();
1132
1131
  }
1133
1132
  else {
1134
1133
  this.setImageMaxSizeRetries++;
@@ -1149,7 +1148,6 @@ class ImageCropperComponent {
1149
1148
  const oldMaxSize = { ...this.state.maxSize };
1150
1149
  this.setMaxSize();
1151
1150
  this.state.resizeCropperPosition(oldMaxSize);
1152
- this.cd.markForCheck();
1153
1151
  }
1154
1152
  }
1155
1153
  keyboardAccess(event) {
@@ -1173,20 +1171,19 @@ class ImageCropperComponent {
1173
1171
  event.preventDefault();
1174
1172
  event.stopPropagation();
1175
1173
  this.moveStart = {
1176
- active: true,
1177
1174
  type: moveType,
1178
1175
  position,
1179
1176
  clientX: 0,
1180
1177
  clientY: 0,
1181
1178
  transform: this.state.transform,
1182
- cropper: this.state.cropper
1179
+ cropper: this.state.cropper()
1183
1180
  };
1184
1181
  this.handleMouseMove(moveEvent);
1185
1182
  this.handleMouseUp();
1186
1183
  }
1187
1184
  startMove(event, moveType, position = null) {
1188
1185
  if (this.disabled
1189
- || this.moveStart?.active && this.moveStart?.type === MoveTypes.Pinch
1186
+ || this.moveStart && this.moveStart.type === MoveTypes.Pinch
1190
1187
  || moveType === MoveTypes.Drag && !this.allowMoveImage) {
1191
1188
  return;
1192
1189
  }
@@ -1194,30 +1191,23 @@ class ImageCropperComponent {
1194
1191
  event.preventDefault();
1195
1192
  }
1196
1193
  this.moveStart = {
1197
- active: true,
1198
1194
  type: moveType,
1199
1195
  position,
1200
1196
  clientX: getClientX(event),
1201
1197
  clientY: getClientY(event),
1202
1198
  transform: this.state.transform,
1203
- cropper: this.state.cropper
1199
+ cropper: this.state.cropper()
1204
1200
  };
1205
1201
  this.initMouseMove();
1206
1202
  }
1207
1203
  initMouseMove() {
1208
1204
  merge(fromEvent(document, 'mousemove'), fromEvent(document, 'touchmove')).pipe(takeUntil(merge(fromEvent(document, 'mouseup'), fromEvent(document, 'touchend'), this.pinchStart$).pipe(first()))).subscribe({
1209
- next: (event) => this.zone.run(() => {
1210
- this.handleMouseMove(event);
1211
- this.cd.markForCheck();
1212
- }),
1213
- complete: () => this.zone.run(() => {
1214
- this.handleMouseUp();
1215
- this.cd.markForCheck();
1216
- })
1205
+ next: (event) => this.handleMouseMove(event),
1206
+ complete: () => this.handleMouseUp()
1217
1207
  });
1218
1208
  }
1219
1209
  handleMouseMove(event) {
1220
- if (!this.moveStart?.active) {
1210
+ if (!this.moveStart) {
1221
1211
  return;
1222
1212
  }
1223
1213
  if ('stopPropagation' in event) {
@@ -1227,11 +1217,11 @@ class ImageCropperComponent {
1227
1217
  event.preventDefault();
1228
1218
  }
1229
1219
  if (this.moveStart.type === MoveTypes.Move) {
1230
- this.state.cropper = checkCropperWithinMaxSizeBounds(moveCropper(event, this.moveStart), this.state, true);
1220
+ this.state.cropper.set(checkCropperWithinMaxSizeBounds(moveCropper(event, this.moveStart), this.state, true));
1231
1221
  }
1232
1222
  else if (this.moveStart.type === MoveTypes.Resize) {
1233
1223
  if (!this.cropperStaticWidth && !this.cropperStaticHeight) {
1234
- this.state.cropper = checkCropperWithinMaxSizeBounds(resizeCropper(event, this.moveStart, this.state), this.state, false);
1224
+ this.state.cropper.set(checkCropperWithinMaxSizeBounds(resizeCropper(event, this.moveStart, this.state), this.state, false));
1235
1225
  }
1236
1226
  }
1237
1227
  else if (this.moveStart.type === MoveTypes.Drag) {
@@ -1246,15 +1236,16 @@ class ImageCropperComponent {
1246
1236
  }
1247
1237
  }
1248
1238
  handleMouseUp() {
1249
- if (!this.moveStart?.active || this.moveStart?.type === MoveTypes.Pinch) {
1239
+ if (!this.moveStart || this.moveStart.type === MoveTypes.Pinch) {
1250
1240
  return;
1251
1241
  }
1252
- if (!this.state.equalsCropperPosition(this.moveStart.cropper) || this.moveStart.transform && !this.state.equalsTransform(this.moveStart.transform)) {
1242
+ if (!this.state.equalsCropperPosition(this.moveStart.cropper)
1243
+ || this.moveStart.transform && !this.state.equalsTransform(this.moveStart.transform)) {
1253
1244
  if (this.moveStart.type === MoveTypes.Drag) {
1254
1245
  this.transformChange.emit(this.state.transform);
1255
1246
  }
1256
1247
  else {
1257
- this.cropperChange.emit(this.state.cropper);
1248
+ this.cropperChange.emit(this.state.cropper());
1258
1249
  }
1259
1250
  this.doAutoCrop();
1260
1251
  }
@@ -1267,13 +1258,13 @@ class ImageCropperComponent {
1267
1258
  if ('preventDefault' in event) {
1268
1259
  event.preventDefault();
1269
1260
  }
1261
+ const cropper = this.state.cropper();
1270
1262
  this.moveStart = {
1271
- active: true,
1272
1263
  type: MoveTypes.Pinch,
1273
1264
  position: 'center',
1274
- clientX: this.state.cropper.x1 + (this.state.cropper.x2 - this.state.cropper.x1) / 2,
1275
- clientY: this.state.cropper.y1 + (this.state.cropper.y2 - this.state.cropper.y1) / 2,
1276
- cropper: this.state.cropper
1265
+ clientX: cropper.x1 + (cropper.x2 - cropper.x1) / 2,
1266
+ clientY: cropper.y1 + (cropper.y2 - cropper.y1) / 2,
1267
+ cropper: cropper
1277
1268
  };
1278
1269
  this.initPinch();
1279
1270
  }
@@ -1282,18 +1273,12 @@ class ImageCropperComponent {
1282
1273
  fromEvent(document, 'touchmove')
1283
1274
  .pipe(takeUntil(fromEvent(document, 'touchend')))
1284
1275
  .subscribe({
1285
- next: (event) => this.zone.run(() => {
1286
- this.handlePinchMove(event);
1287
- this.cd.markForCheck();
1288
- }),
1289
- complete: () => this.zone.run(() => {
1290
- this.handlePinchStop();
1291
- this.cd.markForCheck();
1292
- })
1276
+ next: (event) => this.handlePinchMove(event),
1277
+ complete: () => this.handlePinchStop()
1293
1278
  });
1294
1279
  }
1295
1280
  handlePinchMove(event) {
1296
- if (!this.moveStart?.active) {
1281
+ if (!this.moveStart) {
1297
1282
  return;
1298
1283
  }
1299
1284
  if (event.preventDefault) {
@@ -1301,13 +1286,12 @@ class ImageCropperComponent {
1301
1286
  }
1302
1287
  if (this.moveStart.type === MoveTypes.Pinch) {
1303
1288
  if (!this.cropperStaticWidth && !this.cropperStaticHeight) {
1304
- this.state.cropper = checkCropperWithinMaxSizeBounds(resizeCropper(event, this.moveStart, this.state), this.state, false);
1289
+ this.state.cropper.set(checkCropperWithinMaxSizeBounds(resizeCropper(event, this.moveStart, this.state), this.state, false));
1305
1290
  }
1306
1291
  }
1307
- this.cd.markForCheck();
1308
1292
  }
1309
1293
  handlePinchStop() {
1310
- if (!this.moveStart?.active) {
1294
+ if (!this.moveStart) {
1311
1295
  return;
1312
1296
  }
1313
1297
  if (!this.state.equalsCropperPosition(this.moveStart.cropper)) {
@@ -1325,7 +1309,7 @@ class ImageCropperComponent {
1325
1309
  }
1326
1310
  emitCropperPositionChange(previousPosition) {
1327
1311
  if (!this.state.equalsCropperPosition(previousPosition)) {
1328
- this.cropperChange.emit(this.state.cropper);
1312
+ this.cropperChange.emit(this.state.cropper());
1329
1313
  }
1330
1314
  }
1331
1315
  doAutoCrop() {
@@ -1346,7 +1330,7 @@ class ImageCropperComponent {
1346
1330
  return null;
1347
1331
  }
1348
1332
  cropToBlob() {
1349
- return new Promise((resolve, reject) => this.zone.run(async () => {
1333
+ return new Promise(async (resolve, reject) => {
1350
1334
  const result = await this.cropService.crop(this.state, 'blob');
1351
1335
  if (result) {
1352
1336
  this.imageCropped.emit(result);
@@ -1355,7 +1339,7 @@ class ImageCropperComponent {
1355
1339
  else {
1356
1340
  reject('Crop image failed');
1357
1341
  }
1358
- }));
1342
+ });
1359
1343
  }
1360
1344
  cropToBase64() {
1361
1345
  const result = this.cropService.crop(this.state, 'base64');
@@ -1366,19 +1350,19 @@ class ImageCropperComponent {
1366
1350
  return null;
1367
1351
  }
1368
1352
  resetCropperPosition() {
1369
- this.state.cropper = checkCropperPosition(this.state.maxSizeCropperPosition(), this.state, true);
1370
- this.cropperChange.emit(this.state.cropper);
1353
+ this.state.cropper.set(checkCropperPosition(this.state.maxSizeCropperPosition(), this.state, true));
1354
+ this.cropperChange.emit(this.state.cropper());
1371
1355
  }
1372
1356
  ngOnDestroy() {
1373
1357
  this.pinchStart$.complete();
1374
1358
  }
1375
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ImageCropperComponent, deps: [{ token: i1.DomSanitizer }, { token: i0.ChangeDetectorRef }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component }); }
1376
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: ImageCropperComponent, isStandalone: true, selector: "image-cropper", inputs: { imageChangedEvent: "imageChangedEvent", imageURL: "imageURL", imageBase64: "imageBase64", imageFile: "imageFile", imageAltText: "imageAltText", options: "options", cropperFrameAriaLabel: "cropperFrameAriaLabel", output: "output", format: "format", autoCrop: "autoCrop", cropper: "cropper", transform: "transform", maintainAspectRatio: "maintainAspectRatio", aspectRatio: "aspectRatio", resetCropOnAspectRatioChange: "resetCropOnAspectRatioChange", resizeToWidth: "resizeToWidth", resizeToHeight: "resizeToHeight", cropperMinWidth: "cropperMinWidth", cropperMinHeight: "cropperMinHeight", cropperMaxHeight: "cropperMaxHeight", cropperMaxWidth: "cropperMaxWidth", cropperStaticWidth: "cropperStaticWidth", cropperStaticHeight: "cropperStaticHeight", canvasRotation: "canvasRotation", initialStepSize: "initialStepSize", roundCropper: "roundCropper", onlyScaleDown: "onlyScaleDown", imageQuality: "imageQuality", backgroundColor: "backgroundColor", containWithinAspectRatio: "containWithinAspectRatio", hideResizeSquares: "hideResizeSquares", allowMoveImage: "allowMoveImage", checkImageType: "checkImageType", alignImage: "alignImage", disabled: "disabled", hidden: "hidden" }, outputs: { imageCropped: "imageCropped", startCropImage: "startCropImage", imageLoaded: "imageLoaded", cropperReady: "cropperReady", loadImageFailed: "loadImageFailed", transformChange: "transformChange", cropperChange: "cropperChange" }, host: { listeners: { "window:resize": "onResize()" }, properties: { "class.disabled": "this.disabled", "class.ngx-ic-hidden": "this.hidden", "style.text-align": "this.alignImageStyle" } }, viewQueries: [{ propertyName: "wrapper", first: true, predicate: ["wrapper"], descendants: true, static: true }, { propertyName: "sourceImage", first: true, predicate: ["sourceImage"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div\n [style.background]=\"imageVisible && state.options.backgroundColor\"\n (touchstart)=\"startPinch($event)\"\n>\n <img\n #sourceImage\n class=\"ngx-ic-source-image\"\n role=\"presentation\"\n *ngIf=\"safeImgDataUrl() as src\"\n [src]=\"src\"\n [style.visibility]=\"imageVisible ? 'visible' : 'hidden'\"\n [style.transform]=\"safeTransformStyle\"\n [class.ngx-ic-draggable]=\"!disabled && allowMoveImage\"\n [attr.alt]=\"imageAltText\"\n (load)=\"imageLoadedInView()\"\n (mousedown)=\"startMove($event, moveTypes.Drag)\"\n (touchstart)=\"startMove($event, moveTypes.Drag)\"\n (error)=\"loadImageError($event)\"\n >\n <div\n class=\"ngx-ic-overlay\"\n [style.width.px]=\"state.maxSize?.width || 0\"\n [style.height.px]=\"state.maxSize?.height || 0\"\n [style.margin-left]=\"alignImage === 'center' ? marginLeft : null\"\n ></div>\n <div\n class=\"ngx-ic-cropper\"\n *ngIf=\"imageVisible\"\n [class.ngx-ic-round]=\"state.options.roundCropper\"\n [attr.aria-label]=\"state.options.cropperFrameAriaLabel\"\n [style.top.px]=\"state.cropper.y1\"\n [style.left.px]=\"state.cropper.x1\"\n [style.width.px]=\"state.cropper.x2 - state.cropper.x1\"\n [style.height.px]=\"state.cropper.y2 - state.cropper.y1\"\n [style.margin-left]=\"state.options.alignImage === 'center' ? marginLeft : null\"\n [style.visibility]=\"imageVisible ? 'visible' : 'hidden'\"\n (keydown)=\"keyboardAccess($event)\"\n tabindex=\"0\"\n >\n <div\n (mousedown)=\"startMove($event, moveTypes.Move)\"\n (touchstart)=\"startMove($event, moveTypes.Move)\"\n class=\"ngx-ic-move\"\n role=\"presentation\">\n </div>\n <ng-container\n *ngIf=\"!state.options.hideResizeSquares && !(state.options.cropperStaticWidth && state.options.cropperStaticHeight)\">\n <span\n class=\"ngx-ic-resize ngx-ic-topleft\"\n role=\"presentation\"\n (mousedown)=\"startMove($event, moveTypes.Resize, 'topleft')\"\n (touchstart)=\"startMove($event, moveTypes.Resize, 'topleft')\"\n >\n <span class=\"ngx-ic-square\"></span>\n </span>\n <span class=\"ngx-ic-resize ngx-ic-top\">\n <span class=\"ngx-ic-square\"></span>\n </span>\n <span\n class=\"ngx-ic-resize ngx-ic-topright\"\n role=\"presentation\"\n (mousedown)=\"startMove($event, moveTypes.Resize, 'topright')\"\n (touchstart)=\"startMove($event, moveTypes.Resize, 'topright')\"\n >\n <span class=\"ngx-ic-square\"></span>\n </span>\n <span class=\"ngx-ic-resize ngx-ic-right\">\n <span class=\"ngx-ic-square\"></span>\n </span>\n <span\n class=\"ngx-ic-resize ngx-ic-bottomright\"\n role=\"presentation\"\n (mousedown)=\"startMove($event, moveTypes.Resize, 'bottomright')\"\n (touchstart)=\"startMove($event, moveTypes.Resize, 'bottomright')\"\n >\n <span class=\"ngx-ic-square\"></span>\n </span>\n <span class=\"ngx-ic-resize ngx-ic-bottom\">\n <span class=\"ngx-ic-square\"></span>\n </span>\n <span\n class=\"ngx-ic-resize ngx-ic-bottomleft\"\n role=\"presentation\"\n (mousedown)=\"startMove($event, moveTypes.Resize, 'bottomleft')\"\n (touchstart)=\"startMove($event, moveTypes.Resize, 'bottomleft')\"\n >\n <span class=\"ngx-ic-square\"></span>\n </span>\n <span class=\"ngx-ic-resize ngx-ic-left\">\n <span class=\"ngx-ic-square\"></span>\n </span>\n <span\n class=\"ngx-ic-resize-bar ngx-ic-top\"\n role=\"presentation\"\n (mousedown)=\"startMove($event, moveTypes.Resize, 'top')\"\n (touchstart)=\"startMove($event, moveTypes.Resize, 'top')\"\n ></span>\n <span\n class=\"ngx-ic-resize-bar ngx-ic-right\"\n role=\"presentation\"\n (mousedown)=\"startMove($event, moveTypes.Resize, 'right')\"\n (touchstart)=\"startMove($event, moveTypes.Resize, 'right')\"\n ></span>\n <span\n class=\"ngx-ic-resize-bar ngx-ic-bottom\"\n role=\"presentation\"\n (mousedown)=\"startMove($event, moveTypes.Resize, 'bottom')\"\n (touchstart)=\"startMove($event, moveTypes.Resize, 'bottom')\"\n ></span>\n <span\n class=\"ngx-ic-resize-bar ngx-ic-left\"\n role=\"presentation\"\n (mousedown)=\"startMove($event, moveTypes.Resize, 'left')\"\n (touchstart)=\"startMove($event, moveTypes.Resize, 'left')\"\n ></span>\n </ng-container>\n </div>\n</div>\n", styles: [":host{display:flex;position:relative;width:100%;max-width:100%;max-height:100%;overflow:hidden;padding:5px;text-align:center}:host>div{width:100%;position:relative}:host>div img.ngx-ic-source-image{max-width:100%;max-height:100%;transform-origin:center}:host>div img.ngx-ic-source-image.ngx-ic-draggable{user-drag:none;-webkit-user-drag:none;user-select:none;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;cursor:grab}:host .ngx-ic-overlay{position:absolute;pointer-events:none;touch-action:none;outline:var(--cropper-overlay-color, white) solid 100vw;top:0;left:0}:host .ngx-ic-cropper{position:absolute;display:flex;color:#53535c;background:transparent;outline:rgba(255,255,255,.3) solid 100vw;outline:var(--cropper-outline-color, rgba(255, 255, 255, .3)) solid 100vw;touch-action:none}@media (orientation: portrait){:host .ngx-ic-cropper{outline-width:100vh}}:host .ngx-ic-cropper:after{position:absolute;content:\"\";inset:0;pointer-events:none;border:dashed 1px;opacity:.75;color:inherit;z-index:1}:host .ngx-ic-cropper .ngx-ic-move{width:100%;cursor:move;border:var(--cropper-move-border, 1px solid rgba(255, 255, 255, .5))}:host .ngx-ic-cropper:focus .ngx-ic-move{border-color:#1e90ff;border-width:2px}:host .ngx-ic-cropper .ngx-ic-resize{position:absolute;display:inline-block;line-height:6px;padding:8px;opacity:.85;z-index:1}:host .ngx-ic-cropper .ngx-ic-resize .ngx-ic-square{display:inline-block;background:#53535c;width:6px;height:6px;border:1px solid rgba(255,255,255,.5);box-sizing:content-box}:host .ngx-ic-cropper .ngx-ic-resize.ngx-ic-topleft{top:-12px;left:-12px;cursor:nwse-resize}:host .ngx-ic-cropper .ngx-ic-resize.ngx-ic-top{top:-12px;left:calc(50% - 12px);cursor:ns-resize}:host .ngx-ic-cropper .ngx-ic-resize.ngx-ic-topright{top:-12px;right:-12px;cursor:nesw-resize}:host .ngx-ic-cropper .ngx-ic-resize.ngx-ic-right{top:calc(50% - 12px);right:-12px;cursor:ew-resize}:host .ngx-ic-cropper .ngx-ic-resize.ngx-ic-bottomright{bottom:-12px;right:-12px;cursor:nwse-resize}:host .ngx-ic-cropper .ngx-ic-resize.ngx-ic-bottom{bottom:-12px;left:calc(50% - 12px);cursor:ns-resize}:host .ngx-ic-cropper .ngx-ic-resize.ngx-ic-bottomleft{bottom:-12px;left:-12px;cursor:nesw-resize}:host .ngx-ic-cropper .ngx-ic-resize.ngx-ic-left{top:calc(50% - 12px);left:-12px;cursor:ew-resize}:host .ngx-ic-cropper .ngx-ic-resize-bar{position:absolute;z-index:1}:host .ngx-ic-cropper .ngx-ic-resize-bar.ngx-ic-top{top:-11px;left:11px;width:calc(100% - 22px);height:22px;cursor:ns-resize}:host .ngx-ic-cropper .ngx-ic-resize-bar.ngx-ic-right{top:11px;right:-11px;height:calc(100% - 22px);width:22px;cursor:ew-resize}:host .ngx-ic-cropper .ngx-ic-resize-bar.ngx-ic-bottom{bottom:-11px;left:11px;width:calc(100% - 22px);height:22px;cursor:ns-resize}:host .ngx-ic-cropper .ngx-ic-resize-bar.ngx-ic-left{top:11px;left:-11px;height:calc(100% - 22px);width:22px;cursor:ew-resize}:host .ngx-ic-cropper.ngx-ic-round{outline-color:transparent}:host .ngx-ic-cropper.ngx-ic-round:after{border-radius:100%;box-shadow:0 0 0 100vw #ffffff4d;box-shadow:0 0 0 100vw var(--cropper-outline-color, rgba(255, 255, 255, .3))}@media (orientation: portrait){:host .ngx-ic-cropper.ngx-ic-round:after{box-shadow:0 0 0 100vh #ffffff4d;box-shadow:0 0 0 100vh var(--cropper-outline-color, rgba(255, 255, 255, .3))}}:host .ngx-ic-cropper.ngx-ic-round .ngx-ic-move{border-radius:100%}:host.disabled .ngx-ic-cropper .ngx-ic-resize,:host.disabled .ngx-ic-cropper .ngx-ic-resize-bar,:host.disabled .ngx-ic-cropper .ngx-ic-move{display:none}:host.ngx-ic-hidden{display:none}\n"], dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1359
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ImageCropperComponent, deps: [{ token: i1.DomSanitizer }], target: i0.ɵɵFactoryTarget.Component }); }
1360
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: ImageCropperComponent, isStandalone: true, selector: "image-cropper", inputs: { imageChangedEvent: "imageChangedEvent", imageURL: "imageURL", imageBase64: "imageBase64", imageFile: "imageFile", imageAltText: "imageAltText", options: "options", cropperFrameAriaLabel: "cropperFrameAriaLabel", output: "output", format: "format", autoCrop: "autoCrop", cropper: "cropper", transform: "transform", maintainAspectRatio: "maintainAspectRatio", aspectRatio: "aspectRatio", resetCropOnAspectRatioChange: "resetCropOnAspectRatioChange", resizeToWidth: "resizeToWidth", resizeToHeight: "resizeToHeight", cropperMinWidth: "cropperMinWidth", cropperMinHeight: "cropperMinHeight", cropperMaxHeight: "cropperMaxHeight", cropperMaxWidth: "cropperMaxWidth", cropperStaticWidth: "cropperStaticWidth", cropperStaticHeight: "cropperStaticHeight", canvasRotation: "canvasRotation", initialStepSize: "initialStepSize", roundCropper: "roundCropper", onlyScaleDown: "onlyScaleDown", imageQuality: "imageQuality", backgroundColor: "backgroundColor", containWithinAspectRatio: "containWithinAspectRatio", hideResizeSquares: "hideResizeSquares", allowMoveImage: "allowMoveImage", checkImageType: "checkImageType", alignImage: "alignImage", disabled: "disabled", hidden: "hidden" }, outputs: { imageCropped: "imageCropped", startCropImage: "startCropImage", imageLoaded: "imageLoaded", cropperReady: "cropperReady", loadImageFailed: "loadImageFailed", transformChange: "transformChange", cropperChange: "cropperChange" }, host: { listeners: { "window:resize": "onResize()" }, properties: { "class.disabled": "this.disabled", "class.ngx-ic-hidden": "this.hidden", "style.text-align": "this.alignImageStyle" } }, viewQueries: [{ propertyName: "wrapper", first: true, predicate: ["wrapper"], descendants: true, static: true }, { propertyName: "sourceImage", first: true, predicate: ["sourceImage"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div\n [style.background]=\"imageVisible && state.options.backgroundColor\"\n (touchstart)=\"startPinch($event)\"\n>\n <img\n #sourceImage\n class=\"ngx-ic-source-image\"\n role=\"presentation\"\n *ngIf=\"safeImgDataUrl() as src\"\n [src]=\"src\"\n [style.visibility]=\"imageVisible ? 'visible' : 'hidden'\"\n [style.transform]=\"safeTransformStyle()\"\n [class.ngx-ic-draggable]=\"!disabled && allowMoveImage\"\n [attr.alt]=\"imageAltText\"\n (load)=\"imageLoadedInView()\"\n (mousedown)=\"startMove($event, moveTypes.Drag)\"\n (touchstart)=\"startMove($event, moveTypes.Drag)\"\n (error)=\"loadImageError($event)\"\n >\n <div\n class=\"ngx-ic-overlay\"\n [style.width.px]=\"state.maxSize?.width || 0\"\n [style.height.px]=\"state.maxSize?.height || 0\"\n [style.margin-left]=\"alignImage === 'center' ? marginLeft : null\"\n ></div>\n <div\n class=\"ngx-ic-cropper\"\n *ngIf=\"imageVisible\"\n [class.ngx-ic-round]=\"state.options.roundCropper\"\n [attr.aria-label]=\"state.options.cropperFrameAriaLabel\"\n [style.top.px]=\"state.cropper().y1\"\n [style.left.px]=\"state.cropper().x1\"\n [style.width.px]=\"state.cropper().x2 - state.cropper().x1\"\n [style.height.px]=\"state.cropper().y2 - state.cropper().y1\"\n [style.margin-left]=\"state.options.alignImage === 'center' ? marginLeft : null\"\n [style.visibility]=\"imageVisible ? 'visible' : 'hidden'\"\n (keydown)=\"keyboardAccess($event)\"\n tabindex=\"0\"\n >\n <div\n (mousedown)=\"startMove($event, moveTypes.Move)\"\n (touchstart)=\"startMove($event, moveTypes.Move)\"\n class=\"ngx-ic-move\"\n role=\"presentation\">\n </div>\n <ng-container\n *ngIf=\"!state.options.hideResizeSquares && !(state.options.cropperStaticWidth && state.options.cropperStaticHeight)\">\n <span\n class=\"ngx-ic-resize ngx-ic-topleft\"\n role=\"presentation\"\n (mousedown)=\"startMove($event, moveTypes.Resize, 'topleft')\"\n (touchstart)=\"startMove($event, moveTypes.Resize, 'topleft')\"\n >\n <span class=\"ngx-ic-square\"></span>\n </span>\n <span class=\"ngx-ic-resize ngx-ic-top\">\n <span class=\"ngx-ic-square\"></span>\n </span>\n <span\n class=\"ngx-ic-resize ngx-ic-topright\"\n role=\"presentation\"\n (mousedown)=\"startMove($event, moveTypes.Resize, 'topright')\"\n (touchstart)=\"startMove($event, moveTypes.Resize, 'topright')\"\n >\n <span class=\"ngx-ic-square\"></span>\n </span>\n <span class=\"ngx-ic-resize ngx-ic-right\">\n <span class=\"ngx-ic-square\"></span>\n </span>\n <span\n class=\"ngx-ic-resize ngx-ic-bottomright\"\n role=\"presentation\"\n (mousedown)=\"startMove($event, moveTypes.Resize, 'bottomright')\"\n (touchstart)=\"startMove($event, moveTypes.Resize, 'bottomright')\"\n >\n <span class=\"ngx-ic-square\"></span>\n </span>\n <span class=\"ngx-ic-resize ngx-ic-bottom\">\n <span class=\"ngx-ic-square\"></span>\n </span>\n <span\n class=\"ngx-ic-resize ngx-ic-bottomleft\"\n role=\"presentation\"\n (mousedown)=\"startMove($event, moveTypes.Resize, 'bottomleft')\"\n (touchstart)=\"startMove($event, moveTypes.Resize, 'bottomleft')\"\n >\n <span class=\"ngx-ic-square\"></span>\n </span>\n <span class=\"ngx-ic-resize ngx-ic-left\">\n <span class=\"ngx-ic-square\"></span>\n </span>\n <span\n class=\"ngx-ic-resize-bar ngx-ic-top\"\n role=\"presentation\"\n (mousedown)=\"startMove($event, moveTypes.Resize, 'top')\"\n (touchstart)=\"startMove($event, moveTypes.Resize, 'top')\"\n ></span>\n <span\n class=\"ngx-ic-resize-bar ngx-ic-right\"\n role=\"presentation\"\n (mousedown)=\"startMove($event, moveTypes.Resize, 'right')\"\n (touchstart)=\"startMove($event, moveTypes.Resize, 'right')\"\n ></span>\n <span\n class=\"ngx-ic-resize-bar ngx-ic-bottom\"\n role=\"presentation\"\n (mousedown)=\"startMove($event, moveTypes.Resize, 'bottom')\"\n (touchstart)=\"startMove($event, moveTypes.Resize, 'bottom')\"\n ></span>\n <span\n class=\"ngx-ic-resize-bar ngx-ic-left\"\n role=\"presentation\"\n (mousedown)=\"startMove($event, moveTypes.Resize, 'left')\"\n (touchstart)=\"startMove($event, moveTypes.Resize, 'left')\"\n ></span>\n </ng-container>\n </div>\n</div>\n", styles: [":host{display:flex;position:relative;width:100%;max-width:100%;max-height:100%;overflow:hidden;padding:5px;text-align:center}:host>div{width:100%;position:relative}:host>div img.ngx-ic-source-image{max-width:100%;max-height:100%;transform-origin:center}:host>div img.ngx-ic-source-image.ngx-ic-draggable{user-drag:none;-webkit-user-drag:none;user-select:none;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;cursor:grab}:host .ngx-ic-overlay{position:absolute;pointer-events:none;touch-action:none;outline:var(--cropper-overlay-color, white) solid 100vw;top:0;left:0}:host .ngx-ic-cropper{position:absolute;display:flex;color:#53535c;background:transparent;outline:rgba(255,255,255,.3) solid 100vw;outline:var(--cropper-outline-color, rgba(255, 255, 255, .3)) solid 100vw;touch-action:none}@media (orientation: portrait){:host .ngx-ic-cropper{outline-width:100vh}}:host .ngx-ic-cropper:after{position:absolute;content:\"\";inset:0;pointer-events:none;border:dashed 1px;opacity:.75;color:inherit;z-index:1}:host .ngx-ic-cropper .ngx-ic-move{width:100%;cursor:move;border:var(--cropper-move-border, 1px solid rgba(255, 255, 255, .5))}:host .ngx-ic-cropper:focus .ngx-ic-move{border-color:#1e90ff;border-width:2px}:host .ngx-ic-cropper .ngx-ic-resize{position:absolute;display:inline-block;line-height:6px;padding:8px;opacity:.85;z-index:1}:host .ngx-ic-cropper .ngx-ic-resize .ngx-ic-square{display:inline-block;background:#53535c;width:6px;height:6px;border:1px solid rgba(255,255,255,.5);box-sizing:content-box}:host .ngx-ic-cropper .ngx-ic-resize.ngx-ic-topleft{top:-12px;left:-12px;cursor:nwse-resize}:host .ngx-ic-cropper .ngx-ic-resize.ngx-ic-top{top:-12px;left:calc(50% - 12px);cursor:ns-resize}:host .ngx-ic-cropper .ngx-ic-resize.ngx-ic-topright{top:-12px;right:-12px;cursor:nesw-resize}:host .ngx-ic-cropper .ngx-ic-resize.ngx-ic-right{top:calc(50% - 12px);right:-12px;cursor:ew-resize}:host .ngx-ic-cropper .ngx-ic-resize.ngx-ic-bottomright{bottom:-12px;right:-12px;cursor:nwse-resize}:host .ngx-ic-cropper .ngx-ic-resize.ngx-ic-bottom{bottom:-12px;left:calc(50% - 12px);cursor:ns-resize}:host .ngx-ic-cropper .ngx-ic-resize.ngx-ic-bottomleft{bottom:-12px;left:-12px;cursor:nesw-resize}:host .ngx-ic-cropper .ngx-ic-resize.ngx-ic-left{top:calc(50% - 12px);left:-12px;cursor:ew-resize}:host .ngx-ic-cropper .ngx-ic-resize-bar{position:absolute;z-index:1}:host .ngx-ic-cropper .ngx-ic-resize-bar.ngx-ic-top{top:-11px;left:11px;width:calc(100% - 22px);height:22px;cursor:ns-resize}:host .ngx-ic-cropper .ngx-ic-resize-bar.ngx-ic-right{top:11px;right:-11px;height:calc(100% - 22px);width:22px;cursor:ew-resize}:host .ngx-ic-cropper .ngx-ic-resize-bar.ngx-ic-bottom{bottom:-11px;left:11px;width:calc(100% - 22px);height:22px;cursor:ns-resize}:host .ngx-ic-cropper .ngx-ic-resize-bar.ngx-ic-left{top:11px;left:-11px;height:calc(100% - 22px);width:22px;cursor:ew-resize}:host .ngx-ic-cropper.ngx-ic-round{outline-color:transparent}:host .ngx-ic-cropper.ngx-ic-round:after{border-radius:100%;box-shadow:0 0 0 100vw #ffffff4d;box-shadow:0 0 0 100vw var(--cropper-outline-color, rgba(255, 255, 255, .3))}@media (orientation: portrait){:host .ngx-ic-cropper.ngx-ic-round:after{box-shadow:0 0 0 100vh #ffffff4d;box-shadow:0 0 0 100vh var(--cropper-outline-color, rgba(255, 255, 255, .3))}}:host .ngx-ic-cropper.ngx-ic-round .ngx-ic-move{border-radius:100%}:host.disabled .ngx-ic-cropper .ngx-ic-resize,:host.disabled .ngx-ic-cropper .ngx-ic-resize-bar,:host.disabled .ngx-ic-cropper .ngx-ic-move{display:none}:host.ngx-ic-hidden{display:none}\n"], dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1377
1361
  }
1378
1362
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ImageCropperComponent, decorators: [{
1379
1363
  type: Component,
1380
- args: [{ selector: 'image-cropper', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [NgIf], template: "<div\n [style.background]=\"imageVisible && state.options.backgroundColor\"\n (touchstart)=\"startPinch($event)\"\n>\n <img\n #sourceImage\n class=\"ngx-ic-source-image\"\n role=\"presentation\"\n *ngIf=\"safeImgDataUrl() as src\"\n [src]=\"src\"\n [style.visibility]=\"imageVisible ? 'visible' : 'hidden'\"\n [style.transform]=\"safeTransformStyle\"\n [class.ngx-ic-draggable]=\"!disabled && allowMoveImage\"\n [attr.alt]=\"imageAltText\"\n (load)=\"imageLoadedInView()\"\n (mousedown)=\"startMove($event, moveTypes.Drag)\"\n (touchstart)=\"startMove($event, moveTypes.Drag)\"\n (error)=\"loadImageError($event)\"\n >\n <div\n class=\"ngx-ic-overlay\"\n [style.width.px]=\"state.maxSize?.width || 0\"\n [style.height.px]=\"state.maxSize?.height || 0\"\n [style.margin-left]=\"alignImage === 'center' ? marginLeft : null\"\n ></div>\n <div\n class=\"ngx-ic-cropper\"\n *ngIf=\"imageVisible\"\n [class.ngx-ic-round]=\"state.options.roundCropper\"\n [attr.aria-label]=\"state.options.cropperFrameAriaLabel\"\n [style.top.px]=\"state.cropper.y1\"\n [style.left.px]=\"state.cropper.x1\"\n [style.width.px]=\"state.cropper.x2 - state.cropper.x1\"\n [style.height.px]=\"state.cropper.y2 - state.cropper.y1\"\n [style.margin-left]=\"state.options.alignImage === 'center' ? marginLeft : null\"\n [style.visibility]=\"imageVisible ? 'visible' : 'hidden'\"\n (keydown)=\"keyboardAccess($event)\"\n tabindex=\"0\"\n >\n <div\n (mousedown)=\"startMove($event, moveTypes.Move)\"\n (touchstart)=\"startMove($event, moveTypes.Move)\"\n class=\"ngx-ic-move\"\n role=\"presentation\">\n </div>\n <ng-container\n *ngIf=\"!state.options.hideResizeSquares && !(state.options.cropperStaticWidth && state.options.cropperStaticHeight)\">\n <span\n class=\"ngx-ic-resize ngx-ic-topleft\"\n role=\"presentation\"\n (mousedown)=\"startMove($event, moveTypes.Resize, 'topleft')\"\n (touchstart)=\"startMove($event, moveTypes.Resize, 'topleft')\"\n >\n <span class=\"ngx-ic-square\"></span>\n </span>\n <span class=\"ngx-ic-resize ngx-ic-top\">\n <span class=\"ngx-ic-square\"></span>\n </span>\n <span\n class=\"ngx-ic-resize ngx-ic-topright\"\n role=\"presentation\"\n (mousedown)=\"startMove($event, moveTypes.Resize, 'topright')\"\n (touchstart)=\"startMove($event, moveTypes.Resize, 'topright')\"\n >\n <span class=\"ngx-ic-square\"></span>\n </span>\n <span class=\"ngx-ic-resize ngx-ic-right\">\n <span class=\"ngx-ic-square\"></span>\n </span>\n <span\n class=\"ngx-ic-resize ngx-ic-bottomright\"\n role=\"presentation\"\n (mousedown)=\"startMove($event, moveTypes.Resize, 'bottomright')\"\n (touchstart)=\"startMove($event, moveTypes.Resize, 'bottomright')\"\n >\n <span class=\"ngx-ic-square\"></span>\n </span>\n <span class=\"ngx-ic-resize ngx-ic-bottom\">\n <span class=\"ngx-ic-square\"></span>\n </span>\n <span\n class=\"ngx-ic-resize ngx-ic-bottomleft\"\n role=\"presentation\"\n (mousedown)=\"startMove($event, moveTypes.Resize, 'bottomleft')\"\n (touchstart)=\"startMove($event, moveTypes.Resize, 'bottomleft')\"\n >\n <span class=\"ngx-ic-square\"></span>\n </span>\n <span class=\"ngx-ic-resize ngx-ic-left\">\n <span class=\"ngx-ic-square\"></span>\n </span>\n <span\n class=\"ngx-ic-resize-bar ngx-ic-top\"\n role=\"presentation\"\n (mousedown)=\"startMove($event, moveTypes.Resize, 'top')\"\n (touchstart)=\"startMove($event, moveTypes.Resize, 'top')\"\n ></span>\n <span\n class=\"ngx-ic-resize-bar ngx-ic-right\"\n role=\"presentation\"\n (mousedown)=\"startMove($event, moveTypes.Resize, 'right')\"\n (touchstart)=\"startMove($event, moveTypes.Resize, 'right')\"\n ></span>\n <span\n class=\"ngx-ic-resize-bar ngx-ic-bottom\"\n role=\"presentation\"\n (mousedown)=\"startMove($event, moveTypes.Resize, 'bottom')\"\n (touchstart)=\"startMove($event, moveTypes.Resize, 'bottom')\"\n ></span>\n <span\n class=\"ngx-ic-resize-bar ngx-ic-left\"\n role=\"presentation\"\n (mousedown)=\"startMove($event, moveTypes.Resize, 'left')\"\n (touchstart)=\"startMove($event, moveTypes.Resize, 'left')\"\n ></span>\n </ng-container>\n </div>\n</div>\n", styles: [":host{display:flex;position:relative;width:100%;max-width:100%;max-height:100%;overflow:hidden;padding:5px;text-align:center}:host>div{width:100%;position:relative}:host>div img.ngx-ic-source-image{max-width:100%;max-height:100%;transform-origin:center}:host>div img.ngx-ic-source-image.ngx-ic-draggable{user-drag:none;-webkit-user-drag:none;user-select:none;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;cursor:grab}:host .ngx-ic-overlay{position:absolute;pointer-events:none;touch-action:none;outline:var(--cropper-overlay-color, white) solid 100vw;top:0;left:0}:host .ngx-ic-cropper{position:absolute;display:flex;color:#53535c;background:transparent;outline:rgba(255,255,255,.3) solid 100vw;outline:var(--cropper-outline-color, rgba(255, 255, 255, .3)) solid 100vw;touch-action:none}@media (orientation: portrait){:host .ngx-ic-cropper{outline-width:100vh}}:host .ngx-ic-cropper:after{position:absolute;content:\"\";inset:0;pointer-events:none;border:dashed 1px;opacity:.75;color:inherit;z-index:1}:host .ngx-ic-cropper .ngx-ic-move{width:100%;cursor:move;border:var(--cropper-move-border, 1px solid rgba(255, 255, 255, .5))}:host .ngx-ic-cropper:focus .ngx-ic-move{border-color:#1e90ff;border-width:2px}:host .ngx-ic-cropper .ngx-ic-resize{position:absolute;display:inline-block;line-height:6px;padding:8px;opacity:.85;z-index:1}:host .ngx-ic-cropper .ngx-ic-resize .ngx-ic-square{display:inline-block;background:#53535c;width:6px;height:6px;border:1px solid rgba(255,255,255,.5);box-sizing:content-box}:host .ngx-ic-cropper .ngx-ic-resize.ngx-ic-topleft{top:-12px;left:-12px;cursor:nwse-resize}:host .ngx-ic-cropper .ngx-ic-resize.ngx-ic-top{top:-12px;left:calc(50% - 12px);cursor:ns-resize}:host .ngx-ic-cropper .ngx-ic-resize.ngx-ic-topright{top:-12px;right:-12px;cursor:nesw-resize}:host .ngx-ic-cropper .ngx-ic-resize.ngx-ic-right{top:calc(50% - 12px);right:-12px;cursor:ew-resize}:host .ngx-ic-cropper .ngx-ic-resize.ngx-ic-bottomright{bottom:-12px;right:-12px;cursor:nwse-resize}:host .ngx-ic-cropper .ngx-ic-resize.ngx-ic-bottom{bottom:-12px;left:calc(50% - 12px);cursor:ns-resize}:host .ngx-ic-cropper .ngx-ic-resize.ngx-ic-bottomleft{bottom:-12px;left:-12px;cursor:nesw-resize}:host .ngx-ic-cropper .ngx-ic-resize.ngx-ic-left{top:calc(50% - 12px);left:-12px;cursor:ew-resize}:host .ngx-ic-cropper .ngx-ic-resize-bar{position:absolute;z-index:1}:host .ngx-ic-cropper .ngx-ic-resize-bar.ngx-ic-top{top:-11px;left:11px;width:calc(100% - 22px);height:22px;cursor:ns-resize}:host .ngx-ic-cropper .ngx-ic-resize-bar.ngx-ic-right{top:11px;right:-11px;height:calc(100% - 22px);width:22px;cursor:ew-resize}:host .ngx-ic-cropper .ngx-ic-resize-bar.ngx-ic-bottom{bottom:-11px;left:11px;width:calc(100% - 22px);height:22px;cursor:ns-resize}:host .ngx-ic-cropper .ngx-ic-resize-bar.ngx-ic-left{top:11px;left:-11px;height:calc(100% - 22px);width:22px;cursor:ew-resize}:host .ngx-ic-cropper.ngx-ic-round{outline-color:transparent}:host .ngx-ic-cropper.ngx-ic-round:after{border-radius:100%;box-shadow:0 0 0 100vw #ffffff4d;box-shadow:0 0 0 100vw var(--cropper-outline-color, rgba(255, 255, 255, .3))}@media (orientation: portrait){:host .ngx-ic-cropper.ngx-ic-round:after{box-shadow:0 0 0 100vh #ffffff4d;box-shadow:0 0 0 100vh var(--cropper-outline-color, rgba(255, 255, 255, .3))}}:host .ngx-ic-cropper.ngx-ic-round .ngx-ic-move{border-radius:100%}:host.disabled .ngx-ic-cropper .ngx-ic-resize,:host.disabled .ngx-ic-cropper .ngx-ic-resize-bar,:host.disabled .ngx-ic-cropper .ngx-ic-move{display:none}:host.ngx-ic-hidden{display:none}\n"] }]
1381
- }], ctorParameters: () => [{ type: i1.DomSanitizer }, { type: i0.ChangeDetectorRef }, { type: i0.NgZone }], propDecorators: { wrapper: [{
1364
+ args: [{ selector: 'image-cropper', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [NgIf], template: "<div\n [style.background]=\"imageVisible && state.options.backgroundColor\"\n (touchstart)=\"startPinch($event)\"\n>\n <img\n #sourceImage\n class=\"ngx-ic-source-image\"\n role=\"presentation\"\n *ngIf=\"safeImgDataUrl() as src\"\n [src]=\"src\"\n [style.visibility]=\"imageVisible ? 'visible' : 'hidden'\"\n [style.transform]=\"safeTransformStyle()\"\n [class.ngx-ic-draggable]=\"!disabled && allowMoveImage\"\n [attr.alt]=\"imageAltText\"\n (load)=\"imageLoadedInView()\"\n (mousedown)=\"startMove($event, moveTypes.Drag)\"\n (touchstart)=\"startMove($event, moveTypes.Drag)\"\n (error)=\"loadImageError($event)\"\n >\n <div\n class=\"ngx-ic-overlay\"\n [style.width.px]=\"state.maxSize?.width || 0\"\n [style.height.px]=\"state.maxSize?.height || 0\"\n [style.margin-left]=\"alignImage === 'center' ? marginLeft : null\"\n ></div>\n <div\n class=\"ngx-ic-cropper\"\n *ngIf=\"imageVisible\"\n [class.ngx-ic-round]=\"state.options.roundCropper\"\n [attr.aria-label]=\"state.options.cropperFrameAriaLabel\"\n [style.top.px]=\"state.cropper().y1\"\n [style.left.px]=\"state.cropper().x1\"\n [style.width.px]=\"state.cropper().x2 - state.cropper().x1\"\n [style.height.px]=\"state.cropper().y2 - state.cropper().y1\"\n [style.margin-left]=\"state.options.alignImage === 'center' ? marginLeft : null\"\n [style.visibility]=\"imageVisible ? 'visible' : 'hidden'\"\n (keydown)=\"keyboardAccess($event)\"\n tabindex=\"0\"\n >\n <div\n (mousedown)=\"startMove($event, moveTypes.Move)\"\n (touchstart)=\"startMove($event, moveTypes.Move)\"\n class=\"ngx-ic-move\"\n role=\"presentation\">\n </div>\n <ng-container\n *ngIf=\"!state.options.hideResizeSquares && !(state.options.cropperStaticWidth && state.options.cropperStaticHeight)\">\n <span\n class=\"ngx-ic-resize ngx-ic-topleft\"\n role=\"presentation\"\n (mousedown)=\"startMove($event, moveTypes.Resize, 'topleft')\"\n (touchstart)=\"startMove($event, moveTypes.Resize, 'topleft')\"\n >\n <span class=\"ngx-ic-square\"></span>\n </span>\n <span class=\"ngx-ic-resize ngx-ic-top\">\n <span class=\"ngx-ic-square\"></span>\n </span>\n <span\n class=\"ngx-ic-resize ngx-ic-topright\"\n role=\"presentation\"\n (mousedown)=\"startMove($event, moveTypes.Resize, 'topright')\"\n (touchstart)=\"startMove($event, moveTypes.Resize, 'topright')\"\n >\n <span class=\"ngx-ic-square\"></span>\n </span>\n <span class=\"ngx-ic-resize ngx-ic-right\">\n <span class=\"ngx-ic-square\"></span>\n </span>\n <span\n class=\"ngx-ic-resize ngx-ic-bottomright\"\n role=\"presentation\"\n (mousedown)=\"startMove($event, moveTypes.Resize, 'bottomright')\"\n (touchstart)=\"startMove($event, moveTypes.Resize, 'bottomright')\"\n >\n <span class=\"ngx-ic-square\"></span>\n </span>\n <span class=\"ngx-ic-resize ngx-ic-bottom\">\n <span class=\"ngx-ic-square\"></span>\n </span>\n <span\n class=\"ngx-ic-resize ngx-ic-bottomleft\"\n role=\"presentation\"\n (mousedown)=\"startMove($event, moveTypes.Resize, 'bottomleft')\"\n (touchstart)=\"startMove($event, moveTypes.Resize, 'bottomleft')\"\n >\n <span class=\"ngx-ic-square\"></span>\n </span>\n <span class=\"ngx-ic-resize ngx-ic-left\">\n <span class=\"ngx-ic-square\"></span>\n </span>\n <span\n class=\"ngx-ic-resize-bar ngx-ic-top\"\n role=\"presentation\"\n (mousedown)=\"startMove($event, moveTypes.Resize, 'top')\"\n (touchstart)=\"startMove($event, moveTypes.Resize, 'top')\"\n ></span>\n <span\n class=\"ngx-ic-resize-bar ngx-ic-right\"\n role=\"presentation\"\n (mousedown)=\"startMove($event, moveTypes.Resize, 'right')\"\n (touchstart)=\"startMove($event, moveTypes.Resize, 'right')\"\n ></span>\n <span\n class=\"ngx-ic-resize-bar ngx-ic-bottom\"\n role=\"presentation\"\n (mousedown)=\"startMove($event, moveTypes.Resize, 'bottom')\"\n (touchstart)=\"startMove($event, moveTypes.Resize, 'bottom')\"\n ></span>\n <span\n class=\"ngx-ic-resize-bar ngx-ic-left\"\n role=\"presentation\"\n (mousedown)=\"startMove($event, moveTypes.Resize, 'left')\"\n (touchstart)=\"startMove($event, moveTypes.Resize, 'left')\"\n ></span>\n </ng-container>\n </div>\n</div>\n", styles: [":host{display:flex;position:relative;width:100%;max-width:100%;max-height:100%;overflow:hidden;padding:5px;text-align:center}:host>div{width:100%;position:relative}:host>div img.ngx-ic-source-image{max-width:100%;max-height:100%;transform-origin:center}:host>div img.ngx-ic-source-image.ngx-ic-draggable{user-drag:none;-webkit-user-drag:none;user-select:none;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;cursor:grab}:host .ngx-ic-overlay{position:absolute;pointer-events:none;touch-action:none;outline:var(--cropper-overlay-color, white) solid 100vw;top:0;left:0}:host .ngx-ic-cropper{position:absolute;display:flex;color:#53535c;background:transparent;outline:rgba(255,255,255,.3) solid 100vw;outline:var(--cropper-outline-color, rgba(255, 255, 255, .3)) solid 100vw;touch-action:none}@media (orientation: portrait){:host .ngx-ic-cropper{outline-width:100vh}}:host .ngx-ic-cropper:after{position:absolute;content:\"\";inset:0;pointer-events:none;border:dashed 1px;opacity:.75;color:inherit;z-index:1}:host .ngx-ic-cropper .ngx-ic-move{width:100%;cursor:move;border:var(--cropper-move-border, 1px solid rgba(255, 255, 255, .5))}:host .ngx-ic-cropper:focus .ngx-ic-move{border-color:#1e90ff;border-width:2px}:host .ngx-ic-cropper .ngx-ic-resize{position:absolute;display:inline-block;line-height:6px;padding:8px;opacity:.85;z-index:1}:host .ngx-ic-cropper .ngx-ic-resize .ngx-ic-square{display:inline-block;background:#53535c;width:6px;height:6px;border:1px solid rgba(255,255,255,.5);box-sizing:content-box}:host .ngx-ic-cropper .ngx-ic-resize.ngx-ic-topleft{top:-12px;left:-12px;cursor:nwse-resize}:host .ngx-ic-cropper .ngx-ic-resize.ngx-ic-top{top:-12px;left:calc(50% - 12px);cursor:ns-resize}:host .ngx-ic-cropper .ngx-ic-resize.ngx-ic-topright{top:-12px;right:-12px;cursor:nesw-resize}:host .ngx-ic-cropper .ngx-ic-resize.ngx-ic-right{top:calc(50% - 12px);right:-12px;cursor:ew-resize}:host .ngx-ic-cropper .ngx-ic-resize.ngx-ic-bottomright{bottom:-12px;right:-12px;cursor:nwse-resize}:host .ngx-ic-cropper .ngx-ic-resize.ngx-ic-bottom{bottom:-12px;left:calc(50% - 12px);cursor:ns-resize}:host .ngx-ic-cropper .ngx-ic-resize.ngx-ic-bottomleft{bottom:-12px;left:-12px;cursor:nesw-resize}:host .ngx-ic-cropper .ngx-ic-resize.ngx-ic-left{top:calc(50% - 12px);left:-12px;cursor:ew-resize}:host .ngx-ic-cropper .ngx-ic-resize-bar{position:absolute;z-index:1}:host .ngx-ic-cropper .ngx-ic-resize-bar.ngx-ic-top{top:-11px;left:11px;width:calc(100% - 22px);height:22px;cursor:ns-resize}:host .ngx-ic-cropper .ngx-ic-resize-bar.ngx-ic-right{top:11px;right:-11px;height:calc(100% - 22px);width:22px;cursor:ew-resize}:host .ngx-ic-cropper .ngx-ic-resize-bar.ngx-ic-bottom{bottom:-11px;left:11px;width:calc(100% - 22px);height:22px;cursor:ns-resize}:host .ngx-ic-cropper .ngx-ic-resize-bar.ngx-ic-left{top:11px;left:-11px;height:calc(100% - 22px);width:22px;cursor:ew-resize}:host .ngx-ic-cropper.ngx-ic-round{outline-color:transparent}:host .ngx-ic-cropper.ngx-ic-round:after{border-radius:100%;box-shadow:0 0 0 100vw #ffffff4d;box-shadow:0 0 0 100vw var(--cropper-outline-color, rgba(255, 255, 255, .3))}@media (orientation: portrait){:host .ngx-ic-cropper.ngx-ic-round:after{box-shadow:0 0 0 100vh #ffffff4d;box-shadow:0 0 0 100vh var(--cropper-outline-color, rgba(255, 255, 255, .3))}}:host .ngx-ic-cropper.ngx-ic-round .ngx-ic-move{border-radius:100%}:host.disabled .ngx-ic-cropper .ngx-ic-resize,:host.disabled .ngx-ic-cropper .ngx-ic-resize-bar,:host.disabled .ngx-ic-cropper .ngx-ic-move{display:none}:host.ngx-ic-hidden{display:none}\n"] }]
1365
+ }], ctorParameters: () => [{ type: i1.DomSanitizer }], propDecorators: { wrapper: [{
1382
1366
  type: ViewChild,
1383
1367
  args: ['wrapper', { static: true }]
1384
1368
  }], sourceImage: [{
@@ -1462,20 +1446,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
1462
1446
  args: ['class.ngx-ic-hidden']
1463
1447
  }, {
1464
1448
  type: Input
1465
- }], imageCropped: [{
1466
- type: Output
1467
- }], startCropImage: [{
1468
- type: Output
1469
- }], imageLoaded: [{
1470
- type: Output
1471
- }], cropperReady: [{
1472
- type: Output
1473
- }], loadImageFailed: [{
1474
- type: Output
1475
- }], transformChange: [{
1476
- type: Output
1477
- }], cropperChange: [{
1478
- type: Output
1479
1449
  }], alignImageStyle: [{
1480
1450
  type: HostBinding,
1481
1451
  args: ['style.text-align']