ngx-kit 6.2.0 → 6.3.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 +1 @@
1
- {"version":3,"file":"ngx-kit-drawer-menu.mjs","sources":["../../../projects/libs/drawer-menu/components/drawer-menu.component.ts","../../../projects/libs/drawer-menu/components/drawer-menu.component.html","../../../projects/libs/drawer-menu/ngx-kit-drawer-menu.ts"],"sourcesContent":["import {\r\n ChangeDetectionStrategy,\r\n Component,\r\n DestroyRef,\r\n DOCUMENT,\r\n HostListener,\r\n computed,\r\n effect,\r\n inject,\r\n input,\r\n model,\r\n signal,\r\n} from '@angular/core';\r\nimport { DirectionService, startDragSession } from 'ngx-kit/shared';\r\nimport {\r\n NgxDrawerContentBehavior,\r\n NgxDrawerEffect,\r\n NgxDrawerSide,\r\n} from '../contracts/drawer-menu-types';\r\n\r\n/**\r\n * درور منو (side drawer) با ۶ جلوه‌ی بازوبسته‌شدنِ متفاوت (از ساده تا\r\n * سه‌بعدی/ژله‌ای) و ۳ رفتار برای محتوای صفحه (overlay/push/reveal) —\r\n * دقیقاً مدل کتابخونه‌های حرفه‌ای مثل react-burger-menu یا Ionic Menu، ولی\r\n * signal-based و بدون هیچ وابستگی خارجی.\r\n *\r\n * نکات معماری:\r\n * - از 'start'/'end' منطقی استفاده می‌کنه، پس با CSS logical properties\r\n * زیر RTL خودکار برعکس می‌شه؛ فقط ریاضیِ درگ (که برخلاف CSS جهت فیزیکیِ\r\n * واقعی لازم داره) از DirectionService مشترک استفاده می‌کنه.\r\n * - وضعیت باز/بسته با model() دوطرفه‌ست، پس هم با [(open)] قابل کنترله و\r\n * هم می‌تونه به‌صورت خودکار و زنده با عرض صفحه هماهنگ بشه (respondToViewport)\r\n * — یعنی رد شدن از breakpoint (نه فقط بار اول لود) می‌تونه خودکار باز/بسته‌ش کنه.\r\n * - افکت‌های jelly/pull با keyframe سه‌مرحله‌ای (overshoot → نوسان → استقرار)\r\n * پیاده شدن، نه فقط یه transition ساده.\r\n */\r\n@Component({\r\n selector: 'ngx-drawer-menu',\r\n standalone: true,\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './drawer-menu.component.html',\r\n styleUrl: './drawer-menu.component.scss',\r\n host: { class: 'ngx-drawer-menu-host' },\r\n})\r\nexport class NgxDrawerMenuComponent {\r\n side = input<NgxDrawerSide>('start');\r\n effect = input<NgxDrawerEffect>('slide');\r\n contentBehavior = input<NgxDrawerContentBehavior>('overlay');\r\n width = input<number>(280);\r\n swipeEdgeSize = input<number>(24);\r\n curtainStrips = input<number>(7);\r\n backdropClose = input<boolean>(true);\r\n swipeEnabled = input<boolean>(true);\r\n\r\n /** اگه true باشه، رد شدن از mobileBreakpoint به‌صورت زنده open رو با openOnDesktop/openOnMobile هماهنگ می‌کنه */\r\n respondToViewport = input<boolean>(true);\r\n openOnDesktop = input<boolean>(true);\r\n openOnMobile = input<boolean>(false);\r\n mobileBreakpoint = input<number>(768);\r\n\r\n /** state دوطرفه‌ی باز/بسته؛ با [(open)] قابل bind هست */\r\n open = model<boolean>(false);\r\n\r\n private readonly directionService = inject(DirectionService);\r\n private readonly doc = inject(DOCUMENT);\r\n private readonly destroyRef = inject(DestroyRef);\r\n\r\n /** فقط حین یه درگِ واقعی مقدار داره؛ null یعنی از روی open() تصمیم بگیر */\r\n protected readonly dragRatio = signal<number | null>(null);\r\n protected readonly isDragging = computed(() => this.dragRatio() !== null);\r\n protected readonly visualOpen = computed(() => this.dragRatio() ?? (this.open() ? 1 : 0));\r\n protected readonly strips = computed(() =>\r\n Array.from({ length: this.curtainStrips() }, (_, i) => i),\r\n );\r\n\r\n /**\r\n * +۱ یعنی این پنل فیزیکاً روی لبه‌ی چپِ صفحه‌ست، -۱ یعنی لبه‌ی راست —\r\n * برای transform:translateX() محتوای اصلی (که برخلاف inset-inline، به\r\n * dir=rtl خودکار واکنش نشون نمی‌ده) لازمه. reactive هست چون هم به side()\r\n * و هم به جهتِ زنده‌ی صفحه (directionService.isRtl()) وابسته‌ست.\r\n */\r\n protected readonly pushDirSign = computed(() => (this.isPhysicalLeftEdge() ? 1 : -1));\r\n\r\n /** برای افکت‌های keyframe‌محور (jelly/pull) — فقط لحظه‌ی رهاشدن (نه حین درگ زنده) پخش می‌شه */\r\n protected readonly playEffectClass = signal(false);\r\n\r\n private stopDrag?: () => void;\r\n private dragStartX = 0;\r\n private dragStartRatio = 0;\r\n private prevOpen = false;\r\n\r\n constructor() {\r\n // قفل اسکرول پس‌زمینه حین باز بودن پنل (فقط در حالت overlay واقعاً لازمه،\r\n // ولی در push/reveal هم بی‌ضرره و تجربه‌ی بهتری می‌ده)\r\n effect((onCleanup) => {\r\n if (this.open() && this.contentBehavior() === 'overlay') {\r\n const prevOverflow = this.doc.body.style.overflow;\r\n this.doc.body.style.overflow = 'hidden';\r\n onCleanup(() => {\r\n this.doc.body.style.overflow = prevOverflow;\r\n });\r\n }\r\n });\r\n\r\n // پخش انیمیشن keyframe‌محور فقط لحظه‌ای که open() واقعاً عوض می‌شه (نه هر CD)\r\n effect(() => {\r\n const isOpen = this.open();\r\n if (isOpen !== this.prevOpen) {\r\n this.prevOpen = isOpen;\r\n this.playEffectClass.set(true);\r\n const id = setTimeout(() => this.playEffectClass.set(false), 700);\r\n // پاک‌سازی در صورتی که کامپوننت زودتر destroy بشه\r\n this.destroyRef.onDestroy(() => clearTimeout(id));\r\n }\r\n });\r\n\r\n this.destroyRef.onDestroy(() => this.stopDrag?.());\r\n\r\n // هماهنگیِ زنده با breakpoint\r\n if (typeof window !== 'undefined') {\r\n const mql = window.matchMedia(`(min-width: ${this.mobileBreakpoint()}px)`);\r\n const applyForCurrentViewport = (isDesktop: boolean) => {\r\n if (this.respondToViewport()) {\r\n this.open.set(isDesktop ? this.openOnDesktop() : this.openOnMobile());\r\n }\r\n };\r\n applyForCurrentViewport(mql.matches);\r\n const handler = (e: MediaQueryListEvent) => applyForCurrentViewport(e.matches);\r\n mql.addEventListener('change', handler);\r\n this.destroyRef.onDestroy(() => mql.removeEventListener('change', handler));\r\n }\r\n }\r\n\r\n @HostListener('document:keydown.escape')\r\n protected onEscape(): void {\r\n if (this.open()) this.open.set(false);\r\n }\r\n\r\n protected closeFromBackdrop(): void {\r\n if (this.backdropClose()) this.open.set(false);\r\n }\r\n\r\n toggle(): void {\r\n this.open.update((o) => !o);\r\n }\r\n\r\n /** true یعنی این پنل فیزیکاً روی لبه‌ی چپِ صفحه‌ست (صرف‌نظر از start/end منطقی) */\r\n private isPhysicalLeftEdge(): boolean {\r\n const isRtl = this.directionService.isRtl();\r\n return this.side() === 'start' ? !isRtl : isRtl;\r\n }\r\n\r\n protected stripDelay(index: number): string {\r\n const count = this.curtainStrips();\r\n const order = this.open() ? index : count - 1 - index;\r\n return `${order * 28}ms`;\r\n }\r\n\r\n // ---------- درگ (هم برای باز کردن از لبه، هم بستن با کشیدنِ پنل) ----------\r\n protected onEdgeDragStart(ev: MouseEvent | TouchEvent): void {\r\n if (!this.swipeEnabled() || this.open()) return;\r\n this.beginDrag(ev, 0);\r\n }\r\n\r\n protected onPanelDragStart(ev: MouseEvent | TouchEvent): void {\r\n if (!this.open()) return;\r\n this.beginDrag(ev, 1);\r\n }\r\n\r\n private beginDrag(ev: MouseEvent | TouchEvent, startRatio: number): void {\r\n ev.preventDefault();\r\n this.dragStartX = this.clientXOf(ev);\r\n this.dragStartRatio = startRatio;\r\n this.dragRatio.set(startRatio);\r\n this.stopDrag?.();\r\n this.stopDrag = startDragSession({\r\n onMove: (moveEv) => {\r\n const dx = this.clientXOf(moveEv) - this.dragStartX;\r\n const opensToward = this.isPhysicalLeftEdge() ? 1 : -1;\r\n const signedRatio = (dx * opensToward) / this.width();\r\n const ratio = Math.min(1, Math.max(0, this.dragStartRatio + signedRatio));\r\n this.dragRatio.set(ratio);\r\n },\r\n onEnd: () => {\r\n const ratio = this.dragRatio() ?? this.dragStartRatio;\r\n this.open.set(ratio > 0.4);\r\n this.dragRatio.set(null);\r\n this.stopDrag = undefined;\r\n },\r\n });\r\n }\r\n\r\n private clientXOf(ev: MouseEvent | TouchEvent): number {\r\n return 'touches' in ev\r\n ? (ev.touches[0]?.clientX ?? ev.changedTouches[0]?.clientX ?? 0)\r\n : ev.clientX;\r\n }\r\n}\r\n","<div\r\n class=\"ngx-drawer-root\"\r\n [class]=\"'behavior-' + contentBehavior()\"\r\n [style.perspective.px]=\"1200\">\r\n @if (swipeEnabled() && !open()) {\r\n <div\r\n class=\"ngx-drawer-edge-zone\"\r\n [class.edge-start]=\"side() === 'start'\"\r\n [class.edge-end]=\"side() === 'end'\"\r\n [style.--ngx-drawer-edge-size]=\"swipeEdgeSize() + 'px'\"\r\n (mousedown)=\"onEdgeDragStart($event)\"\r\n (touchstart)=\"onEdgeDragStart($event)\"></div>\r\n }\r\n\r\n @if (visualOpen() > 0 && contentBehavior() === 'overlay') {\r\n <div\r\n class=\"ngx-drawer-backdrop\"\r\n [style.opacity]=\"visualOpen()\"\r\n [class.no-transition]=\"isDragging()\"\r\n (click)=\"closeFromBackdrop()\"></div>\r\n }\r\n\r\n <div\r\n class=\"ngx-drawer-main\"\r\n [class.no-transition]=\"isDragging()\"\r\n [style.--ngx-drawer-width]=\"width() + 'px'\"\r\n [style.--ngx-drawer-open]=\"visualOpen()\"\r\n [style.--ngx-drawer-dir]=\"pushDirSign()\">\r\n <ng-content></ng-content>\r\n\r\n @if (visualOpen() > 0 && contentBehavior() !== 'overlay') {\r\n <div\r\n class=\"ngx-drawer-main-dim\"\r\n [style.opacity]=\"visualOpen() * 0.35\"\r\n (click)=\"closeFromBackdrop()\"></div>\r\n }\r\n </div>\r\n\r\n <aside\r\n class=\"ngx-drawer-panel\"\r\n [class]=\"'effect-' + effect()\"\r\n [class.side-start]=\"side() === 'start'\"\r\n [class.side-end]=\"side() === 'end'\"\r\n [class.no-transition]=\"isDragging()\"\r\n [class.is-open]=\"open()\"\r\n [class.playing]=\"playEffectClass()\"\r\n [style.--ngx-drawer-width]=\"width() + 'px'\"\r\n [style.--ngx-drawer-open]=\"visualOpen()\"\r\n role=\"dialog\"\r\n aria-modal=\"true\">\r\n <div\r\n class=\"ngx-drawer-drag-handle\"\r\n [class.edge-start]=\"side() === 'start'\"\r\n [class.edge-end]=\"side() === 'end'\"\r\n (mousedown)=\"onPanelDragStart($event)\"\r\n (touchstart)=\"onPanelDragStart($event)\"></div>\r\n\r\n <div class=\"ngx-drawer-content\">\r\n <ng-content select=\"[drawerContent]\"></ng-content>\r\n </div>\r\n\r\n @if (effect() === 'curtain') {\r\n <div\r\n class=\"ngx-drawer-curtain\"\r\n [class.open]=\"open()\"\r\n [class.revealed]=\"visualOpen() >= 1 && !isDragging()\">\r\n @for (i of strips(); track i) {\r\n <div\r\n class=\"ngx-drawer-strip\"\r\n [class.side-start]=\"side() === 'start'\"\r\n [class.side-end]=\"side() === 'end'\"\r\n [style.transition-delay]=\"stripDelay(i)\"></div>\r\n }\r\n </div>\r\n }\r\n </aside>\r\n</div>\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ngx-kit-drawer-menu.mjs","sources":["../../../projects/libs/drawer-menu/components/drawer-menu.component.ts","../../../projects/libs/drawer-menu/components/drawer-menu.component.html","../../../projects/libs/drawer-menu/ngx-kit-drawer-menu.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n DOCUMENT,\n DestroyRef,\n computed,\n effect,\n inject,\n input,\n model,\n signal,\n} from '@angular/core';\nimport { DirectionService } from 'ngx-kit/shared';\nimport {\n NgxDrawerEffect,\n NgxDrawerMode,\n NgxDrawerResponsiveBehavior,\n NgxDrawerResponsiveConfig,\n NgxDrawerSide,\n} from '../contracts/drawer-menu-types';\n\n/**\n * Structural (not reference) equality for the `responsive` config.\n *\n * Consumers are expected to pass this as an inline object literal (see README),\n * which means the parent template creates a brand-new object on every change\n * detection run. Without this comparator, the `responsive` input signal sees a\n * \"change\" on every such run even when nothing actually changed, which re-triggers\n * the viewport-sync effect and forcibly resets `open` back to the configured\n * desktop/mobile default — silently overriding whatever the user just did by\n * dragging, clicking, or toggling the drawer.\n */\nfunction responsiveConfigsEqual(\n a: NgxDrawerResponsiveConfig,\n b: NgxDrawerResponsiveConfig,\n): boolean {\n return (\n a === b ||\n (a.mode === b.mode &&\n a.breakpoint === b.breakpoint &&\n a.desktopOpen === b.desktopOpen &&\n a.mobileOpen === b.mobileOpen &&\n a.desktopBehavior === b.desktopBehavior &&\n a.mobileBehavior === b.mobileBehavior &&\n a.respectPinned === b.respectPinned)\n );\n}\n\n@Component({\n selector: 'ngx-drawer-menu',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './drawer-menu.component.html',\n styleUrl: './drawer-menu.component.scss',\n host: {\n class: 'ngx-drawer-menu-host',\n '(keydown.escape)': 'onEscape()',\n },\n})\nexport class NgxDrawerMenuComponent {\n readonly side = input<NgxDrawerSide>('start');\n readonly mode = input<NgxDrawerMode>('overlay');\n /** When responsive mode is active, desktop/mobile can use different layout behavior. */\n readonly desktopBehavior = input<NgxDrawerResponsiveBehavior>('dock');\n readonly mobileBehavior = input<NgxDrawerResponsiveBehavior>('overlay');\n private readonly responsiveDesktopBehavior = signal<NgxDrawerResponsiveBehavior | null>(null);\n private readonly responsiveMobileBehavior = signal<NgxDrawerResponsiveBehavior | null>(null);\n readonly effect = input<NgxDrawerEffect>('fabric');\n\n readonly width = input<number>(300);\n readonly maxWidth = input<number>(420);\n readonly edgeSize = input<number>(34);\n readonly dragThreshold = input<number>(0.38);\n readonly velocityThreshold = input<number>(0.45);\n\n /** Opens/closes the panel from the edge and while the panel itself is dragged. */\n readonly swipeEnabled = input<boolean>(true);\n /** Allows closing by clicking the backdrop. */\n readonly backdropClose = input<boolean>(true);\n /** Allows Escape to close the drawer. */\n readonly escapeClose = input<boolean>(true);\n\n /** The drawer starts open unless explicitly configured otherwise. */\n readonly open = model<boolean>(true);\n /** Pinned drawers are intended for persistent desktop navigation. */\n readonly pinned = model<boolean>(false);\n\n /** Responsive behavior. Can be overridden with individual inputs below. */\n readonly responsive = input<NgxDrawerResponsiveConfig>(\n {\n mode: 'auto',\n breakpoint: 768,\n desktopOpen: true,\n mobileOpen: false,\n respectPinned: true,\n desktopBehavior: 'dock',\n mobileBehavior: 'overlay',\n } as any,\n // { equal: responsiveConfigsEqual },\n );\n\n /** Convenience aliases for the common responsive configuration. */\n readonly respondToViewport = input<boolean>(true);\n readonly mobileBreakpoint = input<number>(768);\n readonly openOnDesktop = input<boolean>(true);\n readonly openOnMobile = input<boolean>(false);\n\n /** Visual tuning. */\n readonly curtainStrips = input<number>(9);\n readonly backdropOpacity = input<number>(0.46);\n readonly transitionMs = input<number>(420);\n readonly focusOnOpen = input<boolean>(true);\n\n protected readonly dragProgress = signal<number | null>(null);\n protected readonly dragVelocity = signal<number>(0);\n protected readonly isMobile = signal<boolean>(false);\n protected readonly effectiveBehavior = computed<NgxDrawerResponsiveBehavior>(() => {\n if (!this.respondToViewport() || this.responsive().mode === 'off') {\n return this.mode() === 'push' ? 'dock' : 'overlay';\n }\n return this.isMobile()\n ? (this.responsiveMobileBehavior() ?? this.mobileBehavior())\n : (this.responsiveDesktopBehavior() ?? this.desktopBehavior());\n });\n protected readonly isDocked = computed(() =>\n this.respondToViewport() ? this.effectiveBehavior() === 'dock' : this.mode() === 'push',\n );\n protected readonly usesOverlay = computed(() => !this.isDocked());\n protected readonly isDragging = computed(() => this.dragProgress() !== null);\n protected readonly progress = computed(() => this.dragProgress() ?? (this.open() ? 1 : 0));\n protected readonly isActuallyOpen = computed(() => this.progress() > 0.001);\n protected readonly strips = computed(() =>\n Array.from({ length: Math.max(3, this.curtainStrips()) }, (_, i) => i),\n );\n\n /** Physical side: true means the drawer is attached to the physical left edge. */\n protected readonly isPhysicalLeft = computed(() => {\n const rtl = this.directionService.isRtl();\n return this.side() === 'start' ? !rtl : rtl;\n });\n\n protected readonly physicalSign = computed(() => (this.isPhysicalLeft() ? 1 : -1));\n protected readonly effectiveMode = computed<NgxDrawerMode>(() => {\n if (!this.respondToViewport() || this.responsive().mode === 'off') return this.mode();\n return this.effectiveBehavior() === 'dock' ? 'push' : 'overlay';\n });\n protected readonly duration = computed(() => `${this.transitionMs()}ms`);\n\n private readonly directionService = inject(DirectionService);\n private readonly document = inject(DOCUMENT);\n private readonly destroyRef = inject(DestroyRef);\n\n private pointerId: number | null = null;\n private dragStartX = 0;\n private dragStartProgress = 0;\n private dragLastX = 0;\n private dragLastTime = 0;\n private lastVelocity = 0;\n private activePointerTarget: HTMLElement | null = null;\n private resizeObserver?: ResizeObserver;\n private mediaQuery?: MediaQueryList;\n private mediaQueryListener?: (event: MediaQueryListEvent) => void;\n private lastManagedViewportState: boolean | null = null;\n\n constructor() {\n effect((onCleanup) => {\n const locked = this.open() && this.effectiveMode() === 'overlay';\n if (!locked) return;\n\n const body = this.document.body;\n const previous = body.style.overflow;\n body.style.overflow = 'hidden';\n onCleanup(() => (body.style.overflow = previous));\n });\n\n effect(() => {\n const config = this.responsive();\n const enabled = this.respondToViewport() && config.mode !== 'off';\n const breakpoint = config.breakpoint ?? this.mobileBreakpoint();\n const desktopOpen = config.desktopOpen ?? this.openOnDesktop();\n const mobileOpen = config.mobileOpen ?? this.openOnMobile();\n const desktopBehavior = config.desktopBehavior ?? this.desktopBehavior();\n const mobileBehavior = config.mobileBehavior ?? this.mobileBehavior();\n this.responsiveDesktopBehavior.set(desktopBehavior);\n this.responsiveMobileBehavior.set(mobileBehavior);\n\n this.setupViewportSync(\n enabled,\n breakpoint,\n desktopOpen,\n mobileOpen,\n config.respectPinned ?? true,\n );\n });\n\n this.destroyRef.onDestroy(() => {\n this.disposePointer();\n this.disposeViewportSync();\n });\n }\n\n toggle(): void {\n if (this.pinned() && this.open()) return;\n this.open.update((value) => !value);\n }\n\n openDrawer(): void {\n this.open.set(true);\n }\n\n closeDrawer(): void {\n if (!this.pinned()) this.open.set(false);\n }\n\n pin(): void {\n this.pinned.set(true);\n this.open.set(true);\n }\n\n unpin(): void {\n this.pinned.set(false);\n }\n\n protected onEscape(): void {\n if (this.escapeClose() && !this.pinned()) this.closeDrawer();\n }\n\n protected onBackdropPointerDown(event: PointerEvent): void {\n if (!this.backdropClose() || this.pinned() || !this.usesOverlay()) return;\n event.preventDefault();\n this.closeDrawer();\n }\n\n protected onEdgePointerDown(event: PointerEvent): void {\n if (!this.swipeEnabled() || this.open() || this.pinned()) return;\n this.beginDrag(event, 0);\n }\n\n protected onPanelPointerDown(event: PointerEvent): void {\n if (!this.swipeEnabled() || !this.open() || this.pinned()) return;\n if (event.button !== 0) return;\n this.beginDrag(event, 1);\n }\n\n private beginDrag(event: PointerEvent, startProgress: number): void {\n if (this.pointerId !== null) return;\n\n const target = event.currentTarget as HTMLElement | null;\n if (!target) return;\n\n this.pointerId = event.pointerId;\n this.activePointerTarget = target;\n this.dragStartX = event.clientX;\n this.dragLastX = event.clientX;\n this.dragLastTime = performance.now();\n this.dragStartProgress = startProgress;\n this.lastVelocity = 0;\n this.dragProgress.set(startProgress);\n\n target.setPointerCapture?.(event.pointerId);\n event.preventDefault();\n\n target.addEventListener('pointermove', this.onPointerMove);\n target.addEventListener('pointerup', this.onPointerUp);\n target.addEventListener('pointercancel', this.onPointerCancel);\n }\n\n private readonly onPointerMove = (event: PointerEvent): void => {\n if (event.pointerId !== this.pointerId) return;\n\n const now = performance.now();\n const dx = event.clientX - this.dragStartX;\n const signedDistance = dx * this.physicalSign();\n const next = this.clamp01(this.dragStartProgress + signedDistance / this.width());\n\n const dt = Math.max(8, now - this.dragLastTime);\n this.lastVelocity = ((event.clientX - this.dragLastX) * this.physicalSign()) / dt;\n this.dragVelocity.set(this.lastVelocity);\n this.dragLastX = event.clientX;\n this.dragLastTime = now;\n\n this.dragProgress.set(next);\n event.preventDefault();\n };\n\n private readonly onPointerUp = (event: PointerEvent): void => {\n if (event.pointerId !== this.pointerId) return;\n\n const progress = this.dragProgress() ?? this.dragStartProgress;\n const velocity = this.dragVelocity();\n const opening = velocity > this.velocityThreshold();\n const closing = velocity < -this.velocityThreshold();\n\n let shouldOpen: boolean;\n if (opening) shouldOpen = true;\n else if (closing) shouldOpen = false;\n else shouldOpen = progress >= this.dragThreshold();\n\n this.open.set(shouldOpen);\n this.dragProgress.set(null);\n this.dragVelocity.set(0);\n this.disposePointer(event.pointerId);\n };\n\n private readonly onPointerCancel = (event: PointerEvent): void => {\n if (event.pointerId !== this.pointerId) return;\n const progress = this.dragProgress() ?? this.dragStartProgress;\n this.open.set(progress >= 0.5);\n this.dragProgress.set(null);\n this.dragVelocity.set(0);\n this.disposePointer(event.pointerId);\n };\n\n private disposePointer(pointerId?: number): void {\n if (pointerId !== undefined && this.pointerId !== pointerId) return;\n\n const target = this.activePointerTarget;\n if (target) {\n target.removeEventListener('pointermove', this.onPointerMove);\n target.removeEventListener('pointerup', this.onPointerUp);\n target.removeEventListener('pointercancel', this.onPointerCancel);\n if (this.pointerId !== null) {\n try {\n target.releasePointerCapture?.(this.pointerId);\n } catch {\n // Pointer capture may already be released by the browser.\n }\n }\n }\n\n this.pointerId = null;\n this.activePointerTarget = null;\n }\n\n private setupViewportSync(\n enabled: boolean,\n breakpoint: number,\n desktopOpen: boolean,\n mobileOpen: boolean,\n respectPinned: boolean,\n ): void {\n this.disposeViewportSync();\n if (!enabled || typeof window === 'undefined') {\n this.isMobile.set(false);\n return;\n }\n\n this.mediaQuery = window.matchMedia(`(max-width: ${Math.max(0, breakpoint - 0.02)}px)`);\n\n const apply = (isMobile: boolean) => {\n this.isMobile.set(isMobile);\n if (respectPinned && this.pinned()) return;\n\n const next = isMobile ? mobileOpen : desktopOpen;\n if (this.lastManagedViewportState === next) return;\n this.lastManagedViewportState = next;\n this.open.set(next);\n };\n\n apply(this.mediaQuery.matches);\n this.mediaQueryListener = (event) => apply(event.matches);\n this.mediaQuery.addEventListener('change', this.mediaQueryListener);\n }\n\n private disposeViewportSync(): void {\n if (this.mediaQuery && this.mediaQueryListener) {\n this.mediaQuery.removeEventListener('change', this.mediaQueryListener);\n }\n this.mediaQuery = undefined;\n this.mediaQueryListener = undefined;\n this.lastManagedViewportState = null;\n }\n\n private clamp01(value: number): number {\n return Math.max(0, Math.min(1, value));\n }\n}\n","<div\n class=\"ngx-drawer\"\n [class.is-open]=\"isActuallyOpen()\"\n [class.is-dragging]=\"isDragging()\"\n [class.is-pinned]=\"pinned()\"\n [class.is-docked]=\"isDocked()\"\n [class.is-overlay]=\"usesOverlay()\"\n [class.side-start]=\"side() === 'start'\"\n [class.side-end]=\"side() === 'end'\"\n [class.physical-left]=\"isPhysicalLeft()\"\n [class.physical-right]=\"!isPhysicalLeft()\"\n [class.mode-overlay]=\"effectiveMode() === 'overlay'\"\n [class.mode-push]=\"effectiveMode() === 'push'\"\n [class.mode-reveal]=\"effectiveMode() === 'reveal'\"\n [class.effect-slide]=\"effect() === 'slide'\"\n [class.effect-spring]=\"effect() === 'spring'\"\n [class.effect-fabric]=\"effect() === 'fabric'\"\n [class.effect-curtain]=\"effect() === 'curtain'\"\n [class.effect-elastic]=\"effect() === 'elastic'\"\n [class.effect-reveal]=\"effect() === 'reveal'\"\n [style.--ngx-progress]=\"progress()\"\n [style.--ngx-width.px]=\"width()\"\n [style.--ngx-edge-size.px]=\"edgeSize()\"\n [style.--ngx-max-width.px]=\"maxWidth()\"\n [style.--ngx-duration]=\"duration()\"\n [style.--ngx-backdrop-opacity]=\"backdropOpacity()\"\n [style.--ngx-physical-sign]=\"physicalSign()\"\n [style.--ngx-closed-translate.px]=\"(1 - progress()) * -width() * physicalSign()\"\n [style.--ngx-transform-origin]=\"isPhysicalLeft() ? 'left center' : 'right center'\"\n [style.--ngx-fabric-skew]=\"(1 - progress()) * 10 + 'deg'\">\n @if (swipeEnabled() && !isActuallyOpen() && !pinned()) {\n <div\n class=\"ngx-drawer-edge-zone\"\n [class.edge-start]=\"side() === 'start'\"\n [class.edge-end]=\"side() === 'end'\"\n (pointerdown)=\"onEdgePointerDown($event)\"\n aria-hidden=\"true\"></div>\n }\n\n @if (isActuallyOpen() && usesOverlay()) {\n <button\n class=\"ngx-drawer-backdrop\"\n type=\"button\"\n tabindex=\"-1\"\n aria-label=\"Close navigation\"\n (pointerdown)=\"onBackdropPointerDown($event)\"></button>\n }\n\n <main class=\"ngx-drawer-main\">\n <ng-content></ng-content>\n </main>\n\n <aside\n class=\"ngx-drawer-panel\"\n [attr.aria-hidden]=\"!isActuallyOpen()\"\n [attr.inert]=\"!isActuallyOpen() ? '' : null\"\n role=\"navigation\">\n <div class=\"ngx-drawer-fabric\" aria-hidden=\"true\">\n <div class=\"ngx-fabric-fold fold-1\"></div>\n <div class=\"ngx-fabric-fold fold-2\"></div>\n <div class=\"ngx-fabric-fold fold-3\"></div>\n <div class=\"ngx-fabric-fold fold-4\"></div>\n <div class=\"ngx-fabric-edge\"></div>\n </div>\n\n <!-- Full-height drag affordance at the physical edge of the panel. -->\n @if (swipeEnabled() && !pinned()) {\n <div\n class=\"ngx-drawer-drag-handle\"\n [class.handle-start]=\"side() === 'start'\"\n [class.handle-end]=\"side() === 'end'\"\n (pointerdown)=\"onPanelPointerDown($event)\"\n aria-hidden=\"true\">\n <span></span>\n </div>\n }\n\n <div class=\"ngx-drawer-inner\">\n <div class=\"ngx-drawer-content\">\n <ng-content select=\"[drawerContent]\"></ng-content>\n </div>\n </div>\n\n @if (effect() === 'curtain') {\n <div class=\"ngx-drawer-curtain\" aria-hidden=\"true\">\n @for (i of strips(); track i) {\n <span\n class=\"ngx-drawer-strip\"\n [style.--strip-index]=\"i\"\n [style.--strip-count]=\"curtainStrips()\"></span>\n }\n </div>\n }\n </aside>\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
@@ -573,11 +573,11 @@ class NgxImageEditorComponent {
573
573
  }
574
574
  }
575
575
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: NgxImageEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
576
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.4", type: NgxImageEditorComponent, isStandalone: true, selector: "ngx-image-editor", inputs: { source: { classPropertyName: "source", publicName: "source", isSignal: true, isRequired: false, transformFunction: null }, aspectRatio: { classPropertyName: "aspectRatio", publicName: "aspectRatio", isSignal: true, isRequired: false, transformFunction: null }, outputMaxWidth: { classPropertyName: "outputMaxWidth", publicName: "outputMaxWidth", isSignal: true, isRequired: false, transformFunction: null }, outputMaxHeight: { classPropertyName: "outputMaxHeight", publicName: "outputMaxHeight", isSignal: true, isRequired: false, transformFunction: null }, outputType: { classPropertyName: "outputType", publicName: "outputType", isSignal: true, isRequired: false, transformFunction: null }, filters: { classPropertyName: "filters", publicName: "filters", isSignal: true, isRequired: false, transformFunction: null }, quality: { classPropertyName: "quality", publicName: "quality", isSignal: true, isRequired: false, transformFunction: null }, localize: { classPropertyName: "localize", publicName: "localize", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { saved: "saved", cancelled: "cancelled" }, host: { classAttribute: "ngx-image-editor-host" }, viewQueries: [{ propertyName: "stageWrapEl", first: true, predicate: ["stageWrap"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (loading()) {\n <div class=\"ngx-ie-state\">{{ localize().LoadingImage }}</div>\n} @else if (loadError()) {\n <div class=\"ngx-ie-state ngx-ie-state--error\">{{ loadError() }}</div>\n} @else if (stageImageUrl()) {\n <div class=\"ngx-ie-layout\">\n <div class=\"ngx-ie-stage-wrap\" #stageWrap>\n <div\n class=\"ngx-ie-stage\"\n [style.width.px]=\"stageSize().width\"\n [style.height.px]=\"stageSize().height\">\n <img class=\"ngx-ie-stage-img\" [src]=\"stageImageUrl()\" alt=\"\" draggable=\"false\" />\n\n <div\n class=\"ngx-ie-crop-box\"\n [style.left]=\"cropOverlayStyle().left\"\n [style.top]=\"cropOverlayStyle().top\"\n [style.width]=\"cropOverlayStyle().width\"\n [style.height]=\"cropOverlayStyle().height\"\n ngxPointerDrag\n (dragStart)=\"onMoveDragStart()\"\n (dragMove)=\"onMoveDragMove($event)\">\n <span\n class=\"ngx-ie-handle ngx-ie-handle--nw\"\n ngxPointerDrag\n (dragStart)=\"onResizeDragStart()\"\n (dragMove)=\"onResizeDragMove('nw', $event)\"></span>\n <span\n class=\"ngx-ie-handle ngx-ie-handle--ne\"\n ngxPointerDrag\n (dragStart)=\"onResizeDragStart()\"\n (dragMove)=\"onResizeDragMove('ne', $event)\"></span>\n <span\n class=\"ngx-ie-handle ngx-ie-handle--sw\"\n ngxPointerDrag\n (dragStart)=\"onResizeDragStart()\"\n (dragMove)=\"onResizeDragMove('sw', $event)\"></span>\n <span\n class=\"ngx-ie-handle ngx-ie-handle--se\"\n ngxPointerDrag\n (dragStart)=\"onResizeDragStart()\"\n (dragMove)=\"onResizeDragMove('se', $event)\"></span>\n </div>\n </div>\n </div>\n\n <div class=\"ngx-ie-panel-row\">\n <div class=\"ngx-ie-panel\">\n <div class=\"ngx-ie-preview\">\n @if (previewUrl(); as url) {\n <img [src]=\"url\" alt=\"Preview\" />\n }\n </div>\n\n <div class=\"ngx-ie-row ngx-ie-rotate-row\">\n <button type=\"button\" (click)=\"rotateBy(-90)\" title=\"Rotate 90\u00B0 left\">\u27F2 90</button>\n <button type=\"button\" (click)=\"rotateBy(90)\" title=\"Rotate 90\u00B0 right\">\u27F3 90</button>\n </div>\n\n <label class=\"ngx-ie-field\">\n <slider\n [ngModel]=\"rotation()\"\n (ngModelChange)=\"rotation.set($event)\"\n [min]=\"-180\"\n [max]=\"180\">\n <span>{{ localize().Rotation }} ({{ rotation() }}\u00B0)</span>\n </slider>\n\n <button\n type=\"button\"\n (click)=\"rotation.set(0)\"\n class=\"ngx-ie-btn-secondary\"\n [title]=\"localize().Reset\">\n x\n </button>\n </label>\n\n <label class=\"ngx-ie-field\">\n <slider\n [ngModel]=\"brightness()\"\n (ngModelChange)=\"brightness.set($event)\"\n [min]=\"0\"\n [max]=\"200\">\n <span>{{ localize().Brightness }} ({{ brightness() }}%)</span>\n </slider>\n <button\n type=\"button\"\n (click)=\"brightness.set(100)\"\n class=\"ngx-ie-btn-secondary\"\n [title]=\"localize().Reset\">\n x\n </button>\n </label>\n\n <label class=\"ngx-ie-field\">\n <slider\n [ngModel]=\"contrast()\"\n (ngModelChange)=\"contrast.set($event)\"\n [min]=\"0\"\n [max]=\"200\">\n <span>{{ localize().Contrast }} ({{ contrast() }}%)</span>\n </slider>\n <button\n type=\"button\"\n (click)=\"contrast.set(100)\"\n class=\"ngx-ie-btn-secondary\"\n [title]=\"localize().Reset\">\n x\n </button>\n </label>\n\n <label class=\"ngx-ie-field\">\n <slider\n [ngModel]=\"saturation()\"\n (ngModelChange)=\"saturation.set($event)\"\n [min]=\"0\"\n [max]=\"200\">\n <span>{{ localize().Saturation }} ({{ saturation() }}%)</span>\n </slider>\n <button\n type=\"button\"\n (click)=\"saturation.set(100)\"\n class=\"ngx-ie-btn-secondary\"\n [title]=\"localize().Reset\">\n x\n </button>\n </label>\n\n @if (filters().length) {\n <div>\n <span>{{ localize().Filter }}</span>\n <div class=\"ngx-ie-filter-row\">\n @for (f of filters(); track f) {\n <button type=\"button\" [class.active]=\"filterPreset() === f\" (click)=\"setFilter(f)\">\n {{ filterLabels()[f] }}\n </button>\n }\n </div>\n </div>\n }\n\n <div class=\"ngx-ie-row ngx-ie-actions\">\n <button type=\"button\" class=\"ngx-ie-btn-secondary\" (click)=\"cancel()\">\n {{ localize().Cancel }}\n </button>\n <button type=\"button\" class=\"ngx-ie-btn-primary\" [disabled]=\"saving()\" (click)=\"save()\">\n {{ saving() ? localize().Saving : localize().Save }}\n </button>\n </div>\n </div>\n </div>\n </div>\n}\n", styles: ["@charset \"UTF-8\";:host{display:block;min-height:70dvh;--ngx-image-editor-panel-width: 25%}.ngx-ie-state{padding:2rem;text-align:center;color:light-dark(#6b7280,#9ca3af)}.ngx-ie-state--error{color:light-dark(#b91c1c,#f87171)}.ngx-ie-layout{display:grid;grid-template-columns:1fr var(--ngx-image-editor-panel-width, 30%);gap:1.25rem;height:100%}.ngx-ie-stage-wrap{width:100%;display:flex;align-items:center;justify-content:center;background:light-dark(#f3f4f6,#18181b);border-radius:10px;overflow:hidden;flex-shrink:0}.ngx-ie-stage{position:relative;touch-action:none;-webkit-user-select:none;user-select:none;direction:ltr}.ngx-ie-stage-img{display:block;inline-size:100%;block-size:100%;border-radius:4px;pointer-events:none;background:#fff;background-image:linear-gradient(45deg,#ccc 25%,transparent 25%),linear-gradient(-45deg,#ccc 25%,transparent 25%),linear-gradient(45deg,transparent 75%,#ccc 75%),linear-gradient(-45deg,transparent 75%,#ccc 75%);background-size:16px 16px;background-position:0 0,0 8px,8px -8px,-8px 0px}.ngx-ie-crop-box{position:absolute;box-sizing:border-box;border:2px solid #2563eb;box-shadow:0 0 0 9999px #00000073;cursor:move;touch-action:none}.ngx-ie-handle{position:absolute;inline-size:14px;block-size:14px;background:#fff;border:2px solid #2563eb;border-radius:50%;touch-action:none}.ngx-ie-handle--nw{inset-inline-start:-7px;inset-block-start:-7px;cursor:nwse-resize}.ngx-ie-handle--ne{inset-inline-end:-7px;inset-block-start:-7px;cursor:nesw-resize}.ngx-ie-handle--sw{inset-inline-start:-7px;inset-block-end:-7px;cursor:nesw-resize}.ngx-ie-handle--se{inset-inline-end:-7px;inset-block-end:-7px;cursor:nwse-resize}.ngx-ie-panel{flex:1;display:flex;flex-direction:column;gap:.75rem}.ngx-ie-panel-row{display:flex;flex-wrap:wrap;gap:1.25rem}.ngx-ie-preview{display:flex;align-items:center;justify-content:center;min-block-size:100px;background:light-dark(#f3f4f6,#18181b);border-radius:8px;overflow:hidden}.ngx-ie-preview img{max-inline-size:100%;max-block-size:160px;display:block;background:#fff;background-image:linear-gradient(45deg,#ccc 25%,transparent 25%),linear-gradient(-45deg,#ccc 25%,transparent 25%),linear-gradient(45deg,transparent 75%,#ccc 75%),linear-gradient(-45deg,transparent 75%,#ccc 75%);background-size:16px 16px;background-position:0 0,0 8px,8px -8px,-8px 0px}.ngx-ie-field{display:flex;gap:.3rem;align-items:flex-end}.ngx-ie-field slider{flex:1}.ngx-ie-row{display:flex;gap:.5rem}.ngx-ie-rotate-row button,.ngx-ie-filter-row button{appearance:none;border:1px solid light-dark(#e5e7eb,#33333a);background:light-dark(#ffffff,#232327);color:light-dark(#374151,#d4d4d8);border-radius:999px;padding:.4rem .85rem;font-size:.75rem;cursor:pointer;transition:background-color .15s ease,border-color .15s ease,transform .15s ease,color .15s ease}.ngx-ie-rotate-row button:hover,.ngx-ie-filter-row button:hover{background:light-dark(#f3f4f6,#2c2c31);transform:translateY(-1px)}.ngx-ie-rotate-row button:active,.ngx-ie-filter-row button:active{transform:translateY(0)}.ngx-ie-rotate-row button.active,.ngx-ie-filter-row button.active{background:light-dark(#2563eb,#3b82f6);border-color:light-dark(#2563eb,#3b82f6);color:#fff;box-shadow:0 2px 10px light-dark(rgba(37,99,235,.3),rgba(59,130,246,.3))}.ngx-ie-filter-row{display:flex;flex-wrap:wrap;gap:.4rem}.ngx-ie-actions{margin-block-start:auto;justify-content:flex-end}.ngx-ie-btn-primary,.ngx-ie-btn-secondary{appearance:none;border:none;border-radius:8px;padding:.55rem 1.1rem;font-size:.85rem;cursor:pointer;font-weight:500;transition:transform .15s ease,box-shadow .15s ease,opacity .15s ease}.ngx-ie-btn-primary:hover,.ngx-ie-btn-secondary:hover{transform:translateY(-1px)}.ngx-ie-btn-primary:active,.ngx-ie-btn-secondary:active{transform:translateY(0)}.ngx-ie-btn-primary{background:light-dark(#2563eb,#3b82f6);color:#fff;box-shadow:0 2px 10px light-dark(rgba(37,99,235,.25),rgba(59,130,246,.25))}.ngx-ie-btn-primary:disabled{opacity:.6;cursor:not-allowed;transform:none}.ngx-ie-btn-secondary{background:light-dark(#e5e7eb,#3f3f46);color:light-dark(#374151,#e4e4e7)}@media(max-width:768px){:host{height:unset!important}.ngx-ie-layout{display:flex;flex-direction:column}}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: SliderComponent, selector: "slider", inputs: ["step", "min", "max", "background", "isBgTransparent"], outputs: ["change"] }, { kind: "directive", type: NgxPointerDragDirective, selector: "[ngxPointerDrag]", outputs: ["dragStart", "dragMove", "dragEnd"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
576
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.4", type: NgxImageEditorComponent, isStandalone: true, selector: "ngx-image-editor", inputs: { source: { classPropertyName: "source", publicName: "source", isSignal: true, isRequired: false, transformFunction: null }, aspectRatio: { classPropertyName: "aspectRatio", publicName: "aspectRatio", isSignal: true, isRequired: false, transformFunction: null }, outputMaxWidth: { classPropertyName: "outputMaxWidth", publicName: "outputMaxWidth", isSignal: true, isRequired: false, transformFunction: null }, outputMaxHeight: { classPropertyName: "outputMaxHeight", publicName: "outputMaxHeight", isSignal: true, isRequired: false, transformFunction: null }, outputType: { classPropertyName: "outputType", publicName: "outputType", isSignal: true, isRequired: false, transformFunction: null }, filters: { classPropertyName: "filters", publicName: "filters", isSignal: true, isRequired: false, transformFunction: null }, quality: { classPropertyName: "quality", publicName: "quality", isSignal: true, isRequired: false, transformFunction: null }, localize: { classPropertyName: "localize", publicName: "localize", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { saved: "saved", cancelled: "cancelled" }, host: { classAttribute: "ngx-image-editor-host" }, viewQueries: [{ propertyName: "stageWrapEl", first: true, predicate: ["stageWrap"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (loading()) {\r\n <div class=\"ngx-ie-state\">{{ localize().LoadingImage }}</div>\r\n} @else if (loadError()) {\r\n <div class=\"ngx-ie-state ngx-ie-state--error\">{{ loadError() }}</div>\r\n} @else if (stageImageUrl()) {\r\n <div class=\"ngx-ie-layout\">\r\n <div class=\"ngx-ie-stage-wrap\" #stageWrap>\r\n <div\r\n class=\"ngx-ie-stage\"\r\n [style.width.px]=\"stageSize().width\"\r\n [style.height.px]=\"stageSize().height\">\r\n <img class=\"ngx-ie-stage-img\" [src]=\"stageImageUrl()\" alt=\"\" draggable=\"false\" />\r\n\r\n <div\r\n class=\"ngx-ie-crop-box\"\r\n [style.left]=\"cropOverlayStyle().left\"\r\n [style.top]=\"cropOverlayStyle().top\"\r\n [style.width]=\"cropOverlayStyle().width\"\r\n [style.height]=\"cropOverlayStyle().height\"\r\n ngxPointerDrag\r\n (dragStart)=\"onMoveDragStart()\"\r\n (dragMove)=\"onMoveDragMove($event)\">\r\n <span\r\n class=\"ngx-ie-handle ngx-ie-handle--nw\"\r\n ngxPointerDrag\r\n (dragStart)=\"onResizeDragStart()\"\r\n (dragMove)=\"onResizeDragMove('nw', $event)\"></span>\r\n <span\r\n class=\"ngx-ie-handle ngx-ie-handle--ne\"\r\n ngxPointerDrag\r\n (dragStart)=\"onResizeDragStart()\"\r\n (dragMove)=\"onResizeDragMove('ne', $event)\"></span>\r\n <span\r\n class=\"ngx-ie-handle ngx-ie-handle--sw\"\r\n ngxPointerDrag\r\n (dragStart)=\"onResizeDragStart()\"\r\n (dragMove)=\"onResizeDragMove('sw', $event)\"></span>\r\n <span\r\n class=\"ngx-ie-handle ngx-ie-handle--se\"\r\n ngxPointerDrag\r\n (dragStart)=\"onResizeDragStart()\"\r\n (dragMove)=\"onResizeDragMove('se', $event)\"></span>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"ngx-ie-panel-row\">\r\n <div class=\"ngx-ie-panel\">\r\n <div class=\"ngx-ie-preview\">\r\n @if (previewUrl(); as url) {\r\n <img [src]=\"url\" alt=\"Preview\" />\r\n }\r\n </div>\r\n\r\n <div class=\"ngx-ie-row ngx-ie-rotate-row\">\r\n <button type=\"button\" (click)=\"rotateBy(-90)\" title=\"Rotate 90\u00B0 left\">\u27F2 90</button>\r\n <button type=\"button\" (click)=\"rotateBy(90)\" title=\"Rotate 90\u00B0 right\">\u27F3 90</button>\r\n </div>\r\n\r\n <div class=\"ngx-ie-field\">\r\n <slider\r\n [ngModel]=\"rotation()\"\r\n (ngModelChange)=\"rotation.set($event)\"\r\n [min]=\"-180\"\r\n [max]=\"180\">\r\n <span>{{ localize().Rotation }} ({{ rotation() }}\u00B0)</span>\r\n </slider>\r\n\r\n <button\r\n type=\"button\"\r\n (click)=\"rotation.set(0)\"\r\n class=\"ngx-ie-btn-secondary\"\r\n [title]=\"localize().Reset\">\r\n x\r\n </button>\r\n </div>\r\n\r\n <div class=\"ngx-ie-field\">\r\n <slider\r\n [ngModel]=\"brightness()\"\r\n (ngModelChange)=\"brightness.set($event)\"\r\n [min]=\"0\"\r\n [max]=\"200\">\r\n <span>{{ localize().Brightness }} ({{ brightness() }}%)</span>\r\n </slider>\r\n <button\r\n type=\"button\"\r\n (click)=\"brightness.set(100)\"\r\n class=\"ngx-ie-btn-secondary\"\r\n [title]=\"localize().Reset\">\r\n x\r\n </button>\r\n </div>\r\n\r\n <div class=\"ngx-ie-field\">\r\n <slider\r\n [ngModel]=\"contrast()\"\r\n (ngModelChange)=\"contrast.set($event)\"\r\n [min]=\"0\"\r\n [max]=\"200\">\r\n <span>{{ localize().Contrast }} ({{ contrast() }}%)</span>\r\n </slider>\r\n <button\r\n type=\"button\"\r\n (click)=\"contrast.set(100)\"\r\n class=\"ngx-ie-btn-secondary\"\r\n [title]=\"localize().Reset\">\r\n x\r\n </button>\r\n </div>\r\n\r\n <div class=\"ngx-ie-field\">\r\n <slider\r\n [ngModel]=\"saturation()\"\r\n (ngModelChange)=\"saturation.set($event)\"\r\n [min]=\"0\"\r\n [max]=\"200\">\r\n <span>{{ localize().Saturation }} ({{ saturation() }}%)</span>\r\n </slider>\r\n <button\r\n type=\"button\"\r\n (click)=\"saturation.set(100)\"\r\n class=\"ngx-ie-btn-secondary\"\r\n [title]=\"localize().Reset\">\r\n x\r\n </button>\r\n </div>\r\n\r\n @if (filters().length) {\r\n <div>\r\n <span>{{ localize().Filter }}</span>\r\n <div class=\"ngx-ie-filter-row\">\r\n @for (f of filters(); track f) {\r\n <button type=\"button\" [class.active]=\"filterPreset() === f\" (click)=\"setFilter(f)\">\r\n {{ filterLabels()[f] }}\r\n </button>\r\n }\r\n </div>\r\n </div>\r\n }\r\n\r\n <div class=\"ngx-ie-row ngx-ie-actions\">\r\n <button type=\"button\" class=\"ngx-ie-btn-secondary\" (click)=\"cancel()\">\r\n {{ localize().Cancel }}\r\n </button>\r\n <button type=\"button\" class=\"ngx-ie-btn-primary\" [disabled]=\"saving()\" (click)=\"save()\">\r\n {{ saving() ? localize().Saving : localize().Save }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n}\r\n", styles: ["@charset \"UTF-8\";:host{display:block;min-height:70dvh;--ngx-image-editor-panel-width: 25%}.ngx-ie-state{padding:2rem;text-align:center;color:light-dark(#6b7280,#9ca3af)}.ngx-ie-state--error{color:light-dark(#b91c1c,#f87171)}.ngx-ie-layout{display:grid;grid-template-columns:1fr var(--ngx-image-editor-panel-width, 30%);gap:1.25rem;height:100%}.ngx-ie-stage-wrap{width:100%;display:flex;align-items:center;justify-content:center;background:light-dark(#f3f4f6,#18181b);border-radius:10px;overflow:hidden;flex-shrink:0}.ngx-ie-stage{position:relative;touch-action:none;-webkit-user-select:none;user-select:none;direction:ltr}.ngx-ie-stage-img{display:block;inline-size:100%;block-size:100%;border-radius:4px;pointer-events:none;background:#fff;background-image:linear-gradient(45deg,#ccc 25%,transparent 25%),linear-gradient(-45deg,#ccc 25%,transparent 25%),linear-gradient(45deg,transparent 75%,#ccc 75%),linear-gradient(-45deg,transparent 75%,#ccc 75%);background-size:16px 16px;background-position:0 0,0 8px,8px -8px,-8px 0px}.ngx-ie-crop-box{position:absolute;box-sizing:border-box;border:2px solid #2563eb;box-shadow:0 0 0 9999px #00000073;cursor:move;touch-action:none}.ngx-ie-handle{position:absolute;inline-size:14px;block-size:14px;background:#fff;border:2px solid #2563eb;border-radius:50%;touch-action:none}.ngx-ie-handle--nw{inset-inline-start:-7px;inset-block-start:-7px;cursor:nwse-resize}.ngx-ie-handle--ne{inset-inline-end:-7px;inset-block-start:-7px;cursor:nesw-resize}.ngx-ie-handle--sw{inset-inline-start:-7px;inset-block-end:-7px;cursor:nesw-resize}.ngx-ie-handle--se{inset-inline-end:-7px;inset-block-end:-7px;cursor:nwse-resize}.ngx-ie-panel{flex:1;display:flex;flex-direction:column;gap:.75rem}.ngx-ie-panel-row{display:flex;flex-wrap:wrap;gap:1.25rem}.ngx-ie-preview{display:flex;align-items:center;justify-content:center;min-block-size:100px;background:light-dark(#f3f4f6,#18181b);border-radius:8px;overflow:hidden}.ngx-ie-preview img{max-inline-size:100%;max-block-size:160px;display:block;background:#fff;background-image:linear-gradient(45deg,#ccc 25%,transparent 25%),linear-gradient(-45deg,#ccc 25%,transparent 25%),linear-gradient(45deg,transparent 75%,#ccc 75%),linear-gradient(-45deg,transparent 75%,#ccc 75%);background-size:16px 16px;background-position:0 0,0 8px,8px -8px,-8px 0px}.ngx-ie-field{display:flex;gap:.3rem;align-items:flex-end}.ngx-ie-field slider{flex:1}.ngx-ie-row{display:flex;gap:.5rem}.ngx-ie-rotate-row button,.ngx-ie-filter-row button{appearance:none;border:1px solid light-dark(#e5e7eb,#33333a);background:light-dark(#ffffff,#232327);color:light-dark(#374151,#d4d4d8);border-radius:999px;padding:.4rem .85rem;font-size:.75rem;cursor:pointer;transition:background-color .15s ease,border-color .15s ease,transform .15s ease,color .15s ease}.ngx-ie-rotate-row button:hover,.ngx-ie-filter-row button:hover{background:light-dark(#f3f4f6,#2c2c31);transform:translateY(-1px)}.ngx-ie-rotate-row button:active,.ngx-ie-filter-row button:active{transform:translateY(0)}.ngx-ie-rotate-row button.active,.ngx-ie-filter-row button.active{background:light-dark(#2563eb,#3b82f6);border-color:light-dark(#2563eb,#3b82f6);color:#fff;box-shadow:0 2px 10px light-dark(rgba(37,99,235,.3),rgba(59,130,246,.3))}.ngx-ie-filter-row{display:flex;flex-wrap:wrap;gap:.4rem}.ngx-ie-actions{margin-block-start:auto;justify-content:flex-end}.ngx-ie-btn-primary,.ngx-ie-btn-secondary{appearance:none;border:none;border-radius:8px;padding:.55rem 1.1rem;font-size:.85rem;cursor:pointer;font-weight:500;transition:transform .15s ease,box-shadow .15s ease,opacity .15s ease}.ngx-ie-btn-primary:hover,.ngx-ie-btn-secondary:hover{transform:translateY(-1px)}.ngx-ie-btn-primary:active,.ngx-ie-btn-secondary:active{transform:translateY(0)}.ngx-ie-btn-primary{background:light-dark(#2563eb,#3b82f6);color:#fff;box-shadow:0 2px 10px light-dark(rgba(37,99,235,.25),rgba(59,130,246,.25))}.ngx-ie-btn-primary:disabled{opacity:.6;cursor:not-allowed;transform:none}.ngx-ie-btn-secondary{background:light-dark(#e5e7eb,#3f3f46);color:light-dark(#374151,#e4e4e7)}@media(max-width:768px){:host{height:unset!important}.ngx-ie-layout{display:flex;flex-direction:column}}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: SliderComponent, selector: "slider", inputs: ["step", "min", "max", "background", "isBgTransparent"], outputs: ["change"] }, { kind: "directive", type: NgxPointerDragDirective, selector: "[ngxPointerDrag]", outputs: ["dragStart", "dragMove", "dragEnd"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
577
577
  }
578
578
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: NgxImageEditorComponent, decorators: [{
579
579
  type: Component,
580
- args: [{ selector: 'ngx-image-editor', standalone: true, imports: [FormsModule, SliderComponent, NgxPointerDragDirective], changeDetection: ChangeDetectionStrategy.OnPush, host: { class: 'ngx-image-editor-host' }, template: "@if (loading()) {\n <div class=\"ngx-ie-state\">{{ localize().LoadingImage }}</div>\n} @else if (loadError()) {\n <div class=\"ngx-ie-state ngx-ie-state--error\">{{ loadError() }}</div>\n} @else if (stageImageUrl()) {\n <div class=\"ngx-ie-layout\">\n <div class=\"ngx-ie-stage-wrap\" #stageWrap>\n <div\n class=\"ngx-ie-stage\"\n [style.width.px]=\"stageSize().width\"\n [style.height.px]=\"stageSize().height\">\n <img class=\"ngx-ie-stage-img\" [src]=\"stageImageUrl()\" alt=\"\" draggable=\"false\" />\n\n <div\n class=\"ngx-ie-crop-box\"\n [style.left]=\"cropOverlayStyle().left\"\n [style.top]=\"cropOverlayStyle().top\"\n [style.width]=\"cropOverlayStyle().width\"\n [style.height]=\"cropOverlayStyle().height\"\n ngxPointerDrag\n (dragStart)=\"onMoveDragStart()\"\n (dragMove)=\"onMoveDragMove($event)\">\n <span\n class=\"ngx-ie-handle ngx-ie-handle--nw\"\n ngxPointerDrag\n (dragStart)=\"onResizeDragStart()\"\n (dragMove)=\"onResizeDragMove('nw', $event)\"></span>\n <span\n class=\"ngx-ie-handle ngx-ie-handle--ne\"\n ngxPointerDrag\n (dragStart)=\"onResizeDragStart()\"\n (dragMove)=\"onResizeDragMove('ne', $event)\"></span>\n <span\n class=\"ngx-ie-handle ngx-ie-handle--sw\"\n ngxPointerDrag\n (dragStart)=\"onResizeDragStart()\"\n (dragMove)=\"onResizeDragMove('sw', $event)\"></span>\n <span\n class=\"ngx-ie-handle ngx-ie-handle--se\"\n ngxPointerDrag\n (dragStart)=\"onResizeDragStart()\"\n (dragMove)=\"onResizeDragMove('se', $event)\"></span>\n </div>\n </div>\n </div>\n\n <div class=\"ngx-ie-panel-row\">\n <div class=\"ngx-ie-panel\">\n <div class=\"ngx-ie-preview\">\n @if (previewUrl(); as url) {\n <img [src]=\"url\" alt=\"Preview\" />\n }\n </div>\n\n <div class=\"ngx-ie-row ngx-ie-rotate-row\">\n <button type=\"button\" (click)=\"rotateBy(-90)\" title=\"Rotate 90\u00B0 left\">\u27F2 90</button>\n <button type=\"button\" (click)=\"rotateBy(90)\" title=\"Rotate 90\u00B0 right\">\u27F3 90</button>\n </div>\n\n <label class=\"ngx-ie-field\">\n <slider\n [ngModel]=\"rotation()\"\n (ngModelChange)=\"rotation.set($event)\"\n [min]=\"-180\"\n [max]=\"180\">\n <span>{{ localize().Rotation }} ({{ rotation() }}\u00B0)</span>\n </slider>\n\n <button\n type=\"button\"\n (click)=\"rotation.set(0)\"\n class=\"ngx-ie-btn-secondary\"\n [title]=\"localize().Reset\">\n x\n </button>\n </label>\n\n <label class=\"ngx-ie-field\">\n <slider\n [ngModel]=\"brightness()\"\n (ngModelChange)=\"brightness.set($event)\"\n [min]=\"0\"\n [max]=\"200\">\n <span>{{ localize().Brightness }} ({{ brightness() }}%)</span>\n </slider>\n <button\n type=\"button\"\n (click)=\"brightness.set(100)\"\n class=\"ngx-ie-btn-secondary\"\n [title]=\"localize().Reset\">\n x\n </button>\n </label>\n\n <label class=\"ngx-ie-field\">\n <slider\n [ngModel]=\"contrast()\"\n (ngModelChange)=\"contrast.set($event)\"\n [min]=\"0\"\n [max]=\"200\">\n <span>{{ localize().Contrast }} ({{ contrast() }}%)</span>\n </slider>\n <button\n type=\"button\"\n (click)=\"contrast.set(100)\"\n class=\"ngx-ie-btn-secondary\"\n [title]=\"localize().Reset\">\n x\n </button>\n </label>\n\n <label class=\"ngx-ie-field\">\n <slider\n [ngModel]=\"saturation()\"\n (ngModelChange)=\"saturation.set($event)\"\n [min]=\"0\"\n [max]=\"200\">\n <span>{{ localize().Saturation }} ({{ saturation() }}%)</span>\n </slider>\n <button\n type=\"button\"\n (click)=\"saturation.set(100)\"\n class=\"ngx-ie-btn-secondary\"\n [title]=\"localize().Reset\">\n x\n </button>\n </label>\n\n @if (filters().length) {\n <div>\n <span>{{ localize().Filter }}</span>\n <div class=\"ngx-ie-filter-row\">\n @for (f of filters(); track f) {\n <button type=\"button\" [class.active]=\"filterPreset() === f\" (click)=\"setFilter(f)\">\n {{ filterLabels()[f] }}\n </button>\n }\n </div>\n </div>\n }\n\n <div class=\"ngx-ie-row ngx-ie-actions\">\n <button type=\"button\" class=\"ngx-ie-btn-secondary\" (click)=\"cancel()\">\n {{ localize().Cancel }}\n </button>\n <button type=\"button\" class=\"ngx-ie-btn-primary\" [disabled]=\"saving()\" (click)=\"save()\">\n {{ saving() ? localize().Saving : localize().Save }}\n </button>\n </div>\n </div>\n </div>\n </div>\n}\n", styles: ["@charset \"UTF-8\";:host{display:block;min-height:70dvh;--ngx-image-editor-panel-width: 25%}.ngx-ie-state{padding:2rem;text-align:center;color:light-dark(#6b7280,#9ca3af)}.ngx-ie-state--error{color:light-dark(#b91c1c,#f87171)}.ngx-ie-layout{display:grid;grid-template-columns:1fr var(--ngx-image-editor-panel-width, 30%);gap:1.25rem;height:100%}.ngx-ie-stage-wrap{width:100%;display:flex;align-items:center;justify-content:center;background:light-dark(#f3f4f6,#18181b);border-radius:10px;overflow:hidden;flex-shrink:0}.ngx-ie-stage{position:relative;touch-action:none;-webkit-user-select:none;user-select:none;direction:ltr}.ngx-ie-stage-img{display:block;inline-size:100%;block-size:100%;border-radius:4px;pointer-events:none;background:#fff;background-image:linear-gradient(45deg,#ccc 25%,transparent 25%),linear-gradient(-45deg,#ccc 25%,transparent 25%),linear-gradient(45deg,transparent 75%,#ccc 75%),linear-gradient(-45deg,transparent 75%,#ccc 75%);background-size:16px 16px;background-position:0 0,0 8px,8px -8px,-8px 0px}.ngx-ie-crop-box{position:absolute;box-sizing:border-box;border:2px solid #2563eb;box-shadow:0 0 0 9999px #00000073;cursor:move;touch-action:none}.ngx-ie-handle{position:absolute;inline-size:14px;block-size:14px;background:#fff;border:2px solid #2563eb;border-radius:50%;touch-action:none}.ngx-ie-handle--nw{inset-inline-start:-7px;inset-block-start:-7px;cursor:nwse-resize}.ngx-ie-handle--ne{inset-inline-end:-7px;inset-block-start:-7px;cursor:nesw-resize}.ngx-ie-handle--sw{inset-inline-start:-7px;inset-block-end:-7px;cursor:nesw-resize}.ngx-ie-handle--se{inset-inline-end:-7px;inset-block-end:-7px;cursor:nwse-resize}.ngx-ie-panel{flex:1;display:flex;flex-direction:column;gap:.75rem}.ngx-ie-panel-row{display:flex;flex-wrap:wrap;gap:1.25rem}.ngx-ie-preview{display:flex;align-items:center;justify-content:center;min-block-size:100px;background:light-dark(#f3f4f6,#18181b);border-radius:8px;overflow:hidden}.ngx-ie-preview img{max-inline-size:100%;max-block-size:160px;display:block;background:#fff;background-image:linear-gradient(45deg,#ccc 25%,transparent 25%),linear-gradient(-45deg,#ccc 25%,transparent 25%),linear-gradient(45deg,transparent 75%,#ccc 75%),linear-gradient(-45deg,transparent 75%,#ccc 75%);background-size:16px 16px;background-position:0 0,0 8px,8px -8px,-8px 0px}.ngx-ie-field{display:flex;gap:.3rem;align-items:flex-end}.ngx-ie-field slider{flex:1}.ngx-ie-row{display:flex;gap:.5rem}.ngx-ie-rotate-row button,.ngx-ie-filter-row button{appearance:none;border:1px solid light-dark(#e5e7eb,#33333a);background:light-dark(#ffffff,#232327);color:light-dark(#374151,#d4d4d8);border-radius:999px;padding:.4rem .85rem;font-size:.75rem;cursor:pointer;transition:background-color .15s ease,border-color .15s ease,transform .15s ease,color .15s ease}.ngx-ie-rotate-row button:hover,.ngx-ie-filter-row button:hover{background:light-dark(#f3f4f6,#2c2c31);transform:translateY(-1px)}.ngx-ie-rotate-row button:active,.ngx-ie-filter-row button:active{transform:translateY(0)}.ngx-ie-rotate-row button.active,.ngx-ie-filter-row button.active{background:light-dark(#2563eb,#3b82f6);border-color:light-dark(#2563eb,#3b82f6);color:#fff;box-shadow:0 2px 10px light-dark(rgba(37,99,235,.3),rgba(59,130,246,.3))}.ngx-ie-filter-row{display:flex;flex-wrap:wrap;gap:.4rem}.ngx-ie-actions{margin-block-start:auto;justify-content:flex-end}.ngx-ie-btn-primary,.ngx-ie-btn-secondary{appearance:none;border:none;border-radius:8px;padding:.55rem 1.1rem;font-size:.85rem;cursor:pointer;font-weight:500;transition:transform .15s ease,box-shadow .15s ease,opacity .15s ease}.ngx-ie-btn-primary:hover,.ngx-ie-btn-secondary:hover{transform:translateY(-1px)}.ngx-ie-btn-primary:active,.ngx-ie-btn-secondary:active{transform:translateY(0)}.ngx-ie-btn-primary{background:light-dark(#2563eb,#3b82f6);color:#fff;box-shadow:0 2px 10px light-dark(rgba(37,99,235,.25),rgba(59,130,246,.25))}.ngx-ie-btn-primary:disabled{opacity:.6;cursor:not-allowed;transform:none}.ngx-ie-btn-secondary{background:light-dark(#e5e7eb,#3f3f46);color:light-dark(#374151,#e4e4e7)}@media(max-width:768px){:host{height:unset!important}.ngx-ie-layout{display:flex;flex-direction:column}}\n"] }]
580
+ args: [{ selector: 'ngx-image-editor', standalone: true, imports: [FormsModule, SliderComponent, NgxPointerDragDirective], changeDetection: ChangeDetectionStrategy.OnPush, host: { class: 'ngx-image-editor-host' }, template: "@if (loading()) {\r\n <div class=\"ngx-ie-state\">{{ localize().LoadingImage }}</div>\r\n} @else if (loadError()) {\r\n <div class=\"ngx-ie-state ngx-ie-state--error\">{{ loadError() }}</div>\r\n} @else if (stageImageUrl()) {\r\n <div class=\"ngx-ie-layout\">\r\n <div class=\"ngx-ie-stage-wrap\" #stageWrap>\r\n <div\r\n class=\"ngx-ie-stage\"\r\n [style.width.px]=\"stageSize().width\"\r\n [style.height.px]=\"stageSize().height\">\r\n <img class=\"ngx-ie-stage-img\" [src]=\"stageImageUrl()\" alt=\"\" draggable=\"false\" />\r\n\r\n <div\r\n class=\"ngx-ie-crop-box\"\r\n [style.left]=\"cropOverlayStyle().left\"\r\n [style.top]=\"cropOverlayStyle().top\"\r\n [style.width]=\"cropOverlayStyle().width\"\r\n [style.height]=\"cropOverlayStyle().height\"\r\n ngxPointerDrag\r\n (dragStart)=\"onMoveDragStart()\"\r\n (dragMove)=\"onMoveDragMove($event)\">\r\n <span\r\n class=\"ngx-ie-handle ngx-ie-handle--nw\"\r\n ngxPointerDrag\r\n (dragStart)=\"onResizeDragStart()\"\r\n (dragMove)=\"onResizeDragMove('nw', $event)\"></span>\r\n <span\r\n class=\"ngx-ie-handle ngx-ie-handle--ne\"\r\n ngxPointerDrag\r\n (dragStart)=\"onResizeDragStart()\"\r\n (dragMove)=\"onResizeDragMove('ne', $event)\"></span>\r\n <span\r\n class=\"ngx-ie-handle ngx-ie-handle--sw\"\r\n ngxPointerDrag\r\n (dragStart)=\"onResizeDragStart()\"\r\n (dragMove)=\"onResizeDragMove('sw', $event)\"></span>\r\n <span\r\n class=\"ngx-ie-handle ngx-ie-handle--se\"\r\n ngxPointerDrag\r\n (dragStart)=\"onResizeDragStart()\"\r\n (dragMove)=\"onResizeDragMove('se', $event)\"></span>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"ngx-ie-panel-row\">\r\n <div class=\"ngx-ie-panel\">\r\n <div class=\"ngx-ie-preview\">\r\n @if (previewUrl(); as url) {\r\n <img [src]=\"url\" alt=\"Preview\" />\r\n }\r\n </div>\r\n\r\n <div class=\"ngx-ie-row ngx-ie-rotate-row\">\r\n <button type=\"button\" (click)=\"rotateBy(-90)\" title=\"Rotate 90\u00B0 left\">\u27F2 90</button>\r\n <button type=\"button\" (click)=\"rotateBy(90)\" title=\"Rotate 90\u00B0 right\">\u27F3 90</button>\r\n </div>\r\n\r\n <div class=\"ngx-ie-field\">\r\n <slider\r\n [ngModel]=\"rotation()\"\r\n (ngModelChange)=\"rotation.set($event)\"\r\n [min]=\"-180\"\r\n [max]=\"180\">\r\n <span>{{ localize().Rotation }} ({{ rotation() }}\u00B0)</span>\r\n </slider>\r\n\r\n <button\r\n type=\"button\"\r\n (click)=\"rotation.set(0)\"\r\n class=\"ngx-ie-btn-secondary\"\r\n [title]=\"localize().Reset\">\r\n x\r\n </button>\r\n </div>\r\n\r\n <div class=\"ngx-ie-field\">\r\n <slider\r\n [ngModel]=\"brightness()\"\r\n (ngModelChange)=\"brightness.set($event)\"\r\n [min]=\"0\"\r\n [max]=\"200\">\r\n <span>{{ localize().Brightness }} ({{ brightness() }}%)</span>\r\n </slider>\r\n <button\r\n type=\"button\"\r\n (click)=\"brightness.set(100)\"\r\n class=\"ngx-ie-btn-secondary\"\r\n [title]=\"localize().Reset\">\r\n x\r\n </button>\r\n </div>\r\n\r\n <div class=\"ngx-ie-field\">\r\n <slider\r\n [ngModel]=\"contrast()\"\r\n (ngModelChange)=\"contrast.set($event)\"\r\n [min]=\"0\"\r\n [max]=\"200\">\r\n <span>{{ localize().Contrast }} ({{ contrast() }}%)</span>\r\n </slider>\r\n <button\r\n type=\"button\"\r\n (click)=\"contrast.set(100)\"\r\n class=\"ngx-ie-btn-secondary\"\r\n [title]=\"localize().Reset\">\r\n x\r\n </button>\r\n </div>\r\n\r\n <div class=\"ngx-ie-field\">\r\n <slider\r\n [ngModel]=\"saturation()\"\r\n (ngModelChange)=\"saturation.set($event)\"\r\n [min]=\"0\"\r\n [max]=\"200\">\r\n <span>{{ localize().Saturation }} ({{ saturation() }}%)</span>\r\n </slider>\r\n <button\r\n type=\"button\"\r\n (click)=\"saturation.set(100)\"\r\n class=\"ngx-ie-btn-secondary\"\r\n [title]=\"localize().Reset\">\r\n x\r\n </button>\r\n </div>\r\n\r\n @if (filters().length) {\r\n <div>\r\n <span>{{ localize().Filter }}</span>\r\n <div class=\"ngx-ie-filter-row\">\r\n @for (f of filters(); track f) {\r\n <button type=\"button\" [class.active]=\"filterPreset() === f\" (click)=\"setFilter(f)\">\r\n {{ filterLabels()[f] }}\r\n </button>\r\n }\r\n </div>\r\n </div>\r\n }\r\n\r\n <div class=\"ngx-ie-row ngx-ie-actions\">\r\n <button type=\"button\" class=\"ngx-ie-btn-secondary\" (click)=\"cancel()\">\r\n {{ localize().Cancel }}\r\n </button>\r\n <button type=\"button\" class=\"ngx-ie-btn-primary\" [disabled]=\"saving()\" (click)=\"save()\">\r\n {{ saving() ? localize().Saving : localize().Save }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n}\r\n", styles: ["@charset \"UTF-8\";:host{display:block;min-height:70dvh;--ngx-image-editor-panel-width: 25%}.ngx-ie-state{padding:2rem;text-align:center;color:light-dark(#6b7280,#9ca3af)}.ngx-ie-state--error{color:light-dark(#b91c1c,#f87171)}.ngx-ie-layout{display:grid;grid-template-columns:1fr var(--ngx-image-editor-panel-width, 30%);gap:1.25rem;height:100%}.ngx-ie-stage-wrap{width:100%;display:flex;align-items:center;justify-content:center;background:light-dark(#f3f4f6,#18181b);border-radius:10px;overflow:hidden;flex-shrink:0}.ngx-ie-stage{position:relative;touch-action:none;-webkit-user-select:none;user-select:none;direction:ltr}.ngx-ie-stage-img{display:block;inline-size:100%;block-size:100%;border-radius:4px;pointer-events:none;background:#fff;background-image:linear-gradient(45deg,#ccc 25%,transparent 25%),linear-gradient(-45deg,#ccc 25%,transparent 25%),linear-gradient(45deg,transparent 75%,#ccc 75%),linear-gradient(-45deg,transparent 75%,#ccc 75%);background-size:16px 16px;background-position:0 0,0 8px,8px -8px,-8px 0px}.ngx-ie-crop-box{position:absolute;box-sizing:border-box;border:2px solid #2563eb;box-shadow:0 0 0 9999px #00000073;cursor:move;touch-action:none}.ngx-ie-handle{position:absolute;inline-size:14px;block-size:14px;background:#fff;border:2px solid #2563eb;border-radius:50%;touch-action:none}.ngx-ie-handle--nw{inset-inline-start:-7px;inset-block-start:-7px;cursor:nwse-resize}.ngx-ie-handle--ne{inset-inline-end:-7px;inset-block-start:-7px;cursor:nesw-resize}.ngx-ie-handle--sw{inset-inline-start:-7px;inset-block-end:-7px;cursor:nesw-resize}.ngx-ie-handle--se{inset-inline-end:-7px;inset-block-end:-7px;cursor:nwse-resize}.ngx-ie-panel{flex:1;display:flex;flex-direction:column;gap:.75rem}.ngx-ie-panel-row{display:flex;flex-wrap:wrap;gap:1.25rem}.ngx-ie-preview{display:flex;align-items:center;justify-content:center;min-block-size:100px;background:light-dark(#f3f4f6,#18181b);border-radius:8px;overflow:hidden}.ngx-ie-preview img{max-inline-size:100%;max-block-size:160px;display:block;background:#fff;background-image:linear-gradient(45deg,#ccc 25%,transparent 25%),linear-gradient(-45deg,#ccc 25%,transparent 25%),linear-gradient(45deg,transparent 75%,#ccc 75%),linear-gradient(-45deg,transparent 75%,#ccc 75%);background-size:16px 16px;background-position:0 0,0 8px,8px -8px,-8px 0px}.ngx-ie-field{display:flex;gap:.3rem;align-items:flex-end}.ngx-ie-field slider{flex:1}.ngx-ie-row{display:flex;gap:.5rem}.ngx-ie-rotate-row button,.ngx-ie-filter-row button{appearance:none;border:1px solid light-dark(#e5e7eb,#33333a);background:light-dark(#ffffff,#232327);color:light-dark(#374151,#d4d4d8);border-radius:999px;padding:.4rem .85rem;font-size:.75rem;cursor:pointer;transition:background-color .15s ease,border-color .15s ease,transform .15s ease,color .15s ease}.ngx-ie-rotate-row button:hover,.ngx-ie-filter-row button:hover{background:light-dark(#f3f4f6,#2c2c31);transform:translateY(-1px)}.ngx-ie-rotate-row button:active,.ngx-ie-filter-row button:active{transform:translateY(0)}.ngx-ie-rotate-row button.active,.ngx-ie-filter-row button.active{background:light-dark(#2563eb,#3b82f6);border-color:light-dark(#2563eb,#3b82f6);color:#fff;box-shadow:0 2px 10px light-dark(rgba(37,99,235,.3),rgba(59,130,246,.3))}.ngx-ie-filter-row{display:flex;flex-wrap:wrap;gap:.4rem}.ngx-ie-actions{margin-block-start:auto;justify-content:flex-end}.ngx-ie-btn-primary,.ngx-ie-btn-secondary{appearance:none;border:none;border-radius:8px;padding:.55rem 1.1rem;font-size:.85rem;cursor:pointer;font-weight:500;transition:transform .15s ease,box-shadow .15s ease,opacity .15s ease}.ngx-ie-btn-primary:hover,.ngx-ie-btn-secondary:hover{transform:translateY(-1px)}.ngx-ie-btn-primary:active,.ngx-ie-btn-secondary:active{transform:translateY(0)}.ngx-ie-btn-primary{background:light-dark(#2563eb,#3b82f6);color:#fff;box-shadow:0 2px 10px light-dark(rgba(37,99,235,.25),rgba(59,130,246,.25))}.ngx-ie-btn-primary:disabled{opacity:.6;cursor:not-allowed;transform:none}.ngx-ie-btn-secondary{background:light-dark(#e5e7eb,#3f3f46);color:light-dark(#374151,#e4e4e7)}@media(max-width:768px){:host{height:unset!important}.ngx-ie-layout{display:flex;flex-direction:column}}\n"] }]
581
581
  }], ctorParameters: () => [], propDecorators: { source: [{ type: i0.Input, args: [{ isSignal: true, alias: "source", required: false }] }], aspectRatio: [{ type: i0.Input, args: [{ isSignal: true, alias: "aspectRatio", required: false }] }], outputMaxWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "outputMaxWidth", required: false }] }], outputMaxHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "outputMaxHeight", required: false }] }], outputType: [{ type: i0.Input, args: [{ isSignal: true, alias: "outputType", required: false }] }], filters: [{ type: i0.Input, args: [{ isSignal: true, alias: "filters", required: false }] }], quality: [{ type: i0.Input, args: [{ isSignal: true, alias: "quality", required: false }] }], localize: [{ type: i0.Input, args: [{ isSignal: true, alias: "localize", required: false }] }], saved: [{ type: i0.Output, args: ["saved"] }], cancelled: [{ type: i0.Output, args: ["cancelled"] }], stageWrapEl: [{ type: i0.ViewChild, args: ['stageWrap', { isSignal: true }] }] } });
582
582
 
583
583
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"ngx-kit-image-editor.mjs","sources":["../../../projects/libs/image-editor/directives/pointer-drag.directive.ts","../../../projects/libs/image-editor/utils/image-io.ts","../../../projects/libs/image-editor/utils/cartoonify.ts","../../../projects/libs/image-editor/utils/render-pipeline.ts","../../../projects/libs/image-editor/tokens/localization.ts","../../../projects/libs/image-editor/components/image-editor.component.ts","../../../projects/libs/image-editor/components/image-editor.component.html","../../../projects/libs/image-editor/ngx-kit-image-editor.ts"],"sourcesContent":["import { Directive, HostListener, output } from '@angular/core';\n\nexport interface NgxPointerDragDelta {\n dx: number;\n dy: number;\n}\n\n/**\n * درگ عمومی روی پایه‌ی Pointer Events + setPointerCapture (دقیقاً همون\n * تکنیکی که در ngx-kit/data-table برای ریسایز ستون استفاده شده) — نیازی به\n * listener سطح document نداره چون بعد از setPointerCapture، رویدادهای\n * pointermove/pointerup حتی بیرون از محدوده‌ی المنت هم به خودش می‌رسن.\n *\n * dx/dy تجمعی از لحظه‌ی pointerdown هستن (نه دلتای بین دو move متوالی)، چون\n * معمولاً مصرف‌کننده می‌خواد «موقعیت شروع + دلتای کل» رو حساب کنه، نه جمع\n * تدریجی گرد شونده‌ی دلتاهای ریز.\n */\n@Directive({\n selector: '[ngxPointerDrag]',\n standalone: true,\n})\nexport class NgxPointerDragDirective {\n dragStart = output<void>();\n dragMove = output<NgxPointerDragDelta>();\n dragEnd = output<void>();\n\n private dragging = false;\n private startX = 0;\n private startY = 0;\n\n @HostListener('pointerdown', ['$event'])\n onPointerDown(ev: PointerEvent): void {\n ev.preventDefault();\n ev.stopPropagation();\n this.dragging = true;\n this.startX = ev.clientX;\n this.startY = ev.clientY;\n (ev.target as HTMLElement).setPointerCapture(ev.pointerId);\n this.dragStart.emit();\n }\n\n @HostListener('pointermove', ['$event'])\n onPointerMove(ev: PointerEvent): void {\n if (!this.dragging) return;\n this.dragMove.emit({ dx: ev.clientX - this.startX, dy: ev.clientY - this.startY });\n }\n\n @HostListener('pointerup')\n @HostListener('pointercancel')\n onPointerUp(): void {\n if (!this.dragging) return;\n this.dragging = false;\n this.dragEnd.emit();\n }\n}\n","/** یه File/Blob/data-URL/URL رو به یک HTMLImageElement بارگذاری‌شده تبدیل می‌کنه */\nexport function loadImage(source: File | Blob | string): Promise<HTMLImageElement> {\n return new Promise((resolve, reject) => {\n const img = new Image();\n // برای URLهای cross-origin لازم می‌شه، وگرنه canvas بعداً «tainted» می‌شه\n // و toBlob/toDataURL با SecurityError شکست می‌خوره.\n img.crossOrigin = 'anonymous';\n\n const objectUrl = typeof source === 'string' ? null : URL.createObjectURL(source);\n const url = objectUrl ?? (source as string);\n\n img.onload = () => {\n if (objectUrl) URL.revokeObjectURL(objectUrl);\n resolve(img);\n };\n img.onerror = () => {\n if (objectUrl) URL.revokeObjectURL(objectUrl);\n reject(new Error('Failed to load image'));\n };\n img.src = url;\n });\n}\n\n/** canvas.toBlob به‌صورت Promise، به‌همراه fallback برای مرورگرهای قدیمی‌تر */\nexport function canvasToBlob(\n canvas: HTMLCanvasElement,\n type = 'image/jpeg',\n quality = 0.92,\n): Promise<Blob> {\n return new Promise((resolve, reject) => {\n canvas.toBlob(\n (blob) => {\n if (blob) resolve(blob);\n else reject(new Error('Failed to convert canvas to blob'));\n },\n type,\n quality,\n );\n });\n}\n\n/**\n * یه کپیِ کوچیک‌شده از تصویر اصلی می‌سازه که کل UI ویرایشگر (چرخش، کراپ،\n * پیش‌نمایش فیلترها/کارتونی) روی همین کار می‌کنه، نه روی تصویر اصلی که\n * ممکنه چند مگاپیکسل باشه. این باعث می‌شه درگ‌کردنِ اسلایدرها یا لبه‌های\n * کراپ روون بمونه؛ خروجی نهایی (save) همیشه از روی تصویر اصلیِ کامل رندر\n * می‌شه، نه از روی این کپی.\n */\nexport function createWorkingCopy(img: HTMLImageElement, maxSize = 1200): HTMLCanvasElement {\n const { width, height } = fitWithin(img.naturalWidth, img.naturalHeight, maxSize, maxSize);\n const canvas = document.createElement('canvas');\n canvas.width = width;\n canvas.height = height;\n const ctx = canvas.getContext('2d')!;\n ctx.drawImage(img, 0, 0, width, height);\n return canvas;\n}\n\n/** ابعاد جدید رو طوری حساب می‌کنه که از maxWidth/maxHeight بیشتر نشه، با حفظ نسبت تصویر */\nexport function fitWithin(\n width: number,\n height: number,\n maxWidth?: number,\n maxHeight?: number,\n): { width: number; height: number } {\n if (!maxWidth && !maxHeight) return { width, height };\n let ratio = 1;\n if (maxWidth) ratio = Math.min(ratio, maxWidth / width);\n if (maxHeight) ratio = Math.min(ratio, maxHeight / height);\n if (ratio >= 1) return { width, height };\n return { width: Math.round(width * ratio), height: Math.round(height * ratio) };\n}\n","/**\n * افکت «کارتونی»: چون ctx.filter استاندارد چیزی شبیه cartoon نداره (فقط\n * brightness/contrast/saturate/grayscale/sepia/invert/blur/hue-rotate)، این\n * یکی رو واقعاً با پردازش پیکسلی پیاده کردیم؛ دو مرحله:\n *\n * ۱) Posterize: هر کانال رنگ به تعداد محدودی سطح گرد می‌شه (پهنه‌های رنگیِ\n * صاف و یکدست، حسِ کارتونی رنگ می‌ده).\n * ۲) لبه‌یابی Sobel روی نسخه‌ی خاکستریِ تصویر: هرجا شدت لبه از حد آستانه\n * بیشتر باشه، پیکسل تیره می‌شه (حسِ خط دور کارتونی).\n *\n * روی خودِ ImageData کار می‌کنه، پس هزینه‌ش با اندازه‌ی تصویر خطی‌ست؛ برای\n * تصاویر خیلی بزرگ (>~3000px) بهتره قبلش resize بشه (که در کامپوننت اصلی\n * با fitWithin قبل از اعمال فیلتر انجام می‌شه).\n */\nexport function applyCartoonEffect(\n ctx: CanvasRenderingContext2D,\n width: number,\n height: number,\n options: { levels?: number; edgeThreshold?: number } = {},\n): void {\n const levels = options.levels ?? 5;\n const edgeThreshold = options.edgeThreshold ?? 80;\n\n const imageData = ctx.getImageData(0, 0, width, height);\n const src = imageData.data;\n\n // ۱) خاکستری برای Sobel\n const gray = new Uint8ClampedArray(width * height);\n for (let i = 0, p = 0; i < src.length; i += 4, p++) {\n gray[p] = (src[i] * 0.299 + src[i + 1] * 0.587 + src[i + 2] * 0.114) | 0;\n }\n\n // ۲) Posterize رنگ‌ها\n const step = 255 / (levels - 1);\n for (let i = 0; i < src.length; i += 4) {\n src[i] = Math.round(Math.round(src[i] / step) * step);\n src[i + 1] = Math.round(Math.round(src[i + 1] / step) * step);\n src[i + 2] = Math.round(Math.round(src[i + 2] / step) * step);\n }\n\n // ۳) Sobel روی gray، خط دور تیره روی src\n const gxKernel = [-1, 0, 1, -2, 0, 2, -1, 0, 1];\n const gyKernel = [-1, -2, -1, 0, 0, 0, 1, 2, 1];\n\n for (let y = 1; y < height - 1; y++) {\n for (let x = 1; x < width - 1; x++) {\n let gx = 0;\n let gy = 0;\n let k = 0;\n for (let dy = -1; dy <= 1; dy++) {\n for (let dx = -1; dx <= 1; dx++) {\n const v = gray[(y + dy) * width + (x + dx)];\n gx += v * gxKernel[k];\n gy += v * gyKernel[k];\n k++;\n }\n }\n const magnitude = Math.sqrt(gx * gx + gy * gy);\n if (magnitude > edgeThreshold) {\n const idx = (y * width + x) * 4;\n src[idx] = 20;\n src[idx + 1] = 20;\n src[idx + 2] = 20;\n }\n }\n }\n\n ctx.putImageData(imageData, 0, 0);\n}\n","import { NgxCropRect, NgxImageEditorAdjustments } from '../contracts/image-editor-types';\nimport { applyCartoonEffect } from './cartoonify';\nimport { fitWithin } from './image-io';\n\n/** تصویر مبدأ رو با زاویه‌ی داده‌شده روی یه canvas جدید (به اندازه‌ی bounding-box نتیجه) می‌چرخونه */\nexport function renderRotated(\n source: CanvasImageSource,\n width: number,\n height: number,\n degrees: number,\n): HTMLCanvasElement {\n const rad = (degrees * Math.PI) / 180;\n const sin = Math.abs(Math.sin(rad));\n const cos = Math.abs(Math.cos(rad));\n const newW = Math.max(1, Math.round(width * cos + height * sin));\n const newH = Math.max(1, Math.round(width * sin + height * cos));\n\n const canvas = document.createElement('canvas');\n canvas.width = newW;\n canvas.height = newH;\n const ctx = canvas.getContext('2d')!;\n ctx.translate(newW / 2, newH / 2);\n ctx.rotate(rad);\n ctx.drawImage(source, -width / 2, -height / 2, width, height);\n return canvas;\n}\n\nfunction buildCssFilter(adjustments: NgxImageEditorAdjustments): string {\n const parts = [\n `brightness(${adjustments.brightness}%)`,\n `contrast(${adjustments.contrast}%)`,\n `saturate(${adjustments.saturation}%)`,\n ];\n if (adjustments.filter === 'grayscale') parts.push('grayscale(1)');\n if (adjustments.filter === 'sepia') parts.push('sepia(1)');\n if (adjustments.filter === 'invert') parts.push('invert(1)');\n return parts.join(' ');\n}\n\n/**\n * کراپ + فیلترها رو روی یه canvas خروجی می‌سازه. brightness/contrast/\n * saturation/grayscale/sepia/invert همه با ctx.filter بومیِ Canvas 2D انجام\n * می‌شن (شتاب‌دهی‌شده توسط مرورگر، بدون حلقه‌ی پیکسلی دستی)؛ فقط cartoon\n * (که معادل بومی نداره) با پردازش پیکسلی جدا انجام می‌شه.\n *\n * maxWidth/maxHeight برای دو حالت استفاده می‌شه: پیش‌نمایش زنده (عدد کوچیک،\n * برای واکنش‌گرا موندن حین کشیدن اسلایدرها) و خروجی نهایی (بدون محدودیت یا\n * محدودیت دلخواه کاربر).\n */\nexport function renderComposite(\n source: CanvasImageSource,\n sourceWidth: number,\n sourceHeight: number,\n crop: NgxCropRect,\n adjustments: NgxImageEditorAdjustments,\n maxWidth?: number,\n maxHeight?: number,\n): HTMLCanvasElement {\n const { width: outW, height: outH } = fitWithin(crop.width, crop.height, maxWidth, maxHeight);\n\n const canvas = document.createElement('canvas');\n canvas.width = Math.max(1, outW);\n canvas.height = Math.max(1, outH);\n const ctx = canvas.getContext('2d')!;\n\n ctx.filter = buildCssFilter(adjustments);\n ctx.drawImage(source, crop.x, crop.y, crop.width, crop.height, 0, 0, canvas.width, canvas.height);\n ctx.filter = 'none';\n\n if (adjustments.filter === 'cartoon') {\n applyCartoonEffect(ctx, canvas.width, canvas.height);\n }\n\n return canvas;\n}\n","import { InjectionToken } from '@angular/core';\r\n\r\nexport const NGX_IMAGE_EDITOR_LOCALIZATION = new InjectionToken<NgxImageEditorLocalization>(\r\n 'ngx-image-localization',\r\n {\r\n factory: () => DEFAULT_NGX_IMAGE_EDITOR_LOCALIZATION,\r\n },\r\n);\r\n\r\nexport class NgxImageEditorLocalization {\r\n LoadingImage = 'Loading image…';\r\n Rotation = 'Fine rotation';\r\n Brightness = 'Brightness';\r\n Contrast = 'Contrast';\r\n Saturation = 'Saturation';\r\n Filter = 'Filter';\r\n None = 'None';\r\n Grayscale = 'Grayscale';\r\n Sepia = 'Sepia';\r\n Invert = 'Invert';\r\n Cartoon = 'Cartoon';\r\n Cancel = 'Cancel';\r\n Save = 'Save';\r\n Saving = 'Saving…';\r\n Reset = 'Reset';\r\n}\r\nexport const DEFAULT_NGX_IMAGE_EDITOR_LOCALIZATION = new NgxImageEditorLocalization();\r\n","import {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n computed,\n effect,\n inject,\n input,\n output,\n signal,\n viewChild,\n} from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { SliderComponent } from 'ngx-kit/shared';\nimport {\n NgxCropRect,\n NgxImageEditorAdjustments,\n NgxImageEditorResult,\n NgxImageFilterPreset,\n} from '../contracts/image-editor-types';\nimport { NgxPointerDragDelta, NgxPointerDragDirective } from '../directives/pointer-drag.directive';\nimport { canvasToBlob, createWorkingCopy, loadImage } from '../utils/image-io';\nimport { renderComposite, renderRotated } from '../utils/render-pipeline';\nimport { Corner } from '../types/corner';\nimport { NGX_IMAGE_EDITOR_LOCALIZATION, NgxImageEditorLocalization } from '../tokens/localization';\n\nconst ALL_FILTERS: NgxImageFilterPreset[] = ['none', 'grayscale', 'sepia', 'invert', 'cartoon'];\n\n/**\n * ویرایشگر تصویر: کراپ + چرخش + روشنایی/کنتراست/اشباع + فیلترهای آماده\n * (سیاه‌وسفید، سپیا، معکوس، کارتونی) + فشرده‌سازی خروجی. کاملاً روی Canvas\n * خام پیاده شده، بدون هیچ وابستگی خارجی‌ای.\n *\n * نکته‌ی مهمِ معماری: تمام تعامل زنده (چرخوندن، جابه‌جا/ریسایز کراپ‌باکس،\n * پیش‌نمایش فیلترها حتی کارتونی) روی یه کپیِ کوچیک‌شده از تصویر انجام می‌شه\n * (createWorkingCopy)، نه روی تصویر اصلی که ممکنه چند مگاپیکسل باشه — وگرنه\n * درگ‌کردن اسلایدرها/گوشه‌های کراپ رو کاربر حس تاخیر می‌کرد. فقط لحظه‌ی\n * save()، رندر نهایی از روی تصویر اصلیِ کامل انجام می‌شه.\n *\n * اندازه‌ی صحنه (stage) با panelSize کنترل می‌شه: عرض همیشه ۱۰۰٪ عرضِ\n * والدِ کامپوننته (با ResizeObserver اندازه‌گیری می‌شه، پس با تغییر سایز\n * صفحه/layout هم زنده هماهنگ می‌مونه)، ارتفاع دقیقاً همون چیزیه که کاربر با\n * panelSize می‌ده. تصویر همیشه با یک مقیاسِ «contain» واقعی (هم بر اساس\n * عرض، هم بر اساس ارتفاع — هرکدوم تنگ‌تره) جا داده می‌شه، پس کلِ تصویر\n * همیشه در محدوده‌ی همین باکس دیده می‌شه، صرف‌نظر از اندازه‌ی واقعیِ فایل.\n * سقفِ مقیاس هم ۱ هست، یعنی تصاویر کوچیک بزرگ‌نمایی نمی‌شن (که باعثِ محو\n * شدن‌شون می‌شد).\n */\n@Component({\n selector: 'ngx-image-editor',\n standalone: true,\n imports: [FormsModule, SliderComponent, NgxPointerDragDirective],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './image-editor.component.html',\n styleUrl: './image-editor.component.scss',\n host: { class: 'ngx-image-editor-host' },\n})\nexport class NgxImageEditorComponent {\n source = input<File | Blob | string | null>(null);\n /** قفل نسبتِ کراپ (مثلاً ۱ برای آواتار مربعی)؛ undefined یعنی آزاد */\n aspectRatio = input<number | undefined>(undefined);\n outputMaxWidth = input<number | undefined>(undefined);\n outputMaxHeight = input<number | undefined>(undefined);\n outputType = input<'image/jpeg' | 'image/png' | 'image/webp'>('image/jpeg');\n\n /**\n * کدوم فیلترها نشون داده بشن (و به چه ترتیبی). اگه ندید، هر ۵ تا نشون داده\n * می‌شن. آرایه‌ی خالی یعنی کلِ بخشِ فیلتر مخفی بشه.\n */\n filters = input<NgxImageFilterPreset[]>(ALL_FILTERS);\n quality = input(0.92);\n\n defaultLocalization = inject(NGX_IMAGE_EDITOR_LOCALIZATION);\n localize = input<NgxImageEditorLocalization>(this.defaultLocalization);\n\n saved = output<NgxImageEditorResult>();\n cancelled = output<void>();\n\n protected readonly loading = signal(false);\n protected readonly saving = signal(false);\n protected readonly loadError = signal<string | null>(null);\n\n private readonly originalImage = signal<HTMLImageElement | null>(null);\n private readonly workingCanvas = signal<HTMLCanvasElement | null>(null);\n private readonly stageWrapEl = viewChild<ElementRef<HTMLElement>>('stageWrap');\n /** عرضِ واقعیِ رندرشده‌ی کانتینر؛ چون عرض همیشه ۱۰۰٪ (fluid) هست، باید زنده اندازه‌گیری بشه */\n private readonly containerWidth = signal(0);\n\n protected readonly rotation = signal(0);\n protected readonly brightness = signal(100);\n protected readonly contrast = signal(100);\n protected readonly saturation = signal(100);\n protected readonly filterPreset = signal<NgxImageFilterPreset>('none');\n\n protected readonly crop = signal<NgxCropRect>({ x: 0, y: 0, width: 0, height: 0 });\n\n protected readonly adjustments = computed<NgxImageEditorAdjustments>(() => ({\n brightness: this.brightness(),\n contrast: this.contrast(),\n saturation: this.saturation(),\n rotation: this.rotation(),\n filter: this.filterPreset(),\n }));\n\n protected readonly filterLabels = computed<Record<NgxImageFilterPreset, string>>(() => {\n const t = this.localize();\n return {\n none: t.None,\n grayscale: t.Grayscale,\n sepia: t.Sepia,\n invert: t.Invert,\n cartoon: t.Cartoon,\n };\n });\n\n /** تصویرِ (کوچیک‌شده‌یِ) چرخیده — پایه‌ی نمایش صحنه‌ی کراپ */\n protected readonly rotatedWorkingCanvas = computed(() => {\n const wc = this.workingCanvas();\n if (!wc) return null;\n return renderRotated(wc, wc.width, wc.height, this.rotation());\n });\n\n protected readonly panelSize = computed(() => {\n return this.stageWrapEl()?.nativeElement.getBoundingClientRect().height ?? 0;\n });\n\n /**\n * مقیاسِ «contain» واقعی: کوچیک‌ترینِ نسبتِ عرض و ارتفاع (هرکدوم تنگ‌تره)\n * تعیین‌کننده‌ست، و سقفش هم ۱ هست تا تصاویر کوچیک بزرگ‌نمایی نشن.\n */\n protected readonly displayScale = computed(() => {\n const rc = this.rotatedWorkingCanvas();\n const containerW = this.containerWidth();\n const panelH = this.panelSize();\n if (!rc || rc.width <= 0 || rc.height <= 0 || containerW <= 0 || panelH <= 0) return 1;\n return Math.min(containerW / rc.width, panelH / rc.height, 1);\n });\n\n protected readonly stageImageUrl = computed(() => {\n const rc = this.rotatedWorkingCanvas();\n return rc ? rc.toDataURL('image/png') : null;\n });\n\n protected readonly stageSize = computed(() => {\n const rc = this.rotatedWorkingCanvas();\n const scale = this.displayScale();\n return rc ? { width: rc.width * scale, height: rc.height * scale } : { width: 0, height: 0 };\n });\n\n protected readonly cropOverlayStyle = computed(() => {\n const scale = this.displayScale();\n const c = this.crop();\n return {\n left: `${c.x * scale}px`,\n top: `${c.y * scale}px`,\n width: `${c.width * scale}px`,\n height: `${c.height * scale}px`,\n };\n });\n\n /** پیش‌نمایش نهایی (کوچیک، حداکثر ۴۸۰ پیکسل) — شامل همه‌چیز، حتی افکت کارتونی */\n protected readonly previewUrl = computed(() => {\n const rc = this.rotatedWorkingCanvas();\n const c = this.crop();\n if (!rc || c.width <= 0 || c.height <= 0) return null;\n const canvas = renderComposite(rc, rc.width, rc.height, c, this.adjustments(), 480, 480);\n return canvas.toDataURL('image/png');\n });\n\n private moveSnapshot: NgxCropRect | null = null;\n private resizeSnapshot: NgxCropRect | null = null;\n\n constructor() {\n // بارگذاری تصویر هروقت source عوض بشه\n effect(() => {\n const src = this.source();\n if (!src) {\n this.originalImage.set(null);\n this.workingCanvas.set(null);\n return;\n }\n this.loading.set(true);\n this.loadError.set(null);\n loadImage(src)\n .then((img) => {\n this.originalImage.set(img);\n this.workingCanvas.set(createWorkingCopy(img));\n this.resetAdjustments();\n })\n .catch((err) => this.loadError.set(err?.message ?? 'Failed to load image'))\n .finally(() => this.loading.set(false));\n });\n\n // هر وقت چرخیده‌شده عوض بشه (بارگذاریِ تصویر جدید یا چرخش)، کراپ روی کل قاب ریست بشه\n effect(() => {\n const rc = this.rotatedWorkingCanvas();\n if (rc) {\n this.crop.set({ x: 0, y: 0, width: rc.width, height: rc.height });\n }\n });\n\n // اگه فیلترِ فعلاً انتخاب‌شده دیگه توی لیستِ مجازِ filters() نباشه (مثلاً\n // مصرف‌کننده cartoon رو غیرفعال کرده درحالی‌که کاربر روش بود)، برو روی\n // اولین فیلترِ مجاز؛ اگه لیست خالی باشه (کلاً فیلتر مخفیه)، روی none بمون.\n effect(() => {\n const allowed = this.filters();\n if (allowed.length && !allowed.includes(this.filterPreset())) {\n this.filterPreset.set(allowed[0]);\n }\n });\n\n // اندازه‌گیریِ زنده‌ی عرضِ واقعیِ کانتینر — چون عرض همیشه ۱۰۰٪ (fluid)ه،\n // فقط با ResizeObserver می‌شه فهمید الان چند پیکسله (نه یه عددِ ثابتِ ورودی).\n effect((onCleanup) => {\n const el = this.stageWrapEl()?.nativeElement;\n if (!el) return;\n this.containerWidth.set(el.getBoundingClientRect().width);\n const ro = new ResizeObserver((entries) => {\n const width = entries[0]?.contentRect.width;\n if (width != null) this.containerWidth.set(width);\n });\n ro.observe(el);\n onCleanup(() => ro.disconnect());\n });\n }\n\n private resetAdjustments(): void {\n this.rotation.set(0);\n this.brightness.set(100);\n this.contrast.set(100);\n this.saturation.set(100);\n this.filterPreset.set(this.filters()[0] ?? 'none');\n }\n\n protected rotateBy(delta: number): void {\n this.rotation.update((r) => {\n let next = r + delta;\n if (next > 180) next -= 360;\n if (next < -180) next += 360;\n return next;\n });\n }\n\n protected setFilter(preset: NgxImageFilterPreset): void {\n this.filterPreset.set(preset);\n }\n\n // ---------- درگ جابه‌جاییِ کل کراپ‌باکس ----------\n protected onMoveDragStart(): void {\n this.moveSnapshot = { ...this.crop() };\n }\n\n protected onMoveDragMove(delta: NgxPointerDragDelta): void {\n const rc = this.rotatedWorkingCanvas();\n const snap = this.moveSnapshot;\n if (!rc || !snap) return;\n const scale = this.displayScale();\n const dxSrc = delta.dx / scale;\n const dySrc = delta.dy / scale;\n const maxX = Math.max(0, rc.width - snap.width);\n const maxY = Math.max(0, rc.height - snap.height);\n const x = Math.min(Math.max(0, snap.x + dxSrc), maxX);\n const y = Math.min(Math.max(0, snap.y + dySrc), maxY);\n this.crop.set({ ...snap, x, y });\n }\n\n // ---------- درگ ریسایز از گوشه‌ها ----------\n protected onResizeDragStart(): void {\n this.resizeSnapshot = { ...this.crop() };\n }\n\n protected onResizeDragMove(corner: Corner, delta: NgxPointerDragDelta): void {\n const rc = this.rotatedWorkingCanvas();\n const snap = this.resizeSnapshot;\n if (!rc || !snap) return;\n\n const scale = this.displayScale();\n const dxSrc = delta.dx / scale;\n const dySrc = delta.dy / scale;\n const minSize = 24;\n\n let { x, y, width, height } = snap;\n\n if (corner === 'nw' || corner === 'sw') {\n const newX = Math.min(snap.x + dxSrc, snap.x + snap.width - minSize);\n x = Math.max(0, newX);\n width = snap.x + snap.width - x;\n }\n if (corner === 'ne' || corner === 'se') {\n width = Math.min(Math.max(minSize, snap.width + dxSrc), rc.width - snap.x);\n }\n if (corner === 'nw' || corner === 'ne') {\n const newY = Math.min(snap.y + dySrc, snap.y + snap.height - minSize);\n y = Math.max(0, newY);\n height = snap.y + snap.height - y;\n }\n if (corner === 'sw' || corner === 'se') {\n height = Math.min(Math.max(minSize, snap.height + dySrc), rc.height - snap.y);\n }\n\n const ratio = this.aspectRatio();\n if (ratio) {\n height = width / ratio;\n }\n\n this.crop.set({ x, y, width, height });\n }\n\n protected cancel(): void {\n this.cancelled.emit();\n }\n\n async save(): Promise<void> {\n const original = this.originalImage();\n const working = this.workingCanvas();\n if (!original || !working) return;\n\n this.saving.set(true);\n try {\n // نسبت مقیاس بین کپیِ کوچیک‌شده (که کراپ/چرخش روش تعریف شده) و تصویر\n // اصلیِ کامل. چون createWorkingCopy مقیاس یکنواخت (هم‌جهت) اعمال\n // می‌کنه، همین یه ضریب برای هر دو بعد و بعد از چرخش هم معتبر می‌مونه.\n const scaleToOriginal = original.naturalWidth / working.width;\n\n const rotatedFull = renderRotated(\n original,\n original.naturalWidth,\n original.naturalHeight,\n this.rotation(),\n );\n\n const c = this.crop();\n const cropInFullRes: NgxCropRect = {\n x: c.x * scaleToOriginal,\n y: c.y * scaleToOriginal,\n width: c.width * scaleToOriginal,\n height: c.height * scaleToOriginal,\n };\n\n const finalCanvas = renderComposite(\n rotatedFull,\n rotatedFull.width,\n rotatedFull.height,\n cropInFullRes,\n this.adjustments(),\n this.outputMaxWidth(),\n this.outputMaxHeight(),\n );\n\n const type = this.outputType();\n const blob = await canvasToBlob(finalCanvas, type, this.quality());\n const dataUrl = finalCanvas.toDataURL(type, this.quality());\n this.saved.emit({ blob, dataUrl, width: finalCanvas.width, height: finalCanvas.height });\n } finally {\n this.saving.set(false);\n }\n }\n}\n","@if (loading()) {\n <div class=\"ngx-ie-state\">{{ localize().LoadingImage }}</div>\n} @else if (loadError()) {\n <div class=\"ngx-ie-state ngx-ie-state--error\">{{ loadError() }}</div>\n} @else if (stageImageUrl()) {\n <div class=\"ngx-ie-layout\">\n <div class=\"ngx-ie-stage-wrap\" #stageWrap>\n <div\n class=\"ngx-ie-stage\"\n [style.width.px]=\"stageSize().width\"\n [style.height.px]=\"stageSize().height\">\n <img class=\"ngx-ie-stage-img\" [src]=\"stageImageUrl()\" alt=\"\" draggable=\"false\" />\n\n <div\n class=\"ngx-ie-crop-box\"\n [style.left]=\"cropOverlayStyle().left\"\n [style.top]=\"cropOverlayStyle().top\"\n [style.width]=\"cropOverlayStyle().width\"\n [style.height]=\"cropOverlayStyle().height\"\n ngxPointerDrag\n (dragStart)=\"onMoveDragStart()\"\n (dragMove)=\"onMoveDragMove($event)\">\n <span\n class=\"ngx-ie-handle ngx-ie-handle--nw\"\n ngxPointerDrag\n (dragStart)=\"onResizeDragStart()\"\n (dragMove)=\"onResizeDragMove('nw', $event)\"></span>\n <span\n class=\"ngx-ie-handle ngx-ie-handle--ne\"\n ngxPointerDrag\n (dragStart)=\"onResizeDragStart()\"\n (dragMove)=\"onResizeDragMove('ne', $event)\"></span>\n <span\n class=\"ngx-ie-handle ngx-ie-handle--sw\"\n ngxPointerDrag\n (dragStart)=\"onResizeDragStart()\"\n (dragMove)=\"onResizeDragMove('sw', $event)\"></span>\n <span\n class=\"ngx-ie-handle ngx-ie-handle--se\"\n ngxPointerDrag\n (dragStart)=\"onResizeDragStart()\"\n (dragMove)=\"onResizeDragMove('se', $event)\"></span>\n </div>\n </div>\n </div>\n\n <div class=\"ngx-ie-panel-row\">\n <div class=\"ngx-ie-panel\">\n <div class=\"ngx-ie-preview\">\n @if (previewUrl(); as url) {\n <img [src]=\"url\" alt=\"Preview\" />\n }\n </div>\n\n <div class=\"ngx-ie-row ngx-ie-rotate-row\">\n <button type=\"button\" (click)=\"rotateBy(-90)\" title=\"Rotate 90° left\">⟲ 90</button>\n <button type=\"button\" (click)=\"rotateBy(90)\" title=\"Rotate 90° right\">⟳ 90</button>\n </div>\n\n <label class=\"ngx-ie-field\">\n <slider\n [ngModel]=\"rotation()\"\n (ngModelChange)=\"rotation.set($event)\"\n [min]=\"-180\"\n [max]=\"180\">\n <span>{{ localize().Rotation }} ({{ rotation() }}°)</span>\n </slider>\n\n <button\n type=\"button\"\n (click)=\"rotation.set(0)\"\n class=\"ngx-ie-btn-secondary\"\n [title]=\"localize().Reset\">\n x\n </button>\n </label>\n\n <label class=\"ngx-ie-field\">\n <slider\n [ngModel]=\"brightness()\"\n (ngModelChange)=\"brightness.set($event)\"\n [min]=\"0\"\n [max]=\"200\">\n <span>{{ localize().Brightness }} ({{ brightness() }}%)</span>\n </slider>\n <button\n type=\"button\"\n (click)=\"brightness.set(100)\"\n class=\"ngx-ie-btn-secondary\"\n [title]=\"localize().Reset\">\n x\n </button>\n </label>\n\n <label class=\"ngx-ie-field\">\n <slider\n [ngModel]=\"contrast()\"\n (ngModelChange)=\"contrast.set($event)\"\n [min]=\"0\"\n [max]=\"200\">\n <span>{{ localize().Contrast }} ({{ contrast() }}%)</span>\n </slider>\n <button\n type=\"button\"\n (click)=\"contrast.set(100)\"\n class=\"ngx-ie-btn-secondary\"\n [title]=\"localize().Reset\">\n x\n </button>\n </label>\n\n <label class=\"ngx-ie-field\">\n <slider\n [ngModel]=\"saturation()\"\n (ngModelChange)=\"saturation.set($event)\"\n [min]=\"0\"\n [max]=\"200\">\n <span>{{ localize().Saturation }} ({{ saturation() }}%)</span>\n </slider>\n <button\n type=\"button\"\n (click)=\"saturation.set(100)\"\n class=\"ngx-ie-btn-secondary\"\n [title]=\"localize().Reset\">\n x\n </button>\n </label>\n\n @if (filters().length) {\n <div>\n <span>{{ localize().Filter }}</span>\n <div class=\"ngx-ie-filter-row\">\n @for (f of filters(); track f) {\n <button type=\"button\" [class.active]=\"filterPreset() === f\" (click)=\"setFilter(f)\">\n {{ filterLabels()[f] }}\n </button>\n }\n </div>\n </div>\n }\n\n <div class=\"ngx-ie-row ngx-ie-actions\">\n <button type=\"button\" class=\"ngx-ie-btn-secondary\" (click)=\"cancel()\">\n {{ localize().Cancel }}\n </button>\n <button type=\"button\" class=\"ngx-ie-btn-primary\" [disabled]=\"saving()\" (click)=\"save()\">\n {{ saving() ? localize().Saving : localize().Save }}\n </button>\n </div>\n </div>\n </div>\n </div>\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ngx-kit-image-editor.mjs","sources":["../../../projects/libs/image-editor/directives/pointer-drag.directive.ts","../../../projects/libs/image-editor/utils/image-io.ts","../../../projects/libs/image-editor/utils/cartoonify.ts","../../../projects/libs/image-editor/utils/render-pipeline.ts","../../../projects/libs/image-editor/tokens/localization.ts","../../../projects/libs/image-editor/components/image-editor.component.ts","../../../projects/libs/image-editor/components/image-editor.component.html","../../../projects/libs/image-editor/ngx-kit-image-editor.ts"],"sourcesContent":["import { Directive, HostListener, output } from '@angular/core';\n\nexport interface NgxPointerDragDelta {\n dx: number;\n dy: number;\n}\n\n/**\n * درگ عمومی روی پایه‌ی Pointer Events + setPointerCapture (دقیقاً همون\n * تکنیکی که در ngx-kit/data-table برای ریسایز ستون استفاده شده) — نیازی به\n * listener سطح document نداره چون بعد از setPointerCapture، رویدادهای\n * pointermove/pointerup حتی بیرون از محدوده‌ی المنت هم به خودش می‌رسن.\n *\n * dx/dy تجمعی از لحظه‌ی pointerdown هستن (نه دلتای بین دو move متوالی)، چون\n * معمولاً مصرف‌کننده می‌خواد «موقعیت شروع + دلتای کل» رو حساب کنه، نه جمع\n * تدریجی گرد شونده‌ی دلتاهای ریز.\n */\n@Directive({\n selector: '[ngxPointerDrag]',\n standalone: true,\n})\nexport class NgxPointerDragDirective {\n dragStart = output<void>();\n dragMove = output<NgxPointerDragDelta>();\n dragEnd = output<void>();\n\n private dragging = false;\n private startX = 0;\n private startY = 0;\n\n @HostListener('pointerdown', ['$event'])\n onPointerDown(ev: PointerEvent): void {\n ev.preventDefault();\n ev.stopPropagation();\n this.dragging = true;\n this.startX = ev.clientX;\n this.startY = ev.clientY;\n (ev.target as HTMLElement).setPointerCapture(ev.pointerId);\n this.dragStart.emit();\n }\n\n @HostListener('pointermove', ['$event'])\n onPointerMove(ev: PointerEvent): void {\n if (!this.dragging) return;\n this.dragMove.emit({ dx: ev.clientX - this.startX, dy: ev.clientY - this.startY });\n }\n\n @HostListener('pointerup')\n @HostListener('pointercancel')\n onPointerUp(): void {\n if (!this.dragging) return;\n this.dragging = false;\n this.dragEnd.emit();\n }\n}\n","/** یه File/Blob/data-URL/URL رو به یک HTMLImageElement بارگذاری‌شده تبدیل می‌کنه */\nexport function loadImage(source: File | Blob | string): Promise<HTMLImageElement> {\n return new Promise((resolve, reject) => {\n const img = new Image();\n // برای URLهای cross-origin لازم می‌شه، وگرنه canvas بعداً «tainted» می‌شه\n // و toBlob/toDataURL با SecurityError شکست می‌خوره.\n img.crossOrigin = 'anonymous';\n\n const objectUrl = typeof source === 'string' ? null : URL.createObjectURL(source);\n const url = objectUrl ?? (source as string);\n\n img.onload = () => {\n if (objectUrl) URL.revokeObjectURL(objectUrl);\n resolve(img);\n };\n img.onerror = () => {\n if (objectUrl) URL.revokeObjectURL(objectUrl);\n reject(new Error('Failed to load image'));\n };\n img.src = url;\n });\n}\n\n/** canvas.toBlob به‌صورت Promise، به‌همراه fallback برای مرورگرهای قدیمی‌تر */\nexport function canvasToBlob(\n canvas: HTMLCanvasElement,\n type = 'image/jpeg',\n quality = 0.92,\n): Promise<Blob> {\n return new Promise((resolve, reject) => {\n canvas.toBlob(\n (blob) => {\n if (blob) resolve(blob);\n else reject(new Error('Failed to convert canvas to blob'));\n },\n type,\n quality,\n );\n });\n}\n\n/**\n * یه کپیِ کوچیک‌شده از تصویر اصلی می‌سازه که کل UI ویرایشگر (چرخش، کراپ،\n * پیش‌نمایش فیلترها/کارتونی) روی همین کار می‌کنه، نه روی تصویر اصلی که\n * ممکنه چند مگاپیکسل باشه. این باعث می‌شه درگ‌کردنِ اسلایدرها یا لبه‌های\n * کراپ روون بمونه؛ خروجی نهایی (save) همیشه از روی تصویر اصلیِ کامل رندر\n * می‌شه، نه از روی این کپی.\n */\nexport function createWorkingCopy(img: HTMLImageElement, maxSize = 1200): HTMLCanvasElement {\n const { width, height } = fitWithin(img.naturalWidth, img.naturalHeight, maxSize, maxSize);\n const canvas = document.createElement('canvas');\n canvas.width = width;\n canvas.height = height;\n const ctx = canvas.getContext('2d')!;\n ctx.drawImage(img, 0, 0, width, height);\n return canvas;\n}\n\n/** ابعاد جدید رو طوری حساب می‌کنه که از maxWidth/maxHeight بیشتر نشه، با حفظ نسبت تصویر */\nexport function fitWithin(\n width: number,\n height: number,\n maxWidth?: number,\n maxHeight?: number,\n): { width: number; height: number } {\n if (!maxWidth && !maxHeight) return { width, height };\n let ratio = 1;\n if (maxWidth) ratio = Math.min(ratio, maxWidth / width);\n if (maxHeight) ratio = Math.min(ratio, maxHeight / height);\n if (ratio >= 1) return { width, height };\n return { width: Math.round(width * ratio), height: Math.round(height * ratio) };\n}\n","/**\n * افکت «کارتونی»: چون ctx.filter استاندارد چیزی شبیه cartoon نداره (فقط\n * brightness/contrast/saturate/grayscale/sepia/invert/blur/hue-rotate)، این\n * یکی رو واقعاً با پردازش پیکسلی پیاده کردیم؛ دو مرحله:\n *\n * ۱) Posterize: هر کانال رنگ به تعداد محدودی سطح گرد می‌شه (پهنه‌های رنگیِ\n * صاف و یکدست، حسِ کارتونی رنگ می‌ده).\n * ۲) لبه‌یابی Sobel روی نسخه‌ی خاکستریِ تصویر: هرجا شدت لبه از حد آستانه\n * بیشتر باشه، پیکسل تیره می‌شه (حسِ خط دور کارتونی).\n *\n * روی خودِ ImageData کار می‌کنه، پس هزینه‌ش با اندازه‌ی تصویر خطی‌ست؛ برای\n * تصاویر خیلی بزرگ (>~3000px) بهتره قبلش resize بشه (که در کامپوننت اصلی\n * با fitWithin قبل از اعمال فیلتر انجام می‌شه).\n */\nexport function applyCartoonEffect(\n ctx: CanvasRenderingContext2D,\n width: number,\n height: number,\n options: { levels?: number; edgeThreshold?: number } = {},\n): void {\n const levels = options.levels ?? 5;\n const edgeThreshold = options.edgeThreshold ?? 80;\n\n const imageData = ctx.getImageData(0, 0, width, height);\n const src = imageData.data;\n\n // ۱) خاکستری برای Sobel\n const gray = new Uint8ClampedArray(width * height);\n for (let i = 0, p = 0; i < src.length; i += 4, p++) {\n gray[p] = (src[i] * 0.299 + src[i + 1] * 0.587 + src[i + 2] * 0.114) | 0;\n }\n\n // ۲) Posterize رنگ‌ها\n const step = 255 / (levels - 1);\n for (let i = 0; i < src.length; i += 4) {\n src[i] = Math.round(Math.round(src[i] / step) * step);\n src[i + 1] = Math.round(Math.round(src[i + 1] / step) * step);\n src[i + 2] = Math.round(Math.round(src[i + 2] / step) * step);\n }\n\n // ۳) Sobel روی gray، خط دور تیره روی src\n const gxKernel = [-1, 0, 1, -2, 0, 2, -1, 0, 1];\n const gyKernel = [-1, -2, -1, 0, 0, 0, 1, 2, 1];\n\n for (let y = 1; y < height - 1; y++) {\n for (let x = 1; x < width - 1; x++) {\n let gx = 0;\n let gy = 0;\n let k = 0;\n for (let dy = -1; dy <= 1; dy++) {\n for (let dx = -1; dx <= 1; dx++) {\n const v = gray[(y + dy) * width + (x + dx)];\n gx += v * gxKernel[k];\n gy += v * gyKernel[k];\n k++;\n }\n }\n const magnitude = Math.sqrt(gx * gx + gy * gy);\n if (magnitude > edgeThreshold) {\n const idx = (y * width + x) * 4;\n src[idx] = 20;\n src[idx + 1] = 20;\n src[idx + 2] = 20;\n }\n }\n }\n\n ctx.putImageData(imageData, 0, 0);\n}\n","import { NgxCropRect, NgxImageEditorAdjustments } from '../contracts/image-editor-types';\nimport { applyCartoonEffect } from './cartoonify';\nimport { fitWithin } from './image-io';\n\n/** تصویر مبدأ رو با زاویه‌ی داده‌شده روی یه canvas جدید (به اندازه‌ی bounding-box نتیجه) می‌چرخونه */\nexport function renderRotated(\n source: CanvasImageSource,\n width: number,\n height: number,\n degrees: number,\n): HTMLCanvasElement {\n const rad = (degrees * Math.PI) / 180;\n const sin = Math.abs(Math.sin(rad));\n const cos = Math.abs(Math.cos(rad));\n const newW = Math.max(1, Math.round(width * cos + height * sin));\n const newH = Math.max(1, Math.round(width * sin + height * cos));\n\n const canvas = document.createElement('canvas');\n canvas.width = newW;\n canvas.height = newH;\n const ctx = canvas.getContext('2d')!;\n ctx.translate(newW / 2, newH / 2);\n ctx.rotate(rad);\n ctx.drawImage(source, -width / 2, -height / 2, width, height);\n return canvas;\n}\n\nfunction buildCssFilter(adjustments: NgxImageEditorAdjustments): string {\n const parts = [\n `brightness(${adjustments.brightness}%)`,\n `contrast(${adjustments.contrast}%)`,\n `saturate(${adjustments.saturation}%)`,\n ];\n if (adjustments.filter === 'grayscale') parts.push('grayscale(1)');\n if (adjustments.filter === 'sepia') parts.push('sepia(1)');\n if (adjustments.filter === 'invert') parts.push('invert(1)');\n return parts.join(' ');\n}\n\n/**\n * کراپ + فیلترها رو روی یه canvas خروجی می‌سازه. brightness/contrast/\n * saturation/grayscale/sepia/invert همه با ctx.filter بومیِ Canvas 2D انجام\n * می‌شن (شتاب‌دهی‌شده توسط مرورگر، بدون حلقه‌ی پیکسلی دستی)؛ فقط cartoon\n * (که معادل بومی نداره) با پردازش پیکسلی جدا انجام می‌شه.\n *\n * maxWidth/maxHeight برای دو حالت استفاده می‌شه: پیش‌نمایش زنده (عدد کوچیک،\n * برای واکنش‌گرا موندن حین کشیدن اسلایدرها) و خروجی نهایی (بدون محدودیت یا\n * محدودیت دلخواه کاربر).\n */\nexport function renderComposite(\n source: CanvasImageSource,\n sourceWidth: number,\n sourceHeight: number,\n crop: NgxCropRect,\n adjustments: NgxImageEditorAdjustments,\n maxWidth?: number,\n maxHeight?: number,\n): HTMLCanvasElement {\n const { width: outW, height: outH } = fitWithin(crop.width, crop.height, maxWidth, maxHeight);\n\n const canvas = document.createElement('canvas');\n canvas.width = Math.max(1, outW);\n canvas.height = Math.max(1, outH);\n const ctx = canvas.getContext('2d')!;\n\n ctx.filter = buildCssFilter(adjustments);\n ctx.drawImage(source, crop.x, crop.y, crop.width, crop.height, 0, 0, canvas.width, canvas.height);\n ctx.filter = 'none';\n\n if (adjustments.filter === 'cartoon') {\n applyCartoonEffect(ctx, canvas.width, canvas.height);\n }\n\n return canvas;\n}\n","import { InjectionToken } from '@angular/core';\r\n\r\nexport const NGX_IMAGE_EDITOR_LOCALIZATION = new InjectionToken<NgxImageEditorLocalization>(\r\n 'ngx-image-localization',\r\n {\r\n factory: () => DEFAULT_NGX_IMAGE_EDITOR_LOCALIZATION,\r\n },\r\n);\r\n\r\nexport class NgxImageEditorLocalization {\r\n LoadingImage = 'Loading image…';\r\n Rotation = 'Fine rotation';\r\n Brightness = 'Brightness';\r\n Contrast = 'Contrast';\r\n Saturation = 'Saturation';\r\n Filter = 'Filter';\r\n None = 'None';\r\n Grayscale = 'Grayscale';\r\n Sepia = 'Sepia';\r\n Invert = 'Invert';\r\n Cartoon = 'Cartoon';\r\n Cancel = 'Cancel';\r\n Save = 'Save';\r\n Saving = 'Saving…';\r\n Reset = 'Reset';\r\n}\r\nexport const DEFAULT_NGX_IMAGE_EDITOR_LOCALIZATION = new NgxImageEditorLocalization();\r\n","import {\r\n ChangeDetectionStrategy,\r\n Component,\r\n ElementRef,\r\n computed,\r\n effect,\r\n inject,\r\n input,\r\n output,\r\n signal,\r\n viewChild,\r\n} from '@angular/core';\r\nimport { FormsModule } from '@angular/forms';\r\nimport { SliderComponent } from 'ngx-kit/shared';\r\nimport {\r\n NgxCropRect,\r\n NgxImageEditorAdjustments,\r\n NgxImageEditorResult,\r\n NgxImageFilterPreset,\r\n} from '../contracts/image-editor-types';\r\nimport { NgxPointerDragDelta, NgxPointerDragDirective } from '../directives/pointer-drag.directive';\r\nimport { canvasToBlob, createWorkingCopy, loadImage } from '../utils/image-io';\r\nimport { renderComposite, renderRotated } from '../utils/render-pipeline';\r\nimport { Corner } from '../types/corner';\r\nimport { NGX_IMAGE_EDITOR_LOCALIZATION, NgxImageEditorLocalization } from '../tokens/localization';\r\n\r\nconst ALL_FILTERS: NgxImageFilterPreset[] = ['none', 'grayscale', 'sepia', 'invert', 'cartoon'];\r\n\r\n/**\r\n * ویرایشگر تصویر: کراپ + چرخش + روشنایی/کنتراست/اشباع + فیلترهای آماده\r\n * (سیاه‌وسفید، سپیا، معکوس، کارتونی) + فشرده‌سازی خروجی. کاملاً روی Canvas\r\n * خام پیاده شده، بدون هیچ وابستگی خارجی‌ای.\r\n *\r\n * نکته‌ی مهمِ معماری: تمام تعامل زنده (چرخوندن، جابه‌جا/ریسایز کراپ‌باکس،\r\n * پیش‌نمایش فیلترها حتی کارتونی) روی یه کپیِ کوچیک‌شده از تصویر انجام می‌شه\r\n * (createWorkingCopy)، نه روی تصویر اصلی که ممکنه چند مگاپیکسل باشه — وگرنه\r\n * درگ‌کردن اسلایدرها/گوشه‌های کراپ رو کاربر حس تاخیر می‌کرد. فقط لحظه‌ی\r\n * save()، رندر نهایی از روی تصویر اصلیِ کامل انجام می‌شه.\r\n *\r\n * اندازه‌ی صحنه (stage) با panelSize کنترل می‌شه: عرض همیشه ۱۰۰٪ عرضِ\r\n * والدِ کامپوننته (با ResizeObserver اندازه‌گیری می‌شه، پس با تغییر سایز\r\n * صفحه/layout هم زنده هماهنگ می‌مونه)، ارتفاع دقیقاً همون چیزیه که کاربر با\r\n * panelSize می‌ده. تصویر همیشه با یک مقیاسِ «contain» واقعی (هم بر اساس\r\n * عرض، هم بر اساس ارتفاع — هرکدوم تنگ‌تره) جا داده می‌شه، پس کلِ تصویر\r\n * همیشه در محدوده‌ی همین باکس دیده می‌شه، صرف‌نظر از اندازه‌ی واقعیِ فایل.\r\n * سقفِ مقیاس هم ۱ هست، یعنی تصاویر کوچیک بزرگ‌نمایی نمی‌شن (که باعثِ محو\r\n * شدن‌شون می‌شد).\r\n */\r\n@Component({\r\n selector: 'ngx-image-editor',\r\n standalone: true,\r\n imports: [FormsModule, SliderComponent, NgxPointerDragDirective],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './image-editor.component.html',\r\n styleUrl: './image-editor.component.scss',\r\n host: { class: 'ngx-image-editor-host' },\r\n})\r\nexport class NgxImageEditorComponent {\r\n source = input<File | Blob | string | null>(null);\r\n /** قفل نسبتِ کراپ (مثلاً ۱ برای آواتار مربعی)؛ undefined یعنی آزاد */\r\n aspectRatio = input<number | undefined>(undefined);\r\n outputMaxWidth = input<number | undefined>(undefined);\r\n outputMaxHeight = input<number | undefined>(undefined);\r\n outputType = input<'image/jpeg' | 'image/png' | 'image/webp'>('image/jpeg');\r\n\r\n /**\r\n * کدوم فیلترها نشون داده بشن (و به چه ترتیبی). اگه ندید، هر ۵ تا نشون داده\r\n * می‌شن. آرایه‌ی خالی یعنی کلِ بخشِ فیلتر مخفی بشه.\r\n */\r\n filters = input<NgxImageFilterPreset[]>(ALL_FILTERS);\r\n quality = input(0.92);\r\n\r\n defaultLocalization = inject(NGX_IMAGE_EDITOR_LOCALIZATION);\r\n localize = input<NgxImageEditorLocalization>(this.defaultLocalization);\r\n\r\n saved = output<NgxImageEditorResult>();\r\n cancelled = output<void>();\r\n\r\n protected readonly loading = signal(false);\r\n protected readonly saving = signal(false);\r\n protected readonly loadError = signal<string | null>(null);\r\n\r\n private readonly originalImage = signal<HTMLImageElement | null>(null);\r\n private readonly workingCanvas = signal<HTMLCanvasElement | null>(null);\r\n private readonly stageWrapEl = viewChild<ElementRef<HTMLElement>>('stageWrap');\r\n /** عرضِ واقعیِ رندرشده‌ی کانتینر؛ چون عرض همیشه ۱۰۰٪ (fluid) هست، باید زنده اندازه‌گیری بشه */\r\n private readonly containerWidth = signal(0);\r\n\r\n protected readonly rotation = signal(0);\r\n protected readonly brightness = signal(100);\r\n protected readonly contrast = signal(100);\r\n protected readonly saturation = signal(100);\r\n protected readonly filterPreset = signal<NgxImageFilterPreset>('none');\r\n\r\n protected readonly crop = signal<NgxCropRect>({ x: 0, y: 0, width: 0, height: 0 });\r\n\r\n protected readonly adjustments = computed<NgxImageEditorAdjustments>(() => ({\r\n brightness: this.brightness(),\r\n contrast: this.contrast(),\r\n saturation: this.saturation(),\r\n rotation: this.rotation(),\r\n filter: this.filterPreset(),\r\n }));\r\n\r\n protected readonly filterLabels = computed<Record<NgxImageFilterPreset, string>>(() => {\r\n const t = this.localize();\r\n return {\r\n none: t.None,\r\n grayscale: t.Grayscale,\r\n sepia: t.Sepia,\r\n invert: t.Invert,\r\n cartoon: t.Cartoon,\r\n };\r\n });\r\n\r\n /** تصویرِ (کوچیک‌شده‌یِ) چرخیده — پایه‌ی نمایش صحنه‌ی کراپ */\r\n protected readonly rotatedWorkingCanvas = computed(() => {\r\n const wc = this.workingCanvas();\r\n if (!wc) return null;\r\n return renderRotated(wc, wc.width, wc.height, this.rotation());\r\n });\r\n\r\n protected readonly panelSize = computed(() => {\r\n return this.stageWrapEl()?.nativeElement.getBoundingClientRect().height ?? 0;\r\n });\r\n\r\n /**\r\n * مقیاسِ «contain» واقعی: کوچیک‌ترینِ نسبتِ عرض و ارتفاع (هرکدوم تنگ‌تره)\r\n * تعیین‌کننده‌ست، و سقفش هم ۱ هست تا تصاویر کوچیک بزرگ‌نمایی نشن.\r\n */\r\n protected readonly displayScale = computed(() => {\r\n const rc = this.rotatedWorkingCanvas();\r\n const containerW = this.containerWidth();\r\n const panelH = this.panelSize();\r\n if (!rc || rc.width <= 0 || rc.height <= 0 || containerW <= 0 || panelH <= 0) return 1;\r\n return Math.min(containerW / rc.width, panelH / rc.height, 1);\r\n });\r\n\r\n protected readonly stageImageUrl = computed(() => {\r\n const rc = this.rotatedWorkingCanvas();\r\n return rc ? rc.toDataURL('image/png') : null;\r\n });\r\n\r\n protected readonly stageSize = computed(() => {\r\n const rc = this.rotatedWorkingCanvas();\r\n const scale = this.displayScale();\r\n return rc ? { width: rc.width * scale, height: rc.height * scale } : { width: 0, height: 0 };\r\n });\r\n\r\n protected readonly cropOverlayStyle = computed(() => {\r\n const scale = this.displayScale();\r\n const c = this.crop();\r\n return {\r\n left: `${c.x * scale}px`,\r\n top: `${c.y * scale}px`,\r\n width: `${c.width * scale}px`,\r\n height: `${c.height * scale}px`,\r\n };\r\n });\r\n\r\n /** پیش‌نمایش نهایی (کوچیک، حداکثر ۴۸۰ پیکسل) — شامل همه‌چیز، حتی افکت کارتونی */\r\n protected readonly previewUrl = computed(() => {\r\n const rc = this.rotatedWorkingCanvas();\r\n const c = this.crop();\r\n if (!rc || c.width <= 0 || c.height <= 0) return null;\r\n const canvas = renderComposite(rc, rc.width, rc.height, c, this.adjustments(), 480, 480);\r\n return canvas.toDataURL('image/png');\r\n });\r\n\r\n private moveSnapshot: NgxCropRect | null = null;\r\n private resizeSnapshot: NgxCropRect | null = null;\r\n\r\n constructor() {\r\n // بارگذاری تصویر هروقت source عوض بشه\r\n effect(() => {\r\n const src = this.source();\r\n if (!src) {\r\n this.originalImage.set(null);\r\n this.workingCanvas.set(null);\r\n return;\r\n }\r\n this.loading.set(true);\r\n this.loadError.set(null);\r\n loadImage(src)\r\n .then((img) => {\r\n this.originalImage.set(img);\r\n this.workingCanvas.set(createWorkingCopy(img));\r\n this.resetAdjustments();\r\n })\r\n .catch((err) => this.loadError.set(err?.message ?? 'Failed to load image'))\r\n .finally(() => this.loading.set(false));\r\n });\r\n\r\n // هر وقت چرخیده‌شده عوض بشه (بارگذاریِ تصویر جدید یا چرخش)، کراپ روی کل قاب ریست بشه\r\n effect(() => {\r\n const rc = this.rotatedWorkingCanvas();\r\n if (rc) {\r\n this.crop.set({ x: 0, y: 0, width: rc.width, height: rc.height });\r\n }\r\n });\r\n\r\n // اگه فیلترِ فعلاً انتخاب‌شده دیگه توی لیستِ مجازِ filters() نباشه (مثلاً\r\n // مصرف‌کننده cartoon رو غیرفعال کرده درحالی‌که کاربر روش بود)، برو روی\r\n // اولین فیلترِ مجاز؛ اگه لیست خالی باشه (کلاً فیلتر مخفیه)، روی none بمون.\r\n effect(() => {\r\n const allowed = this.filters();\r\n if (allowed.length && !allowed.includes(this.filterPreset())) {\r\n this.filterPreset.set(allowed[0]);\r\n }\r\n });\r\n\r\n // اندازه‌گیریِ زنده‌ی عرضِ واقعیِ کانتینر — چون عرض همیشه ۱۰۰٪ (fluid)ه،\r\n // فقط با ResizeObserver می‌شه فهمید الان چند پیکسله (نه یه عددِ ثابتِ ورودی).\r\n effect((onCleanup) => {\r\n const el = this.stageWrapEl()?.nativeElement;\r\n if (!el) return;\r\n this.containerWidth.set(el.getBoundingClientRect().width);\r\n const ro = new ResizeObserver((entries) => {\r\n const width = entries[0]?.contentRect.width;\r\n if (width != null) this.containerWidth.set(width);\r\n });\r\n ro.observe(el);\r\n onCleanup(() => ro.disconnect());\r\n });\r\n }\r\n\r\n private resetAdjustments(): void {\r\n this.rotation.set(0);\r\n this.brightness.set(100);\r\n this.contrast.set(100);\r\n this.saturation.set(100);\r\n this.filterPreset.set(this.filters()[0] ?? 'none');\r\n }\r\n\r\n protected rotateBy(delta: number): void {\r\n this.rotation.update((r) => {\r\n let next = r + delta;\r\n if (next > 180) next -= 360;\r\n if (next < -180) next += 360;\r\n return next;\r\n });\r\n }\r\n\r\n protected setFilter(preset: NgxImageFilterPreset): void {\r\n this.filterPreset.set(preset);\r\n }\r\n\r\n // ---------- درگ جابه‌جاییِ کل کراپ‌باکس ----------\r\n protected onMoveDragStart(): void {\r\n this.moveSnapshot = { ...this.crop() };\r\n }\r\n\r\n protected onMoveDragMove(delta: NgxPointerDragDelta): void {\r\n const rc = this.rotatedWorkingCanvas();\r\n const snap = this.moveSnapshot;\r\n if (!rc || !snap) return;\r\n const scale = this.displayScale();\r\n const dxSrc = delta.dx / scale;\r\n const dySrc = delta.dy / scale;\r\n const maxX = Math.max(0, rc.width - snap.width);\r\n const maxY = Math.max(0, rc.height - snap.height);\r\n const x = Math.min(Math.max(0, snap.x + dxSrc), maxX);\r\n const y = Math.min(Math.max(0, snap.y + dySrc), maxY);\r\n this.crop.set({ ...snap, x, y });\r\n }\r\n\r\n // ---------- درگ ریسایز از گوشه‌ها ----------\r\n protected onResizeDragStart(): void {\r\n this.resizeSnapshot = { ...this.crop() };\r\n }\r\n\r\n protected onResizeDragMove(corner: Corner, delta: NgxPointerDragDelta): void {\r\n const rc = this.rotatedWorkingCanvas();\r\n const snap = this.resizeSnapshot;\r\n if (!rc || !snap) return;\r\n\r\n const scale = this.displayScale();\r\n const dxSrc = delta.dx / scale;\r\n const dySrc = delta.dy / scale;\r\n const minSize = 24;\r\n\r\n let { x, y, width, height } = snap;\r\n\r\n if (corner === 'nw' || corner === 'sw') {\r\n const newX = Math.min(snap.x + dxSrc, snap.x + snap.width - minSize);\r\n x = Math.max(0, newX);\r\n width = snap.x + snap.width - x;\r\n }\r\n if (corner === 'ne' || corner === 'se') {\r\n width = Math.min(Math.max(minSize, snap.width + dxSrc), rc.width - snap.x);\r\n }\r\n if (corner === 'nw' || corner === 'ne') {\r\n const newY = Math.min(snap.y + dySrc, snap.y + snap.height - minSize);\r\n y = Math.max(0, newY);\r\n height = snap.y + snap.height - y;\r\n }\r\n if (corner === 'sw' || corner === 'se') {\r\n height = Math.min(Math.max(minSize, snap.height + dySrc), rc.height - snap.y);\r\n }\r\n\r\n const ratio = this.aspectRatio();\r\n if (ratio) {\r\n height = width / ratio;\r\n }\r\n\r\n this.crop.set({ x, y, width, height });\r\n }\r\n\r\n protected cancel(): void {\r\n this.cancelled.emit();\r\n }\r\n\r\n async save(): Promise<void> {\r\n const original = this.originalImage();\r\n const working = this.workingCanvas();\r\n if (!original || !working) return;\r\n\r\n this.saving.set(true);\r\n try {\r\n // نسبت مقیاس بین کپیِ کوچیک‌شده (که کراپ/چرخش روش تعریف شده) و تصویر\r\n // اصلیِ کامل. چون createWorkingCopy مقیاس یکنواخت (هم‌جهت) اعمال\r\n // می‌کنه، همین یه ضریب برای هر دو بعد و بعد از چرخش هم معتبر می‌مونه.\r\n const scaleToOriginal = original.naturalWidth / working.width;\r\n\r\n const rotatedFull = renderRotated(\r\n original,\r\n original.naturalWidth,\r\n original.naturalHeight,\r\n this.rotation(),\r\n );\r\n\r\n const c = this.crop();\r\n const cropInFullRes: NgxCropRect = {\r\n x: c.x * scaleToOriginal,\r\n y: c.y * scaleToOriginal,\r\n width: c.width * scaleToOriginal,\r\n height: c.height * scaleToOriginal,\r\n };\r\n\r\n const finalCanvas = renderComposite(\r\n rotatedFull,\r\n rotatedFull.width,\r\n rotatedFull.height,\r\n cropInFullRes,\r\n this.adjustments(),\r\n this.outputMaxWidth(),\r\n this.outputMaxHeight(),\r\n );\r\n\r\n const type = this.outputType();\r\n const blob = await canvasToBlob(finalCanvas, type, this.quality());\r\n const dataUrl = finalCanvas.toDataURL(type, this.quality());\r\n this.saved.emit({ blob, dataUrl, width: finalCanvas.width, height: finalCanvas.height });\r\n } finally {\r\n this.saving.set(false);\r\n }\r\n }\r\n}\r\n","@if (loading()) {\r\n <div class=\"ngx-ie-state\">{{ localize().LoadingImage }}</div>\r\n} @else if (loadError()) {\r\n <div class=\"ngx-ie-state ngx-ie-state--error\">{{ loadError() }}</div>\r\n} @else if (stageImageUrl()) {\r\n <div class=\"ngx-ie-layout\">\r\n <div class=\"ngx-ie-stage-wrap\" #stageWrap>\r\n <div\r\n class=\"ngx-ie-stage\"\r\n [style.width.px]=\"stageSize().width\"\r\n [style.height.px]=\"stageSize().height\">\r\n <img class=\"ngx-ie-stage-img\" [src]=\"stageImageUrl()\" alt=\"\" draggable=\"false\" />\r\n\r\n <div\r\n class=\"ngx-ie-crop-box\"\r\n [style.left]=\"cropOverlayStyle().left\"\r\n [style.top]=\"cropOverlayStyle().top\"\r\n [style.width]=\"cropOverlayStyle().width\"\r\n [style.height]=\"cropOverlayStyle().height\"\r\n ngxPointerDrag\r\n (dragStart)=\"onMoveDragStart()\"\r\n (dragMove)=\"onMoveDragMove($event)\">\r\n <span\r\n class=\"ngx-ie-handle ngx-ie-handle--nw\"\r\n ngxPointerDrag\r\n (dragStart)=\"onResizeDragStart()\"\r\n (dragMove)=\"onResizeDragMove('nw', $event)\"></span>\r\n <span\r\n class=\"ngx-ie-handle ngx-ie-handle--ne\"\r\n ngxPointerDrag\r\n (dragStart)=\"onResizeDragStart()\"\r\n (dragMove)=\"onResizeDragMove('ne', $event)\"></span>\r\n <span\r\n class=\"ngx-ie-handle ngx-ie-handle--sw\"\r\n ngxPointerDrag\r\n (dragStart)=\"onResizeDragStart()\"\r\n (dragMove)=\"onResizeDragMove('sw', $event)\"></span>\r\n <span\r\n class=\"ngx-ie-handle ngx-ie-handle--se\"\r\n ngxPointerDrag\r\n (dragStart)=\"onResizeDragStart()\"\r\n (dragMove)=\"onResizeDragMove('se', $event)\"></span>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"ngx-ie-panel-row\">\r\n <div class=\"ngx-ie-panel\">\r\n <div class=\"ngx-ie-preview\">\r\n @if (previewUrl(); as url) {\r\n <img [src]=\"url\" alt=\"Preview\" />\r\n }\r\n </div>\r\n\r\n <div class=\"ngx-ie-row ngx-ie-rotate-row\">\r\n <button type=\"button\" (click)=\"rotateBy(-90)\" title=\"Rotate 90° left\">⟲ 90</button>\r\n <button type=\"button\" (click)=\"rotateBy(90)\" title=\"Rotate 90° right\">⟳ 90</button>\r\n </div>\r\n\r\n <div class=\"ngx-ie-field\">\r\n <slider\r\n [ngModel]=\"rotation()\"\r\n (ngModelChange)=\"rotation.set($event)\"\r\n [min]=\"-180\"\r\n [max]=\"180\">\r\n <span>{{ localize().Rotation }} ({{ rotation() }}°)</span>\r\n </slider>\r\n\r\n <button\r\n type=\"button\"\r\n (click)=\"rotation.set(0)\"\r\n class=\"ngx-ie-btn-secondary\"\r\n [title]=\"localize().Reset\">\r\n x\r\n </button>\r\n </div>\r\n\r\n <div class=\"ngx-ie-field\">\r\n <slider\r\n [ngModel]=\"brightness()\"\r\n (ngModelChange)=\"brightness.set($event)\"\r\n [min]=\"0\"\r\n [max]=\"200\">\r\n <span>{{ localize().Brightness }} ({{ brightness() }}%)</span>\r\n </slider>\r\n <button\r\n type=\"button\"\r\n (click)=\"brightness.set(100)\"\r\n class=\"ngx-ie-btn-secondary\"\r\n [title]=\"localize().Reset\">\r\n x\r\n </button>\r\n </div>\r\n\r\n <div class=\"ngx-ie-field\">\r\n <slider\r\n [ngModel]=\"contrast()\"\r\n (ngModelChange)=\"contrast.set($event)\"\r\n [min]=\"0\"\r\n [max]=\"200\">\r\n <span>{{ localize().Contrast }} ({{ contrast() }}%)</span>\r\n </slider>\r\n <button\r\n type=\"button\"\r\n (click)=\"contrast.set(100)\"\r\n class=\"ngx-ie-btn-secondary\"\r\n [title]=\"localize().Reset\">\r\n x\r\n </button>\r\n </div>\r\n\r\n <div class=\"ngx-ie-field\">\r\n <slider\r\n [ngModel]=\"saturation()\"\r\n (ngModelChange)=\"saturation.set($event)\"\r\n [min]=\"0\"\r\n [max]=\"200\">\r\n <span>{{ localize().Saturation }} ({{ saturation() }}%)</span>\r\n </slider>\r\n <button\r\n type=\"button\"\r\n (click)=\"saturation.set(100)\"\r\n class=\"ngx-ie-btn-secondary\"\r\n [title]=\"localize().Reset\">\r\n x\r\n </button>\r\n </div>\r\n\r\n @if (filters().length) {\r\n <div>\r\n <span>{{ localize().Filter }}</span>\r\n <div class=\"ngx-ie-filter-row\">\r\n @for (f of filters(); track f) {\r\n <button type=\"button\" [class.active]=\"filterPreset() === f\" (click)=\"setFilter(f)\">\r\n {{ filterLabels()[f] }}\r\n </button>\r\n }\r\n </div>\r\n </div>\r\n }\r\n\r\n <div class=\"ngx-ie-row ngx-ie-actions\">\r\n <button type=\"button\" class=\"ngx-ie-btn-secondary\" (click)=\"cancel()\">\r\n {{ localize().Cancel }}\r\n </button>\r\n <button type=\"button\" class=\"ngx-ie-btn-primary\" [disabled]=\"saving()\" (click)=\"save()\">\r\n {{ saving() ? localize().Saving : localize().Save }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}