File size: 3,339 Bytes
c3fc836
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
const clamp = (num: number, min: number, max: number) => Math.min(Math.max(num, min), max)

export default class WindowViewer {
    scale: number;
    offsetX: number;
    offsetY: number;
    canvasWidth: number;
    canvasHeight: number;
    imageWidth: number;
    imageHeight: number;
    imageRotatedWidth: number;
    imageRotatedHeight: number;
    isDragging: boolean;
    startDragX: number;
    startDragY: number;
    orientation: number;
    renderCallBack: () => void;

    constructor(renderCallBack: () => void) {
        this.renderCallBack = renderCallBack;
        this.scale = 1.0;
        this.offsetX = 0;
        this.offsetY = 0;
        this.canvasWidth = 0;
        this.canvasHeight = 0;
        this.imageWidth = 0;
        this.imageHeight = 0;
        this.imageRotatedWidth = 0;
        this.imageRotatedHeight = 0;
        this.isDragging = false;
        this.startDragX = 0;
        this.startDragY = 0;
        this.orientation = 0;
    }
    startDrag(event: MouseEvent): void {
        this.isDragging = true;
        this.startDragX = event.clientX - this.offsetX;
        this.startDragY = event.clientY - this.offsetY;

        document.addEventListener("pointermove", this.handleDrag);
        document.addEventListener("pointerup", this.stopDrag);
    }

    stopDrag = (): void => {
        this.isDragging = false;
        document.removeEventListener("pointermove", this.handleDrag);
        document.removeEventListener("pointerup", this.stopDrag);
    };

    handleDrag = (event: MouseEvent): void => {
        if (this.isDragging) {

            let deltaX = event.clientX - this.startDragX - this.offsetX;
            let deltaY = event.clientY - this.startDragY - this.offsetY;

            if (this.imageWidth * this.scale > this.canvasWidth){
                deltaX = clamp(deltaX, this.canvasWidth-this.offsetX-(this.imageWidth*this.scale), -this.offsetX);
            } else {
                deltaX = clamp(deltaX, -this.offsetX, this.canvasWidth-this.offsetX-(this.imageWidth*this.scale));
            }

            if (this.imageHeight * this.scale > this.canvasHeight){
                deltaY = clamp(deltaY, this.canvasHeight-this.offsetY-(this.imageHeight*this.scale), -this.offsetY);
            } else {
                deltaY = clamp(deltaY, -this.offsetY, this.canvasHeight-this.offsetY-(this.imageHeight*this.scale));
            }

            this.offsetX += deltaX;
            this.offsetY += deltaY;
            this.renderCallBack();
        }
    };

    setRotatedImage(image: HTMLImageElement | null): void {
        if (image !== null) {
            if (this.orientation == 0 || this.orientation == 2) {
                this.imageRotatedWidth = image.width;
                this.imageRotatedHeight = image.height;
            } else { // (this.orientation == 1 || this.orientation == 3)
                this.imageRotatedWidth = image.height;
                this.imageRotatedHeight = image.width;
            }
        }
    }

    resize(width: number, height: number, offsetX: number=0, offsetY: number=0): void {
        if (this.canvasWidth == width && this.canvasHeight == height) return;
        this.canvasWidth = width;
        this.canvasHeight = height;

        this.scale = 1.0;
        this.offsetX = offsetX;
        this.offsetY = offsetY;
    }
}