@netless/forge-whiteboard 0.1.7 → 0.1.9
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/README.md +63 -3
- package/changelog.md +28 -0
- package/dist/Camera.d.ts +14 -2
- package/dist/Camera.d.ts.map +1 -1
- package/dist/Whiteboard.d.ts +31 -0
- package/dist/Whiteboard.d.ts.map +1 -1
- package/dist/WhiteboardApplication.d.ts +6 -0
- package/dist/WhiteboardApplication.d.ts.map +1 -1
- package/dist/whiteboard.esm.js +196 -17
- package/dist/whiteboard.esm.js.map +2 -2
- package/dist/whiteboard.js +196 -17
- package/dist/whiteboard.js.map +2 -2
- package/package.json +3 -2
package/dist/whiteboard.js
CHANGED
|
@@ -28838,6 +28838,14 @@ var Camera = class extends import_eventemitter38.default {
|
|
|
28838
28838
|
hasPermission;
|
|
28839
28839
|
gesture;
|
|
28840
28840
|
inherentScale = 1;
|
|
28841
|
+
maxScale;
|
|
28842
|
+
initSize;
|
|
28843
|
+
bound;
|
|
28844
|
+
boundTiemoutId;
|
|
28845
|
+
enableByMouse = true;
|
|
28846
|
+
enableByTouch = true;
|
|
28847
|
+
boundaryColor = "#F44336";
|
|
28848
|
+
enableBoundaryHighlight = true;
|
|
28841
28849
|
get inherentMatrix() {
|
|
28842
28850
|
const inherentMatrix = new this.scope.Matrix();
|
|
28843
28851
|
inherentMatrix.scale(this.inherentScale, [0, 0]);
|
|
@@ -28847,8 +28855,12 @@ var Camera = class extends import_eventemitter38.default {
|
|
|
28847
28855
|
const view = this.scope.project.view;
|
|
28848
28856
|
return 1 / view.matrix.scaling.x;
|
|
28849
28857
|
}
|
|
28850
|
-
constructor(dom, userManager, scope, whiteboardAttrsMap, hasPermission, requestUserMap, paperSize, domSize) {
|
|
28858
|
+
constructor(initSize, maxScale, dom, userManager, scope, whiteboardAttrsMap, hasPermission, requestUserMap, paperSize, domSize) {
|
|
28851
28859
|
super();
|
|
28860
|
+
this.maxScale = maxScale;
|
|
28861
|
+
this.bound = window.document.createElement("div");
|
|
28862
|
+
this.bound.style.cssText = `transition: box-shadow 100ms;pointer-events:none;z-index:99;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);`;
|
|
28863
|
+
this.initSize = initSize;
|
|
28852
28864
|
this.hasPermission = hasPermission;
|
|
28853
28865
|
this.paperSize = paperSize;
|
|
28854
28866
|
this.domSize = domSize;
|
|
@@ -28857,6 +28869,7 @@ var Camera = class extends import_eventemitter38.default {
|
|
|
28857
28869
|
this.requestUserMap = requestUserMap;
|
|
28858
28870
|
this.userManager = userManager;
|
|
28859
28871
|
this.dom = dom;
|
|
28872
|
+
this.dom.appendChild(this.bound);
|
|
28860
28873
|
this.dom.addEventListener("wheel", this.handleWheel, { passive: false, capture: true });
|
|
28861
28874
|
this.dom.addEventListener("touchstart", (e) => {
|
|
28862
28875
|
e.preventDefault();
|
|
@@ -28877,17 +28890,32 @@ var Camera = class extends import_eventemitter38.default {
|
|
|
28877
28890
|
this.whiteboardAttrsMap.observe(this.handleMainCameraChange);
|
|
28878
28891
|
this.gesture = new Gesture(this.dom, this.scope);
|
|
28879
28892
|
this.gesture.on("offset", (x, y) => {
|
|
28893
|
+
if (!this.enableByTouch) {
|
|
28894
|
+
return;
|
|
28895
|
+
}
|
|
28880
28896
|
const matrix = new this.scope.Matrix();
|
|
28881
28897
|
matrix.translate({ x: x * this.translateScale, y: y * this.translateScale });
|
|
28882
|
-
this.
|
|
28898
|
+
this.updateViewMatrix(matrix);
|
|
28883
28899
|
});
|
|
28884
28900
|
this.gesture.on("scale", (scale, center) => {
|
|
28901
|
+
if (!this.enableByTouch) {
|
|
28902
|
+
return;
|
|
28903
|
+
}
|
|
28885
28904
|
const matrix = new this.scope.Matrix();
|
|
28886
28905
|
const paperPoint = this.scope.project.view.viewToProject(center);
|
|
28887
28906
|
matrix.scale(scale, paperPoint);
|
|
28888
|
-
this.
|
|
28907
|
+
this.updateViewMatrix(matrix);
|
|
28889
28908
|
});
|
|
28890
28909
|
}
|
|
28910
|
+
highlightBound() {
|
|
28911
|
+
if (this.enableBoundaryHighlight) {
|
|
28912
|
+
this.bound.style.boxShadow = `inset 0px 0px 6px 2px ${this.boundaryColor}`;
|
|
28913
|
+
window.clearTimeout(this.boundTiemoutId);
|
|
28914
|
+
this.boundTiemoutId = window.setTimeout(() => {
|
|
28915
|
+
this.bound.style.boxShadow = `none`;
|
|
28916
|
+
}, 100);
|
|
28917
|
+
}
|
|
28918
|
+
}
|
|
28891
28919
|
updateInherentScale(scale) {
|
|
28892
28920
|
this.inherentScale = scale;
|
|
28893
28921
|
}
|
|
@@ -28904,6 +28932,9 @@ var Camera = class extends import_eventemitter38.default {
|
|
|
28904
28932
|
return new this.scope.Matrix(matrixValue);
|
|
28905
28933
|
}
|
|
28906
28934
|
triggerZoom() {
|
|
28935
|
+
const [width, height] = this.domSize();
|
|
28936
|
+
this.bound.style.width = `${width}px`;
|
|
28937
|
+
this.bound.style.height = `${height}px`;
|
|
28907
28938
|
this.emit("zoom", this.inherentMatrix.appended(this.getActiveMatrix()));
|
|
28908
28939
|
}
|
|
28909
28940
|
resetViewMatrixToFlow(userId) {
|
|
@@ -28982,29 +29013,89 @@ var Camera = class extends import_eventemitter38.default {
|
|
|
28982
29013
|
}
|
|
28983
29014
|
}
|
|
28984
29015
|
};
|
|
28985
|
-
|
|
29016
|
+
validNextMatrix(next) {
|
|
29017
|
+
let shouldHighlightBound = false;
|
|
29018
|
+
const maxTranslate = (this.maxScale - 1) / 2;
|
|
29019
|
+
const maxScale = maxTranslate * 2 + 1;
|
|
29020
|
+
const minScale = 1 / maxScale;
|
|
29021
|
+
if (next.a > maxScale) {
|
|
29022
|
+
const tx = next.tx / next.a;
|
|
29023
|
+
next.a = maxScale;
|
|
29024
|
+
next.tx = tx * maxScale;
|
|
29025
|
+
shouldHighlightBound = true;
|
|
29026
|
+
}
|
|
29027
|
+
if (next.a < minScale) {
|
|
29028
|
+
const tx = next.tx / next.a;
|
|
29029
|
+
next.a = minScale;
|
|
29030
|
+
next.tx = tx * minScale;
|
|
29031
|
+
shouldHighlightBound = true;
|
|
29032
|
+
}
|
|
29033
|
+
if (next.d > maxScale) {
|
|
29034
|
+
const ty = next.ty / next.d;
|
|
29035
|
+
next.d = maxScale;
|
|
29036
|
+
next.ty = ty * maxScale;
|
|
29037
|
+
shouldHighlightBound = true;
|
|
29038
|
+
}
|
|
29039
|
+
if (next.d < minScale) {
|
|
29040
|
+
const ty = next.ty / next.d;
|
|
29041
|
+
next.d = minScale;
|
|
29042
|
+
next.ty = ty * minScale;
|
|
29043
|
+
shouldHighlightBound = true;
|
|
29044
|
+
}
|
|
29045
|
+
const maxTranslateX = this.initSize.width * maxTranslate;
|
|
29046
|
+
if (next.tx / next.a > maxTranslateX) {
|
|
29047
|
+
next.tx = maxTranslateX * next.a;
|
|
29048
|
+
shouldHighlightBound = true;
|
|
29049
|
+
}
|
|
29050
|
+
const minTx = (this.initSize.width * (maxTranslate + 1) - this.scope.project.view.bounds.width) * -next.a;
|
|
29051
|
+
if (next.tx < minTx) {
|
|
29052
|
+
next.tx = minTx;
|
|
29053
|
+
shouldHighlightBound = true;
|
|
29054
|
+
}
|
|
29055
|
+
const maxTranslateY = this.initSize.height * maxTranslate;
|
|
29056
|
+
if (next.ty / next.d > maxTranslateY) {
|
|
29057
|
+
next.ty = maxTranslateY * next.d;
|
|
29058
|
+
shouldHighlightBound = true;
|
|
29059
|
+
}
|
|
29060
|
+
const minTy = (this.initSize.height * (maxTranslate + 1) - this.scope.project.view.bounds.height) * -next.d;
|
|
29061
|
+
if (next.ty < minTy) {
|
|
29062
|
+
next.ty = minTy;
|
|
29063
|
+
shouldHighlightBound = true;
|
|
29064
|
+
}
|
|
29065
|
+
if (shouldHighlightBound) {
|
|
29066
|
+
this.highlightBound();
|
|
29067
|
+
}
|
|
29068
|
+
return next;
|
|
29069
|
+
}
|
|
29070
|
+
updateViewMatrix(matrix, append = true) {
|
|
28986
29071
|
const userMap = this.requestUserMap(this.userManager.selfId);
|
|
28987
29072
|
const cameraMode = userMap.get(WhiteboardKeys.cameraMode);
|
|
28988
|
-
|
|
29073
|
+
let next = matrix;
|
|
29074
|
+
if (append) {
|
|
28989
29075
|
const currentMatrixValue = userMap.get(WhiteboardKeys.viewMatrix);
|
|
28990
29076
|
const current = new this.scope.Matrix(currentMatrixValue);
|
|
28991
|
-
|
|
28992
|
-
|
|
28993
|
-
|
|
29077
|
+
next = current.appended(matrix);
|
|
29078
|
+
}
|
|
29079
|
+
if (this.maxScale >= 1) {
|
|
29080
|
+
next = this.validNextMatrix(next);
|
|
29081
|
+
} else {
|
|
29082
|
+
if (!(next.scaling.x <= 3 && next.scaling.x >= 0.2) && append) {
|
|
29083
|
+
return;
|
|
28994
29084
|
}
|
|
28995
29085
|
}
|
|
29086
|
+
if (cameraMode === "free" || cameraMode === "main") {
|
|
29087
|
+
userMap.set(WhiteboardKeys.viewMatrix, [next.a, next.b, next.c, next.d, next.tx, next.ty]);
|
|
29088
|
+
}
|
|
28996
29089
|
if (cameraMode === "main") {
|
|
28997
29090
|
if (this.hasPermission(32 /* mainView */)) {
|
|
28998
|
-
|
|
28999
|
-
const current = new this.scope.Matrix(currentMatrixValue);
|
|
29000
|
-
const next = current.appended(matrix);
|
|
29001
|
-
if (next.scaling.x <= 3 && next.scaling.x >= 0.3) {
|
|
29002
|
-
this.whiteboardAttrsMap.set(WhiteboardKeys.viewMatrix, [next.a, next.b, next.c, next.d, next.tx, next.ty]);
|
|
29003
|
-
}
|
|
29091
|
+
this.whiteboardAttrsMap.set(WhiteboardKeys.viewMatrix, [next.a, next.b, next.c, next.d, next.tx, next.ty]);
|
|
29004
29092
|
}
|
|
29005
29093
|
}
|
|
29006
29094
|
}
|
|
29007
29095
|
handleWheel = (evt) => {
|
|
29096
|
+
if (!this.enableByMouse) {
|
|
29097
|
+
return;
|
|
29098
|
+
}
|
|
29008
29099
|
evt.preventDefault();
|
|
29009
29100
|
evt.stopImmediatePropagation();
|
|
29010
29101
|
evt.stopPropagation();
|
|
@@ -29028,22 +29119,33 @@ var Camera = class extends import_eventemitter38.default {
|
|
|
29028
29119
|
} else {
|
|
29029
29120
|
scale = 1 + Math.abs(deltaY / wheelDelta);
|
|
29030
29121
|
}
|
|
29122
|
+
scale = Math.max(0.9, scale);
|
|
29123
|
+
scale = Math.min(1.1, scale);
|
|
29031
29124
|
matrix.scale(scale, paperPoint);
|
|
29032
|
-
this.
|
|
29125
|
+
this.updateViewMatrix(matrix);
|
|
29033
29126
|
} else {
|
|
29034
29127
|
const deltaX = this.lastDelta.x + evt.deltaX;
|
|
29035
29128
|
const deltaY = this.lastDelta.y + evt.deltaY;
|
|
29036
29129
|
const matrix = new this.scope.Matrix();
|
|
29037
29130
|
matrix.translate({ x: -deltaX * window.devicePixelRatio, y: -deltaY * window.devicePixelRatio });
|
|
29038
|
-
this.
|
|
29131
|
+
this.updateViewMatrix(matrix);
|
|
29039
29132
|
}
|
|
29040
29133
|
this.lastTriggerTime = Date.now();
|
|
29041
29134
|
this.lastDelta = { x: 0, y: 0 };
|
|
29042
29135
|
};
|
|
29136
|
+
scale(value) {
|
|
29137
|
+
const matrix = new this.scope.Matrix();
|
|
29138
|
+
matrix.scale(value, this.scope.project.view.bounds.center);
|
|
29139
|
+
this.updateViewMatrix(matrix);
|
|
29140
|
+
}
|
|
29043
29141
|
translate(offsetX, offsetY) {
|
|
29044
29142
|
const matrix = new this.scope.Matrix();
|
|
29045
29143
|
matrix.translate({ x: offsetX, y: offsetY });
|
|
29046
|
-
this.
|
|
29144
|
+
this.updateViewMatrix(matrix);
|
|
29145
|
+
}
|
|
29146
|
+
reset() {
|
|
29147
|
+
this.updateViewMatrix(new this.scope.Matrix(), false);
|
|
29148
|
+
this.lastDelta = { x: 0, y: 0 };
|
|
29047
29149
|
}
|
|
29048
29150
|
};
|
|
29049
29151
|
|
|
@@ -29152,6 +29254,22 @@ var Whiteboard = class extends import_eventemitter39.default {
|
|
|
29152
29254
|
* 描边宽度
|
|
29153
29255
|
*/
|
|
29154
29256
|
strokeWidth;
|
|
29257
|
+
/**
|
|
29258
|
+
* 是否允许用鼠标/触控板进行缩放和拖动画布
|
|
29259
|
+
*/
|
|
29260
|
+
enableCameraByMouse;
|
|
29261
|
+
/**
|
|
29262
|
+
* 是否允许触摸屏上触摸事件进行缩放和拖动画布
|
|
29263
|
+
*/
|
|
29264
|
+
enableCameraByTouch;
|
|
29265
|
+
/**
|
|
29266
|
+
* 相机超出边界时, 警示阴影的颜色, 默认 "#F44336"
|
|
29267
|
+
*/
|
|
29268
|
+
cameraBoundaryColor;
|
|
29269
|
+
/**
|
|
29270
|
+
* 是否允许相机超出边界时, 警示高亮阴影, 默认 true
|
|
29271
|
+
*/
|
|
29272
|
+
enableCameraBoundaryHighlight;
|
|
29155
29273
|
getElementAttribute;
|
|
29156
29274
|
setElementAttribute;
|
|
29157
29275
|
getCurrentTool;
|
|
@@ -29193,6 +29311,21 @@ var Whiteboard = class extends import_eventemitter39.default {
|
|
|
29193
29311
|
* 清空当前页面
|
|
29194
29312
|
*/
|
|
29195
29313
|
clearPage;
|
|
29314
|
+
/**
|
|
29315
|
+
* 平移画布
|
|
29316
|
+
* @param {number} offsetX - x 轴偏移量
|
|
29317
|
+
* @param {number} offsetY - y 轴偏移量
|
|
29318
|
+
*/
|
|
29319
|
+
translateCamera;
|
|
29320
|
+
/**
|
|
29321
|
+
* 以画布中心为固定点缩放画布
|
|
29322
|
+
* @param {number} scale - 缩放比例
|
|
29323
|
+
*/
|
|
29324
|
+
scaleCamera;
|
|
29325
|
+
/**
|
|
29326
|
+
* 重置画布, 将画布缩放比例重置为 1, 平移量重置为 [0, 0]
|
|
29327
|
+
*/
|
|
29328
|
+
resetCamera;
|
|
29196
29329
|
/**
|
|
29197
29330
|
* 为 userId 指定的用户设置页面, 调用需要有 `WhiteboardPermissionFlag.setOthersView` 权限,
|
|
29198
29331
|
* userId 指定的用户的视角模式应为 `free`, 否则调用无效
|
|
@@ -30149,6 +30282,15 @@ var WhiteboardApplication = class extends import_forge_room3.AbstractApplication
|
|
|
30149
30282
|
this.inputType = type;
|
|
30150
30283
|
this.emitter.emit("inputTypeChange", this.inputType);
|
|
30151
30284
|
};
|
|
30285
|
+
this.emitter.translateCamera = (offsetX, offsetY) => {
|
|
30286
|
+
this.camera.translate(offsetX, offsetY);
|
|
30287
|
+
};
|
|
30288
|
+
this.emitter.scaleCamera = (scale) => {
|
|
30289
|
+
this.camera.scale(scale);
|
|
30290
|
+
};
|
|
30291
|
+
this.emitter.resetCamera = () => {
|
|
30292
|
+
this.camera.reset();
|
|
30293
|
+
};
|
|
30152
30294
|
this.emitter.on("error", (errorCode, errorMessage) => {
|
|
30153
30295
|
(0, import_forge_room3.log)("WhiteboardApplicationError", {
|
|
30154
30296
|
errorCode,
|
|
@@ -30212,6 +30354,38 @@ var WhiteboardApplication = class extends import_forge_room3.AbstractApplication
|
|
|
30212
30354
|
that.toolbarModel.dashArray = v;
|
|
30213
30355
|
}
|
|
30214
30356
|
});
|
|
30357
|
+
Object.defineProperty(this.emitter, "enableCameraByMouse", {
|
|
30358
|
+
get() {
|
|
30359
|
+
return that.camera.enableByMouse;
|
|
30360
|
+
},
|
|
30361
|
+
set(value) {
|
|
30362
|
+
that.camera.enableByMouse = value;
|
|
30363
|
+
}
|
|
30364
|
+
});
|
|
30365
|
+
Object.defineProperty(this.emitter, "enableCameraByTouch", {
|
|
30366
|
+
get() {
|
|
30367
|
+
return that.camera.enableByTouch;
|
|
30368
|
+
},
|
|
30369
|
+
set(value) {
|
|
30370
|
+
that.camera.enableByTouch = value;
|
|
30371
|
+
}
|
|
30372
|
+
});
|
|
30373
|
+
Object.defineProperty(this.emitter, "cameraBoundaryColor", {
|
|
30374
|
+
get() {
|
|
30375
|
+
return that.camera.boundaryColor;
|
|
30376
|
+
},
|
|
30377
|
+
set(value) {
|
|
30378
|
+
that.camera.boundaryColor = value;
|
|
30379
|
+
}
|
|
30380
|
+
});
|
|
30381
|
+
Object.defineProperty(this.emitter, "enableCameraBoundaryHighlight", {
|
|
30382
|
+
get() {
|
|
30383
|
+
return that.camera.enableBoundaryHighlight;
|
|
30384
|
+
},
|
|
30385
|
+
set(value) {
|
|
30386
|
+
that.camera.enableBoundaryHighlight = value;
|
|
30387
|
+
}
|
|
30388
|
+
});
|
|
30215
30389
|
}
|
|
30216
30390
|
userMap(userId) {
|
|
30217
30391
|
return this.getMap(`user/${userId}`);
|
|
@@ -30239,7 +30413,12 @@ var WhiteboardApplication = class extends import_forge_room3.AbstractApplication
|
|
|
30239
30413
|
);
|
|
30240
30414
|
this.pageModel.on("pagesChange", this.handleLayersChange);
|
|
30241
30415
|
this.pageModel.on("switchPage", this.handlePageSwitch);
|
|
30416
|
+
if (option.maxScaleRatio && option.maxScaleRatio < 1 && option.maxScaleRatio !== -1) {
|
|
30417
|
+
throw new Error(`[@netless/forge-whiteboard] invalid maxScaleRatio ${option.maxScaleRatio}`);
|
|
30418
|
+
}
|
|
30242
30419
|
this.camera = new Camera(
|
|
30420
|
+
new this.paperScope.Size(option.width, option.height),
|
|
30421
|
+
option.maxScaleRatio ?? -1,
|
|
30243
30422
|
this.rootElement,
|
|
30244
30423
|
this.userManager,
|
|
30245
30424
|
this.paperScope,
|