@netless/forge-imagery-doc 0.1.2 → 0.1.3
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.
- package/changelog.md +4 -0
- package/dist/Container.d.ts +1 -1
- package/dist/Container.d.ts.map +1 -1
- package/dist/ContinuousContainer.d.ts +5 -5
- package/dist/ContinuousContainer.d.ts.map +1 -1
- package/dist/FooterView.d.ts +1 -1
- package/dist/FooterView.d.ts.map +1 -1
- package/dist/ImageryDoc.d.ts +18 -18
- package/dist/ImageryDoc.d.ts.map +1 -1
- package/dist/ImageryDocApplication.d.ts +3 -3
- package/dist/ImageryDocApplication.d.ts.map +1 -1
- package/dist/ImageryDocPermissions.d.ts +26 -25
- package/dist/ImageryDocPermissions.d.ts.map +1 -1
- package/dist/InfinityScroll.d.ts +1 -1
- package/dist/InfinityScroll.d.ts.map +1 -1
- package/dist/LazyImage.d.ts.map +1 -1
- package/dist/SingleContainer.d.ts +6 -6
- package/dist/SingleContainer.d.ts.map +1 -1
- package/dist/imagery-doc.esm.js +92 -51
- package/dist/imagery-doc.esm.js.map +2 -2
- package/dist/imagery-doc.js +92 -51
- package/dist/imagery-doc.js.map +2 -2
- package/dist/index.d.ts +4 -4
- package/package.json +5 -4
- package/src/Container.ts +6 -6
- package/src/ContinuousContainer.ts +135 -135
- package/src/FooterView.ts +121 -121
- package/src/ImageryDoc.ts +17 -17
- package/src/ImageryDocApplication.ts +212 -199
- package/src/ImageryDocPermissions.ts +95 -85
- package/src/InfinityScroll.ts +43 -42
- package/src/LazyImage.ts +55 -55
- package/src/SingleContainer.ts +236 -226
- package/src/icons.ts +3 -3
- package/src/index.ts +4 -4
|
@@ -1,157 +1,157 @@
|
|
|
1
|
-
import {LazyImage} from
|
|
2
|
-
import {InfinityScroll} from
|
|
3
|
-
import * as Y from
|
|
4
|
-
import {WhiteboardApplication} from
|
|
5
|
-
import type {ImageryDoc} from
|
|
6
|
-
import {Container, ContainerKeys} from
|
|
1
|
+
import { LazyImage } from './LazyImage';
|
|
2
|
+
import { InfinityScroll } from './InfinityScroll';
|
|
3
|
+
import * as Y from 'yjs';
|
|
4
|
+
import { WhiteboardApplication } from '@netless/forge-whiteboard';
|
|
5
|
+
import type { ImageryDoc } from './ImageryDoc';
|
|
6
|
+
import { Container, ContainerKeys } from './Container';
|
|
7
7
|
|
|
8
8
|
export class ContinuousContainer implements Container {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
9
|
+
public readonly view: HTMLDivElement;
|
|
10
|
+
private parentView: HTMLDivElement;
|
|
11
|
+
private resizeObserver!: ResizeObserver;
|
|
12
|
+
private images: LazyImage[] = [];
|
|
13
|
+
private scroll: InfinityScroll;
|
|
14
|
+
private map: Y.Map<any>;
|
|
15
|
+
private whiteboardApp: WhiteboardApplication;
|
|
16
|
+
private imageDoc: ImageryDoc;
|
|
17
|
+
private totalHeight: number = 0;
|
|
18
|
+
private localScale: number = 1;
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
20
|
+
private get translateY(): number {
|
|
21
|
+
return this.map.get(ContainerKeys.translateY);
|
|
22
|
+
}
|
|
23
|
+
private set translateY(value: number) {
|
|
24
|
+
this.map.set(ContainerKeys.translateY, value);
|
|
25
|
+
}
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}
|
|
34
|
-
return this.images.length - 1;
|
|
27
|
+
public get pageIndex(): number {
|
|
28
|
+
const step = 1 / this.images.length;
|
|
29
|
+
for (let i = 0; i < this.images.length; i++) {
|
|
30
|
+
if (this.translateY < step * i && Math.abs(this.translateY - step * i) >= 0.0001) {
|
|
31
|
+
return i - 1;
|
|
32
|
+
}
|
|
35
33
|
}
|
|
34
|
+
return this.images.length - 1;
|
|
35
|
+
}
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
37
|
+
public constructor(
|
|
38
|
+
map: Y.Map<any>,
|
|
39
|
+
whiteboardApp: WhiteboardApplication,
|
|
40
|
+
parentView: HTMLDivElement,
|
|
41
|
+
imageDoc: ImageryDoc,
|
|
42
|
+
) {
|
|
43
|
+
this.imageDoc = imageDoc;
|
|
44
|
+
this.parentView = parentView;
|
|
45
|
+
this.map = map;
|
|
46
|
+
this.scroll = new InfinityScroll(this.parentView);
|
|
47
|
+
this.whiteboardApp = whiteboardApp;
|
|
48
|
+
this.view = document.createElement('div');
|
|
49
|
+
this.view.style.width = '100%';
|
|
50
|
+
this.view.style.height = '100%';
|
|
51
|
+
this.view.style.position = 'absolute';
|
|
52
|
+
this.view.style.top = '0';
|
|
53
|
+
this.view.style.left = '0';
|
|
54
|
+
this.view.style.transformOrigin = '0, 0';
|
|
55
|
+
this.view.setAttribute('data-imagery-container', 'continuous');
|
|
56
56
|
|
|
57
|
-
|
|
58
|
-
|
|
57
|
+
this.resizeObserver = new ResizeObserver(this.handleResize);
|
|
58
|
+
this.resizeObserver.observe(this.view);
|
|
59
59
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
}
|
|
65
|
-
if (!this.map.has(ContainerKeys.translateX)) {
|
|
66
|
-
this.map.set(ContainerKeys.translateX, 0);
|
|
67
|
-
}
|
|
68
|
-
if (!this.map.has(ContainerKeys.translateY)) {
|
|
69
|
-
this.map.set(ContainerKeys.translateY, 0);
|
|
70
|
-
}
|
|
71
|
-
this.scroll.on("translate", (dx, dy) => {
|
|
72
|
-
this.handleTranslate(dx, dy);
|
|
73
|
-
});
|
|
60
|
+
this.whiteboardApp.updateInternalResizeObserverStatus(false);
|
|
61
|
+
this.map.observe(this.handleMapChange);
|
|
62
|
+
if (!this.map.has(ContainerKeys.scale)) {
|
|
63
|
+
this.map.set(ContainerKeys.scale, 1);
|
|
74
64
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
this.updateSyncedTransform();
|
|
78
|
-
this.totalHeight = this.images.reduce((prev, curr) => prev + curr.height, 0);
|
|
65
|
+
if (!this.map.has(ContainerKeys.translateX)) {
|
|
66
|
+
this.map.set(ContainerKeys.translateX, 0);
|
|
79
67
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
const dyNormalized = dy / this.totalHeight;
|
|
83
|
-
let nextTy = this.translateY + dyNormalized;
|
|
84
|
-
nextTy = Math.max(0, nextTy);
|
|
85
|
-
nextTy = Math.min(1, nextTy);
|
|
86
|
-
this.translateY = nextTy;
|
|
68
|
+
if (!this.map.has(ContainerKeys.translateY)) {
|
|
69
|
+
this.map.set(ContainerKeys.translateY, 0);
|
|
87
70
|
}
|
|
71
|
+
this.scroll.on('translate', (dx, dy) => {
|
|
72
|
+
this.handleTranslate(dx, dy);
|
|
73
|
+
});
|
|
74
|
+
}
|
|
88
75
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
}
|
|
94
|
-
};
|
|
76
|
+
public init() {
|
|
77
|
+
this.updateSyncedTransform();
|
|
78
|
+
this.totalHeight = this.images.reduce((prev, curr) => prev + curr.height, 0);
|
|
79
|
+
}
|
|
95
80
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
81
|
+
private handleTranslate(dx: number, dy: number) {
|
|
82
|
+
const dyNormalized = dy / this.totalHeight;
|
|
83
|
+
let nextTy = this.translateY + dyNormalized;
|
|
84
|
+
nextTy = Math.max(0, nextTy);
|
|
85
|
+
nextTy = Math.min(1, nextTy);
|
|
86
|
+
this.translateY = nextTy;
|
|
87
|
+
}
|
|
101
88
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
89
|
+
private handleMapChange = (event: Y.YMapEvent<any>) => {
|
|
90
|
+
if (event.keysChanged.has(ContainerKeys.translateY)
|
|
91
|
+
) {
|
|
92
|
+
this.updateSyncedTransform();
|
|
105
93
|
}
|
|
94
|
+
};
|
|
106
95
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
const target = this.images[index];
|
|
113
|
-
if (target) {
|
|
114
|
-
await target.prepare();
|
|
115
|
-
}
|
|
116
|
-
this.imageDoc.emit("renderEnd", index);
|
|
117
|
-
for (let i = index - 3; i <= index + 3; i++) {
|
|
118
|
-
const img = this.images[i];
|
|
119
|
-
if (img) {
|
|
120
|
-
img.prepare();
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
}
|
|
96
|
+
public goto(index: number) {
|
|
97
|
+
let nextIndex = Math.max(0, index);
|
|
98
|
+
nextIndex = Math.min(this.images.length - 1, nextIndex);
|
|
99
|
+
this.translateY = nextIndex / this.images.length;
|
|
100
|
+
}
|
|
124
101
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
let scale = bound.width / image.width;
|
|
130
|
-
image.scale(scale);
|
|
131
|
-
scaledHeight += image.height * scale;
|
|
132
|
-
}
|
|
133
|
-
this.localScale = scaledHeight / this.totalHeight;
|
|
134
|
-
this.whiteboardApp.updateOptionSize(bound.width, bound.height);
|
|
135
|
-
this.whiteboardApp.adjustByOutFrame(bound.width, bound.height);
|
|
136
|
-
this.updateSyncedTransform();
|
|
137
|
-
}
|
|
102
|
+
public append(image: LazyImage) {
|
|
103
|
+
this.images.push(image);
|
|
104
|
+
this.view.appendChild(image.view);
|
|
105
|
+
}
|
|
138
106
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
this.whiteboardApp.emitter.translateCamera(0, -ty);
|
|
148
|
-
this.whiteboardApp.emitter.scaleCamera(this.localScale, "top-left");
|
|
149
|
-
console.log("localScale: ", this.localScale, this.translateY);
|
|
150
|
-
this.handleGoto(this.pageIndex);
|
|
107
|
+
private async handleGoto(index: number): Promise<void> {
|
|
108
|
+
if (index < 0 || index >= this.images.length) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
this.imageDoc.emit('renderStart', index);
|
|
112
|
+
const target = this.images[index];
|
|
113
|
+
if (target) {
|
|
114
|
+
await target.prepare();
|
|
151
115
|
}
|
|
116
|
+
this.imageDoc.emit('renderEnd', index);
|
|
117
|
+
for (let i = index - 3; i <= index + 3; i++) {
|
|
118
|
+
const img = this.images[i];
|
|
119
|
+
if (img) {
|
|
120
|
+
img.prepare();
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
152
124
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
125
|
+
private handleResize = () => {
|
|
126
|
+
const bound = this.view.getBoundingClientRect();
|
|
127
|
+
let scaledHeight = 0;
|
|
128
|
+
for (const image of this.images) {
|
|
129
|
+
const scale = bound.width / image.width;
|
|
130
|
+
image.scale(scale);
|
|
131
|
+
scaledHeight += image.height * scale;
|
|
156
132
|
}
|
|
133
|
+
this.localScale = scaledHeight / this.totalHeight;
|
|
134
|
+
this.whiteboardApp.updateOptionSize(bound.width, bound.height);
|
|
135
|
+
this.whiteboardApp.adjustByOutFrame(bound.width, bound.height);
|
|
136
|
+
this.updateSyncedTransform();
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
private updateSyncedTransform = () => {
|
|
140
|
+
const bounds = this.view.getBoundingClientRect();
|
|
141
|
+
const maxTy = this.totalHeight * this.localScale - bounds.height;
|
|
142
|
+
let ty = this.translateY * this.totalHeight * this.localScale;
|
|
143
|
+
ty = Math.min(ty, maxTy);
|
|
144
|
+
ty = Math.max(ty, 0);
|
|
145
|
+
this.view.style.transform = `translate(0, ${-ty}px)`;
|
|
146
|
+
this.whiteboardApp.emitter.resetCamera();
|
|
147
|
+
this.whiteboardApp.emitter.translateCamera(0, -ty);
|
|
148
|
+
this.whiteboardApp.emitter.scaleCamera(this.localScale, 'top-left');
|
|
149
|
+
console.log('localScale: ', this.localScale, this.translateY);
|
|
150
|
+
this.handleGoto(this.pageIndex);
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
public dispose() {
|
|
154
|
+
this.resizeObserver.disconnect();
|
|
155
|
+
this.scroll.dispose();
|
|
156
|
+
}
|
|
157
157
|
}
|
package/src/FooterView.ts
CHANGED
|
@@ -1,139 +1,139 @@
|
|
|
1
|
-
import { Icons } from
|
|
2
|
-
import {ImageryDoc} from
|
|
1
|
+
import { Icons } from './icons';
|
|
2
|
+
import { ImageryDoc } from './ImageryDoc';
|
|
3
3
|
|
|
4
|
-
const EM_COLOR =
|
|
4
|
+
const EM_COLOR = '#8C8C8C';
|
|
5
5
|
|
|
6
6
|
export class FooterView {
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
public readonly root: HTMLDivElement;
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
private prevPage: HTMLDivElement;
|
|
11
|
+
private nextPage: HTMLDivElement;
|
|
12
|
+
private sideBarToggle: HTMLDivElement;
|
|
13
|
+
private sideBarContainer: HTMLDivElement = document.createElement('div');
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
private isSlideBarVisible: boolean = false;
|
|
16
|
+
private imageryDoc: ImageryDoc;
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
18
|
+
public constructor(imageryDoc: ImageryDoc) {
|
|
19
|
+
this.imageryDoc = imageryDoc;
|
|
20
|
+
this.root = document.createElement('div');
|
|
21
|
+
this.root.style.height = '24px';
|
|
22
|
+
this.root.style.zIndex = '2';
|
|
23
|
+
this.root.style.display = 'flex';
|
|
24
|
+
this.root.style.alignItems = 'center';
|
|
25
|
+
this.root.style.backgroundColor = '#fff';
|
|
26
|
+
this.root.style.borderTop = '1px solid #f0f0f0';
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
28
|
+
this.prevPage = this.createIcon(Icons.chevronLeft(EM_COLOR), '18px', () => {
|
|
29
|
+
this.imageryDoc.goto(this.imageryDoc.pageIndex - 1);
|
|
30
|
+
});
|
|
31
|
+
this.nextPage = this.createIcon(Icons.chevronRight(EM_COLOR), '18px', () => {
|
|
32
|
+
this.imageryDoc.goto(this.imageryDoc.pageIndex + 1);
|
|
33
|
+
});
|
|
34
|
+
this.sideBarToggle = this.createIcon(Icons.sideBar(EM_COLOR), '20px', () => {
|
|
35
|
+
this.createSideBar();
|
|
36
|
+
this.isSlideBarVisible = !this.isSlideBarVisible;
|
|
37
|
+
if (this.isSlideBarVisible) {
|
|
38
|
+
this.sideBarContainer.style.display = 'block';
|
|
39
|
+
} else {
|
|
40
|
+
this.sideBarContainer.style.display = 'none';
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
this.root.appendChild(this.sideBarToggle);
|
|
44
|
+
this.root.appendChild(this.createSpacer());
|
|
45
|
+
this.root.appendChild(this.prevPage);
|
|
46
|
+
this.root.appendChild(this.nextPage);
|
|
47
|
+
this.root.appendChild(this.createSpacer());
|
|
48
|
+
}
|
|
49
49
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
}
|
|
50
|
+
public prevPageState(enable: boolean): void {
|
|
51
|
+
if (enable) {
|
|
52
|
+
this.prevPage.style.pointerEvents = 'all';
|
|
53
|
+
this.prevPage.style.opacity = '1';
|
|
54
|
+
} else {
|
|
55
|
+
this.prevPage.style.pointerEvents = 'none';
|
|
56
|
+
this.prevPage.style.opacity = '0.5';
|
|
58
57
|
}
|
|
58
|
+
}
|
|
59
59
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
}
|
|
60
|
+
public nextPageState(enable: boolean): void {
|
|
61
|
+
if (enable) {
|
|
62
|
+
this.nextPage.style.pointerEvents = 'all';
|
|
63
|
+
this.nextPage.style.opacity = '1';
|
|
64
|
+
} else {
|
|
65
|
+
this.nextPage.style.pointerEvents = 'none';
|
|
66
|
+
this.nextPage.style.opacity = '0.5';
|
|
68
67
|
}
|
|
68
|
+
}
|
|
69
69
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
70
|
+
private createSpacer(): HTMLDivElement {
|
|
71
|
+
const div = document.createElement('div');
|
|
72
|
+
div.style.flex = '1 1 auto';
|
|
73
|
+
return div;
|
|
74
|
+
}
|
|
75
75
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
76
|
+
private createIcon(svgContent: string, size: string, action: () => void): HTMLDivElement {
|
|
77
|
+
const icon = document.createElement('div');
|
|
78
|
+
icon.style.width = size;
|
|
79
|
+
icon.style.height = size;
|
|
80
|
+
icon.style.borderRadius = '2px';
|
|
81
|
+
icon.style.margin = '6px';
|
|
82
|
+
icon.innerHTML = svgContent;
|
|
83
|
+
icon.addEventListener('click', () => {
|
|
84
|
+
action();
|
|
85
|
+
});
|
|
86
|
+
icon.addEventListener('mouseover', () => {
|
|
87
|
+
icon.style.backgroundColor = '#f0f0f0';
|
|
88
|
+
});
|
|
89
|
+
icon.addEventListener('mouseout', () => {
|
|
90
|
+
icon.style.backgroundColor = 'transparent';
|
|
91
|
+
});
|
|
92
|
+
return icon;
|
|
93
|
+
}
|
|
94
94
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
}
|
|
99
|
-
if (this.root.contains(this.sideBarContainer)) {
|
|
100
|
-
return;
|
|
101
|
-
}
|
|
102
|
-
this.sideBarContainer.style.width = "24%";
|
|
103
|
-
this.sideBarContainer.style.maxWidth = "180px";
|
|
104
|
-
this.sideBarContainer.style.height = "calc(100% - 24px)";
|
|
105
|
-
this.sideBarContainer.style.position = "absolute";
|
|
106
|
-
this.sideBarContainer.style.bottom = "24px";
|
|
107
|
-
this.sideBarContainer.style.left = "0";
|
|
108
|
-
this.sideBarContainer.style.fontSize = "0px";
|
|
109
|
-
this.sideBarContainer.style.overflow = "auto";
|
|
110
|
-
this.sideBarContainer.style.backgroundColor = "#EFEFEF";
|
|
111
|
-
this.root.appendChild(this.sideBarContainer);
|
|
112
|
-
for (let i = 0, l = this.imageryDoc.pageCount; i < l; i++) {
|
|
113
|
-
const reviewPage = document.createElement("div");
|
|
114
|
-
reviewPage.style.width = "100%";
|
|
115
|
-
reviewPage.style.marginTop = "12px";
|
|
116
|
-
const reviewIndex = document.createElement("div");
|
|
117
|
-
reviewIndex.style.cssText = "font-size:12px;width:100%;text-align:center;height:24px;line-height:24px;color:#585858";
|
|
118
|
-
reviewIndex.textContent = `${i + 1}`;
|
|
119
|
-
const reviewImg = document.createElement("img");
|
|
120
|
-
reviewImg.setAttribute("data-doc-index", `${i}`);
|
|
121
|
-
reviewImg.style.cssText = "width:80%;margin:0 10%;box-shadow:1px 1px 5px #9e9e9e";
|
|
122
|
-
this.imageryDoc.imgContent(i).then((base64Data) => {
|
|
123
|
-
reviewImg.src = base64Data;
|
|
124
|
-
});
|
|
125
|
-
reviewPage.appendChild(reviewImg);
|
|
126
|
-
reviewPage.appendChild(reviewIndex);
|
|
127
|
-
this.sideBarContainer.appendChild(reviewPage);
|
|
128
|
-
}
|
|
129
|
-
this.sideBarContainer.addEventListener("click", this.handleSideBarClick);
|
|
95
|
+
private createSideBar() {
|
|
96
|
+
if (this.imageryDoc.pageCount === 0) {
|
|
97
|
+
return;
|
|
130
98
|
}
|
|
99
|
+
if (this.root.contains(this.sideBarContainer)) {
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
this.sideBarContainer.style.width = '24%';
|
|
103
|
+
this.sideBarContainer.style.maxWidth = '180px';
|
|
104
|
+
this.sideBarContainer.style.height = 'calc(100% - 24px)';
|
|
105
|
+
this.sideBarContainer.style.position = 'absolute';
|
|
106
|
+
this.sideBarContainer.style.bottom = '24px';
|
|
107
|
+
this.sideBarContainer.style.left = '0';
|
|
108
|
+
this.sideBarContainer.style.fontSize = '0px';
|
|
109
|
+
this.sideBarContainer.style.overflow = 'auto';
|
|
110
|
+
this.sideBarContainer.style.backgroundColor = '#EFEFEF';
|
|
111
|
+
this.root.appendChild(this.sideBarContainer);
|
|
112
|
+
for (let i = 0, l = this.imageryDoc.pageCount; i < l; i++) {
|
|
113
|
+
const reviewPage = document.createElement('div');
|
|
114
|
+
reviewPage.style.width = '100%';
|
|
115
|
+
reviewPage.style.marginTop = '12px';
|
|
116
|
+
const reviewIndex = document.createElement('div');
|
|
117
|
+
reviewIndex.style.cssText = 'font-size:12px;width:100%;text-align:center;height:24px;line-height:24px;color:#585858';
|
|
118
|
+
reviewIndex.textContent = `${i + 1}`;
|
|
119
|
+
const reviewImg = document.createElement('img');
|
|
120
|
+
reviewImg.setAttribute('data-doc-index', `${i}`);
|
|
121
|
+
reviewImg.style.cssText = 'width:80%;margin:0 10%;box-shadow:1px 1px 5px #9e9e9e';
|
|
122
|
+
this.imageryDoc.imgContent(i).then((base64Data) => {
|
|
123
|
+
reviewImg.src = base64Data;
|
|
124
|
+
});
|
|
125
|
+
reviewPage.appendChild(reviewImg);
|
|
126
|
+
reviewPage.appendChild(reviewIndex);
|
|
127
|
+
this.sideBarContainer.appendChild(reviewPage);
|
|
128
|
+
}
|
|
129
|
+
this.sideBarContainer.addEventListener('click', this.handleSideBarClick);
|
|
130
|
+
}
|
|
131
131
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
132
|
+
private handleSideBarClick = (evt: MouseEvent) => {
|
|
133
|
+
const target = evt.target as HTMLElement;
|
|
134
|
+
const targetIndex = target.getAttribute('data-doc-index');
|
|
135
|
+
if (targetIndex) {
|
|
136
|
+
this.imageryDoc.goto(parseInt(targetIndex, 10));
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
139
|
}
|
package/src/ImageryDoc.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import EventEmitter from
|
|
2
|
-
import {ApplicationInstanceType} from
|
|
1
|
+
import EventEmitter from 'eventemitter3';
|
|
2
|
+
import { ApplicationInstanceType } from '@netless/forge-room';
|
|
3
3
|
|
|
4
|
-
import {ImageryDocPermissionFlag, ImageryDocPermissions} from
|
|
4
|
+
import { ImageryDocPermissionFlag, ImageryDocPermissions } from './ImageryDocPermissions';
|
|
5
5
|
|
|
6
6
|
export interface ImageryDocEvents {
|
|
7
7
|
/**
|
|
@@ -28,37 +28,37 @@ export interface ImageryDocEvents {
|
|
|
28
28
|
|
|
29
29
|
export class ImageryDoc extends EventEmitter<ImageryDocEvents> implements ApplicationInstanceType {
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
public readonly view!: HTMLDivElement;
|
|
32
|
+
/**
|
|
33
33
|
* 底部操作栏
|
|
34
34
|
*/
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
public readonly footView!: HTMLDivElement;
|
|
36
|
+
public readonly permissions!: ImageryDocPermissions;
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
/**
|
|
39
39
|
* 当前页面索引, 从 0 开始
|
|
40
40
|
*/
|
|
41
|
-
|
|
42
|
-
|
|
41
|
+
public readonly pageIndex!: number;
|
|
42
|
+
/**
|
|
43
43
|
* 总页数
|
|
44
44
|
*/
|
|
45
|
-
|
|
45
|
+
public readonly pageCount!: number;
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
/**
|
|
48
48
|
* 切换到参数指定页面, index 从 0 开始
|
|
49
49
|
* @param {number} index 页面索引
|
|
50
50
|
*/
|
|
51
|
-
|
|
51
|
+
public goto!: (index: number) => void;
|
|
52
52
|
|
|
53
|
-
|
|
53
|
+
/**
|
|
54
54
|
* 获取图片内容, base64 编码
|
|
55
55
|
* @param {number} index 页面索引
|
|
56
56
|
*/
|
|
57
|
-
|
|
57
|
+
public imgContent!: (index: number) => Promise<string>;
|
|
58
58
|
|
|
59
|
-
|
|
59
|
+
/**
|
|
60
60
|
* 获取图片尺寸
|
|
61
61
|
* @param {number} index 页面索引
|
|
62
62
|
*/
|
|
63
|
-
|
|
63
|
+
public imgSize!: (index: number) => {width: number, height: number};
|
|
64
64
|
}
|