|
@@ -65,9 +65,11 @@ export class SCanvasView extends SObject {
|
|
|
return this._origin;
|
|
|
}
|
|
|
set origin(v: SPoint) {
|
|
|
+ // 如果不可移动
|
|
|
if (!this.moveable) {
|
|
|
return;
|
|
|
}
|
|
|
+
|
|
|
this._origin.x = v.x;
|
|
|
this._origin.y = v.y;
|
|
|
this._needDraw = true;
|
|
@@ -81,9 +83,11 @@ export class SCanvasView extends SObject {
|
|
|
return this._scale;
|
|
|
}
|
|
|
set scale(v: number) {
|
|
|
+ // 如果不可缩放
|
|
|
if (!this.scalable) {
|
|
|
return;
|
|
|
}
|
|
|
+
|
|
|
this._scale = v;
|
|
|
this._needDraw = true;
|
|
|
}
|
|
@@ -116,8 +120,6 @@ export class SCanvasView extends SObject {
|
|
|
this.canvasView.style.cursor = v;
|
|
|
}
|
|
|
|
|
|
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
- //
|
|
|
/**
|
|
|
* 构造函数
|
|
|
*
|
|
@@ -191,21 +193,21 @@ export class SCanvasView extends SObject {
|
|
|
* @param y0 缩放计算的中心点 Y 坐标
|
|
|
*/
|
|
|
scaleByPoint(zoom: number, x0: number, y0: number): void {
|
|
|
+ // 如果不可缩放
|
|
|
if (!this.scalable) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
let z = zoom;
|
|
|
- /**
|
|
|
- * 缩放比例在最小比例和最大比例范围内
|
|
|
- */
|
|
|
+
|
|
|
+ // 缩放比例大于等于最大缩放比例
|
|
|
if (this.scale * zoom >= this.maxScale) {
|
|
|
z = this.maxScale / this.scale;
|
|
|
this.scale = this.maxScale;
|
|
|
- } else if (this.scale * zoom <= this.minScale) {
|
|
|
+ } else if (this.scale * zoom <= this.minScale) { // 缩放比例小于等于最小缩放比例
|
|
|
z = this.minScale / this.scale;
|
|
|
this.scale = this.minScale;
|
|
|
- } else {
|
|
|
+ } else { // 缩放比例在最小比例和最大比例范围内
|
|
|
this.scale *= zoom;
|
|
|
}
|
|
|
|
|
@@ -213,19 +215,17 @@ export class SCanvasView extends SObject {
|
|
|
this.origin.y = y0 - (y0 - this.origin.y) * z;
|
|
|
}
|
|
|
|
|
|
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
- //
|
|
|
/**
|
|
|
* 循环
|
|
|
*/
|
|
|
protected loop(): void {
|
|
|
- /** painter 对象 */
|
|
|
- let ctx = this.canvas;
|
|
|
- if (null != ctx && this._needDraw) {
|
|
|
+ // 存在 canvas 对象,并且需要刷新
|
|
|
+ if (null != this.canvas && this._needDraw) {
|
|
|
this._needDraw = false;
|
|
|
let painter = new SPainter(this);
|
|
|
this.onDraw(painter);
|
|
|
}
|
|
|
+
|
|
|
this.requestAnimationFrame(this.loop.bind(this));
|
|
|
}
|
|
|
|
|
@@ -257,6 +257,8 @@ export class SCanvasView extends SObject {
|
|
|
*/
|
|
|
protected onMouseDown(event: MouseEvent): void {
|
|
|
let se = new SMouseEvent(event);
|
|
|
+
|
|
|
+ // 按下鼠标中键
|
|
|
if (se.buttons & SMouseButton.MidButton) {
|
|
|
this._midKeyPos.x = se.x;
|
|
|
this._midKeyPos.y = se.y;
|
|
@@ -273,6 +275,8 @@ export class SCanvasView extends SObject {
|
|
|
if (this.moveable) {
|
|
|
// 按中键移动
|
|
|
let se = new SMouseEvent(event);
|
|
|
+
|
|
|
+ // 按下鼠标中键
|
|
|
if (se.buttons & SMouseButton.MidButton) {
|
|
|
this.origin.x += se.x - this._midKeyPos.x;
|
|
|
this.origin.y += se.y - this._midKeyPos.y;
|
|
@@ -304,9 +308,10 @@ export class SCanvasView extends SObject {
|
|
|
* @param event 事件参数
|
|
|
*/
|
|
|
protected onMouseWheel(event: WheelEvent): void {
|
|
|
+ // TODO: hanjianlong 补
|
|
|
if (event.deltaY < 0) {
|
|
|
this.scaleByPoint(this.wheelZoom, event.offsetX, event.offsetY);
|
|
|
- } else {
|
|
|
+ } else { // TODO: hanjianlong 补
|
|
|
this.scaleByPoint(1 / this.wheelZoom, event.offsetX, event.offsetY);
|
|
|
}
|
|
|
}
|
|
@@ -339,10 +344,14 @@ export class SCanvasView extends SObject {
|
|
|
*/
|
|
|
protected onTouchStart(event: TouchEvent): void {
|
|
|
let touches = event.touches;
|
|
|
+
|
|
|
+ // 单点触摸
|
|
|
if (touches.length == 1) {
|
|
|
this._touchPoint.x = event.touches[0].clientX;
|
|
|
this._touchPoint.y = event.touches[0].clientY;
|
|
|
}
|
|
|
+
|
|
|
+ // 两点触摸
|
|
|
if (touches.length == 2) {
|
|
|
this._touchState = STouchState.Zoom;
|
|
|
this._beforeLength = this.getDistance(event);
|
|
@@ -356,12 +365,16 @@ export class SCanvasView extends SObject {
|
|
|
*/
|
|
|
protected onTouchMove(event: TouchEvent): void {
|
|
|
let touches = event.touches;
|
|
|
+
|
|
|
+ // 单点触摸移动
|
|
|
if (touches.length == 1) {
|
|
|
this.origin.x += event.touches[0].clientX - this._touchPoint.x;
|
|
|
this.origin.y += event.touches[0].clientY - this._touchPoint.y;
|
|
|
this._touchPoint.x = event.touches[0].clientX;
|
|
|
this._touchPoint.y = event.touches[0].clientY;
|
|
|
}
|
|
|
+
|
|
|
+ // 两点触摸缩放
|
|
|
if (touches.length == 2) {
|
|
|
this.viewZoom(event);
|
|
|
}
|
|
@@ -433,11 +446,14 @@ export class SCanvasView extends SObject {
|
|
|
* @param event 触摸事件
|
|
|
*/
|
|
|
private viewZoom(event: TouchEvent): boolean {
|
|
|
+ // 如果是缩放
|
|
|
if (this._touchState == STouchState.Zoom) {
|
|
|
// 获取两点的距离
|
|
|
this._afterLength = this.getDistance(event);
|
|
|
// 变化的长度;
|
|
|
let gapLenght = this._afterLength - this._beforeLength;
|
|
|
+
|
|
|
+ // 两指操作变化距离超过 5 缩放(防抖)
|
|
|
if (Math.abs(gapLenght) > 5 && this._beforeLength != 0.0) {
|
|
|
// 求的缩放的比例
|
|
|
let tempScale = this._afterLength / this._beforeLength;
|
|
@@ -457,6 +473,7 @@ export class SCanvasView extends SObject {
|
|
|
* @return 两手指之间的距离
|
|
|
*/
|
|
|
private getDistance(event: TouchEvent): number {
|
|
|
+ // 两指操作距离小于 2 不做处理
|
|
|
if (event.touches.length < 2) {
|
|
|
return 0;
|
|
|
}
|