Skip to content

Commit

Permalink
Use hammer types from community
Browse files Browse the repository at this point in the history
  • Loading branch information
PowerKiKi authored May 16, 2024
1 parent a3c9a8d commit 8f5da5e
Show file tree
Hide file tree
Showing 5 changed files with 152 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ import { DomSanitizer, HAMMER_LOADER, HammerLoader, SafeStyle, SafeUrl } from '@
import { CropperPosition, Dimensions, ImageCroppedEvent, ImageTransform, LoadedImage, MoveStart } from '../interfaces';
import { OutputFormat, OutputType } from '../interfaces/cropper-options.interface';
import { CropperSettings } from '../interfaces/cropper.settings';
import { MoveTypes } from '../interfaces/move-start.interface';
import { MoveTypes, Position } from '../interfaces/move-start.interface';
import { CropService } from '../services/crop.service';
import { CropperPositionService } from '../services/cropper-position.service';
import { LoadImageService } from '../services/load-image.service';
import { HammerStatic } from '../utils/hammer.utils';
import { HammerStatic, HammerInput } from '../utils/hammer.utils';
import { getEventForKey, getInvertedPositionForKey, getPositionForKey } from '../utils/keyboard.utils';
import { first, takeUntil } from 'rxjs/operators';
import { fromEvent, merge } from 'rxjs';
Expand Down Expand Up @@ -381,7 +381,7 @@ export class ImageCropperComponent implements OnChanges, OnInit {
this.handleMouseUp();
}

startMove(event: Event | BasicEvent, moveType: MoveTypes, position: string | null = null): void {
startMove(event: Event | BasicEvent, moveType: MoveTypes, position: Position | null = null): void {
if (this.disabled
|| this.moveStart?.active && this.moveStart?.type === MoveTypes.Pinch
|| moveType === MoveTypes.Drag && !this.allowMoveImage) {
Expand Down Expand Up @@ -424,7 +424,7 @@ export class ImageCropperComponent implements OnChanges, OnInit {
});
}

startPinch(event: any) {
startPinch(event: HammerInput) {
if (!this.safeImgDataUrl) {
return;
}
Expand Down Expand Up @@ -470,11 +470,8 @@ export class ImageCropperComponent implements OnChanges, OnInit {
}
}

onPinch(event: any) {
onPinch(event: HammerInput) {
if (this.moveStart!.active) {
if (event.stopPropagation) {
event.stopPropagation();
}
if (event.preventDefault) {
event.preventDefault();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { ImageTransform } from './image-transform.interface';

export type Position = 'left' | 'topleft' | 'top' | 'topright' | 'right' | 'bottomright' | 'bottom' | 'bottomleft' | 'center';

export interface MoveStart {
active: boolean;
type: MoveTypes | null;
position: string | null;
position: Position | null;
transform?: ImageTransform;
x1: number;
y1: number;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { ElementRef, Injectable } from '@angular/core';
import { CropperPosition, Dimensions, MoveStart } from '../interfaces';
import { CropperSettings } from '../interfaces/cropper.settings';
import {BasicEvent} from "../interfaces/basic-event.interface";
import { HammerInput } from "../utils/hammer.utils";

@Injectable({ providedIn: 'root' })
export class CropperPositionService {
Expand Down Expand Up @@ -51,7 +52,7 @@ export class CropperPositionService {
cropperPosition.y2 = moveStart.y2 + diffY;
}

resize(event: Event | BasicEvent, moveStart: MoveStart, cropperPosition: CropperPosition, maxSize: Dimensions, settings: CropperSettings): void {
resize(event: Event | BasicEvent | HammerInput, moveStart: MoveStart, cropperPosition: CropperPosition, maxSize: Dimensions, settings: CropperSettings): void {
const moveX = this.getClientX(event) - moveStart.clientX;
const moveY = this.getClientY(event) - moveStart.clientY;
switch (moveStart.position) {
Expand Down Expand Up @@ -96,7 +97,7 @@ export class CropperPositionService {
cropperPosition.y1 + settings.cropperScaledMinHeight);
break;
case 'center':
const scale = (event as any).scale;
const scale = 'scale' in event ? event.scale : 1;
const newWidth = Math.min(
Math.max(settings.cropperScaledMinWidth, (Math.abs(moveStart.x2 - moveStart.x1)) * scale),
settings.cropperScaledMaxWidth);
Expand Down Expand Up @@ -207,7 +208,7 @@ export class CropperPositionService {
}
}

getClientX(event: Event | BasicEvent | TouchEvent): number {
getClientX(event: Event | BasicEvent | TouchEvent | HammerInput): number {
if ('touches' in event && event.touches[0])
return event.touches[0].clientX;
else if ('clientX' in event) {
Expand All @@ -217,7 +218,7 @@ export class CropperPositionService {
return 0;
}

getClientY(event: Event | BasicEvent | TouchEvent): number {
getClientY(event: Event | BasicEvent | TouchEvent | HammerInput): number {
if ('touches' in event && event.touches[0])
return event.touches[0].clientY;
else if ('clientX' in event) {
Expand Down
140 changes: 136 additions & 4 deletions projects/ngx-image-cropper/src/lib/utils/hammer.utils.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,142 @@
export type HammerStatic = new(element: HTMLElement | SVGElement, options?: any) => HammerManager;

export declare class HammerInput {
constructor(manager: HammerManager, callback: Function);

destroy(): void;

handler(): void;

init(): void;

/** Name of the event. Like panstart. */
type: string;

/** Movement of the X axis. */
deltaX: number;

/** Movement of the Y axis. */
deltaY: number;

/** Total time in ms since the first input. */
deltaTime: number;

/** Distance moved. */
distance: number;

/** Angle moved. */
angle: number;

/** Velocity on the X axis, in px/ms. */
velocityX: number;

/** Velocity on the Y axis, in px/ms */
velocityY: number;

/** Highest velocityX/Y value. */
velocity: number;

overallVelocity: number;

overallVelocityX: number;

overallVelocityY: number;

/** Direction moved. Matches the DIRECTION constants. */
direction: number;

/** Direction moved from it's starting point. Matches the DIRECTION constants. */
offsetDirection: number;

/** Scaling that has been done when multi-touch. 1 on a single touch. */
scale: number;

/** Rotation that has been done when multi-touch. 0 on a single touch. */
rotation: number;

/** Source event object, type TouchEvent, MouseEvent or PointerEvent. */
srcEvent: TouchEvent | MouseEvent | PointerEvent;

/** Target that received the event. */
target: HTMLElement;

/** Primary pointer type, could be touch, mouse, pen or kinect. */
pointerType: string;

/** true when the first input. */
isFirst: boolean;

/** true when the final (last) input. */
isFinal: boolean;

/** Array with all pointers, including the ended pointers (touchend, mouseup). */
pointers: any[];

/** Array with all new/moved/lost pointers. */
changedPointers: any[];

/** Maximum number of pointers detected in the gesture */
maxPointers: number;

/** Timestamp of a gesture */
timeStamp: number;

/** Reference to the srcEvent.preventDefault() method. Only for experts! */
preventDefault: Function;
}

interface RecognizerOptions {
direction?: number | undefined;
enable?: boolean | ((recognizer: Recognizer, inputData: HammerInput) => boolean) | undefined;
event?: string | undefined;
interval?: number | undefined;
pointers?: number | undefined;
posThreshold?: number | undefined;
taps?: number | undefined;
threshold?: number | undefined;
time?: number | undefined;
velocity?: number | undefined;
}

interface Recognizer {
defaults: any;

canEmit(): boolean;

canRecognizeWith(otherRecognizer: Recognizer): boolean;

dropRecognizeWith(otherRecognizer: Recognizer | Recognizer[] | string): Recognizer;

dropRequireFailure(otherRecognizer: Recognizer | Recognizer[] | string): Recognizer;

emit(input: HammerInput): void;

getTouchAction(): any[];

hasRequireFailures(): boolean;

process(inputData: HammerInput): string;

recognize(inputData: HammerInput): void;

recognizeWith(otherRecognizer: Recognizer | Recognizer[] | string): Recognizer;

requireFailure(otherRecognizer: Recognizer | Recognizer[] | string): Recognizer;

reset(): void;

set(options?: RecognizerOptions): Recognizer;

tryEmit(input: HammerInput): void;
}

interface HammerListener {
(event: HammerInput): void;
}

/** @docs-private */
export interface HammerManager {
get(eventName: string): HammerManager;

set(options: any): HammerManager;
get(recogniser: string): Recognizer;

on(eventName: string, handler: (ev: any) => any): void;
on(events: string, handler: HammerListener): void;
}
5 changes: 3 additions & 2 deletions projects/ngx-image-cropper/src/lib/utils/keyboard.utils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {BasicEvent} from "../interfaces/basic-event.interface";
import {Position} from "../interfaces/move-start.interface";

export function getPositionForKey(key: string): string {
export function getPositionForKey(key: string): Position {
switch (key) {
case 'ArrowUp':
return 'top';
Expand All @@ -14,7 +15,7 @@ export function getPositionForKey(key: string): string {
}
}

export function getInvertedPositionForKey(key: string): string {
export function getInvertedPositionForKey(key: string): Position {
switch (key) {
case 'ArrowUp':
return 'bottom';
Expand Down

0 comments on commit 8f5da5e

Please sign in to comment.