839 lines
23 KiB
Plaintext
839 lines
23 KiB
Plaintext
import { ShapeType, ICanvasEvent, ICanvasDomEvent, IEventListener, CanvasEventType, ICanvasOptional, IcanvasDomEventDetail } from './interface.uts';
|
|
// import { Shape } from './lib/shape.uts';
|
|
import { Shape } from '@/uni_modules/tmx-ui/core/canvas/lib/shape.uts';
|
|
export class ICanvas {
|
|
canvas : CanvasContext | null = null;
|
|
ctx : CanvasRenderingContext2D | null = null;
|
|
canvasNode : NodeInfo | null = null
|
|
|
|
width : number = 0;
|
|
height : number = 0;
|
|
boxWidth : number = 0;
|
|
boxHeight : number = 0;
|
|
dpr : number = 1;
|
|
/**
|
|
* 命中检测事件范围,默认只对clik点击进行命中测试,如果全放开会有性能风险
|
|
* 相当于是事件过滤。比如['click']那么元素只会触发click事件,其它事件不会响应
|
|
* 空数组响应所有事件
|
|
*/
|
|
checkPointInHitEvents = ['click'] as CanvasEventType[]
|
|
|
|
//点击时的位置
|
|
private touch_x = 0
|
|
private touch_y = 0
|
|
//移动时的位置
|
|
private touch_move_x = 0
|
|
private touch_move_y = 0
|
|
//结束时的位置
|
|
private touch_end_x = 0
|
|
private touch_end_y = 0
|
|
//结束时相对起始时之间的位置距离
|
|
private touch_end_len_x = 0
|
|
private touch_end_len_y = 0
|
|
//移动时相对上一次移动的距离
|
|
private touch_move_len_x = 0
|
|
private touch_move_len_y = 0
|
|
//点击时的时间
|
|
private touchStartTime = 0
|
|
//点击抬起时的结束时间.
|
|
private touchEndTime = 0
|
|
|
|
private touchTimeTid = 0
|
|
|
|
|
|
id = Math.random().toString(16).substring(4)
|
|
|
|
gaptimeId = 23
|
|
|
|
private shapes : ShapeType[] = [];
|
|
private eventListeners : Map<CanvasEventType, IEventListener[]> = new Map();
|
|
|
|
component : any | null = null;
|
|
canvasId : string;
|
|
|
|
|
|
constructor(config : ICanvasOptional) {
|
|
this.canvasId = config.canvasId;
|
|
this.component = config.component
|
|
}
|
|
init() : Promise<any | null> {
|
|
const _this = this;
|
|
return new Promise((res) => {
|
|
uni.createSelectorQuery()
|
|
.in(_this.component)
|
|
.select("#" + _this.canvasId)
|
|
.boundingClientRect()
|
|
.exec(result => {
|
|
if (result.length == 0) return;
|
|
let node = result[0]! as NodeInfo
|
|
uni.createCanvasContextAsync({
|
|
id: _this.canvasId,
|
|
component: _this.component as ComponentPublicInstance | null,
|
|
success: (context : CanvasContext) => {
|
|
_this.canvasNode = node
|
|
_this.canvas = context;
|
|
|
|
const dpr = uni.getWindowInfo().pixelRatio ?? 1;
|
|
const canvasContext = context.getContext('2d')!;
|
|
// #ifdef APP
|
|
canvasContext.resetTransform()
|
|
// #endif
|
|
const canvas = canvasContext.canvas;
|
|
canvas.width = canvas.offsetWidth * dpr;
|
|
canvas.height = canvas.offsetHeight * dpr;
|
|
canvasContext.scale(dpr, dpr);
|
|
_this.ctx = canvasContext as CanvasRenderingContext2D;
|
|
|
|
_this.dpr = dpr;
|
|
|
|
_this.ctx!.globalAlpha = 1;
|
|
_this.width = node.width!;
|
|
_this.height = node.height!;
|
|
_this.boxWidth = canvas.offsetWidth;
|
|
_this.boxHeight = canvas.offsetHeight;
|
|
res(_this)
|
|
}
|
|
})
|
|
})
|
|
})
|
|
|
|
}
|
|
|
|
private _resizePos() {
|
|
const _this = this;
|
|
uni.createSelectorQuery()
|
|
.in(_this.component)
|
|
.select("#" + _this.canvasId)
|
|
.boundingClientRect()
|
|
.exec(result => {
|
|
if (result.length == 0) return;
|
|
let node = result[0]! as NodeInfo
|
|
_this.canvasNode = node
|
|
})
|
|
}
|
|
|
|
clear() : ICanvas {
|
|
this.ctx!.clearRect(0, 0, this.width, this.height)
|
|
return this;
|
|
}
|
|
|
|
addShape(shape : ShapeType|ShapeType[]) : ICanvas {
|
|
if(Array.isArray(shape)){
|
|
let _this = this;
|
|
shape.forEach((el)=>{
|
|
_this.shapes.push(el);
|
|
})
|
|
}else{
|
|
this.shapes.push(shape);
|
|
}
|
|
this.shapes.sort((a, b ) : number => {
|
|
let ela = a as Shape
|
|
let elb = b as Shape
|
|
return ela.zIndex - elb.zIndex
|
|
})
|
|
return this;
|
|
}
|
|
|
|
removeShape(shape : ShapeType) : ICanvas {
|
|
for (let i = 0; i < this.shapes.length; i++) {
|
|
let itemshape = this.shapes[i]
|
|
if (itemshape instanceof Shape && shape instanceof Shape) {
|
|
if (itemshape.id == shape.id) {
|
|
this.shapes.splice(i, 1);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return this;
|
|
}
|
|
|
|
render() : ICanvas {
|
|
this.clear();
|
|
for (let i = 0; i < this.shapes.length; i++) {
|
|
const shape = this.shapes[i];
|
|
if (shape instanceof Shape) {
|
|
shape.draw(this.ctx!);
|
|
}
|
|
}
|
|
return this;
|
|
}
|
|
|
|
update() : ICanvas {
|
|
|
|
let needsRender = false;
|
|
for (let i = 0; i < this.shapes.length; i++) {
|
|
const shape = this.shapes[i];
|
|
if (shape instanceof Shape) {
|
|
if (shape.needsUpdate) {
|
|
needsRender = true;
|
|
shape.update()
|
|
}
|
|
}
|
|
}
|
|
if (needsRender) {
|
|
this.render();
|
|
}
|
|
return this;
|
|
}
|
|
|
|
getImage():Promise<string>{
|
|
return new Promise((res,_rej)=>{
|
|
// #ifdef WEB||H5
|
|
try {
|
|
this.ctx.canvas.toBlob((blob)=>{
|
|
res(URL.createObjectURL(blob))
|
|
},'images/png',1)
|
|
} catch (error) {
|
|
console.error(error,'注意画布中的图片要同域')
|
|
res('')
|
|
}
|
|
// #endif
|
|
|
|
// #ifdef APP
|
|
let ele = uni.getElementById(this.canvasId) as UniElement
|
|
ele!.takeSnapshot({
|
|
success(result){
|
|
res(result.tempFilePath)
|
|
},
|
|
fail(){
|
|
res('')
|
|
}
|
|
})
|
|
// #endif
|
|
|
|
// #ifdef MP
|
|
uni.canvasToTempFilePath({
|
|
canvasId:this.canvasId,
|
|
success(result){
|
|
res(result.tempFilePath)
|
|
},
|
|
fail(){
|
|
res('')
|
|
}
|
|
},this.component)
|
|
// #endif
|
|
})
|
|
}
|
|
/** 将外部事件绑定到对象上,实现事件分发. **/
|
|
bindEvent(eventType : any | null) {
|
|
|
|
let _this = this;
|
|
clearTimeout(this.touchTimeTid)
|
|
if (eventType == null || this.canvasNode == null) return;
|
|
const winTop = uni.getWindowInfo().windowTop
|
|
const offsetTop = this.canvasNode!.top! + 0
|
|
const offsetLeft = this.canvasNode!.left!
|
|
//防止触摸和鼠标事件同时触发。
|
|
let isTouch = false;
|
|
|
|
// 移动端
|
|
// #ifdef APP-ANDROID||H5
|
|
if (eventType instanceof TouchEvent) {
|
|
// #endif
|
|
// #ifdef APP-IOS||APP-HARMONY
|
|
if (eventType instanceof UniTouchEvent) {
|
|
// #endif
|
|
// #ifdef MP
|
|
if (true) {
|
|
// #endif
|
|
|
|
eventType.stopPropagation()
|
|
eventType.preventDefault()
|
|
|
|
isTouch = true;
|
|
let changedTouches = eventType.changedTouches
|
|
// #ifndef APP
|
|
changedTouches = Array.from(changedTouches)
|
|
// #endif
|
|
const clientX = changedTouches[0].clientX - offsetLeft
|
|
const clientY = changedTouches[0].clientY - offsetTop
|
|
|
|
if (eventType.type == 'touchstart') {
|
|
this.touch_x = clientX
|
|
this.touch_y = clientY
|
|
this.touch_move_x = clientX
|
|
this.touch_move_y = clientY
|
|
this.touch_end_x = clientX
|
|
this.touch_end_y = clientY
|
|
|
|
|
|
this.touch_end_len_x = 0
|
|
this.touch_end_len_y = 0
|
|
this.touch_move_len_x = 0
|
|
this.touch_move_len_y = 0
|
|
|
|
|
|
this.touchStartTime = Date.now()
|
|
this.buildEvents('down', {
|
|
type: 'down',
|
|
x: changedTouches[0].clientX - offsetLeft,
|
|
y: changedTouches[0].clientY - offsetTop,
|
|
detail: [{
|
|
startX: this.touch_x,
|
|
startY: this.touch_y,
|
|
endX: this.touch_end_x,
|
|
endY: this.touch_end_y,
|
|
moveX: this.touch_move_x,
|
|
moveY: this.touch_move_y,
|
|
moveLenX: this.touch_move_len_x,
|
|
moveLenY: this.touch_move_len_y,
|
|
endLenX: this.touch_end_len_x,
|
|
endLenY: this.touch_end_len_y
|
|
}],
|
|
touches: changedTouches.map((el) : ICanvasDomEvent => {
|
|
return {
|
|
type: 'down',
|
|
x: el.clientX - offsetLeft,
|
|
y: el.clientY - offsetTop,
|
|
touches: [],
|
|
detail: [{
|
|
startX: this.touch_x,
|
|
startY: this.touch_y,
|
|
endX: this.touch_end_x,
|
|
endY: this.touch_end_y,
|
|
moveX: this.touch_move_x,
|
|
moveY: this.touch_move_y,
|
|
moveLenX: this.touch_move_len_x,
|
|
moveLenY: this.touch_move_len_y,
|
|
endLenX: this.touch_end_len_x,
|
|
endLenY: this.touch_end_len_y
|
|
}],
|
|
} as ICanvasDomEvent
|
|
})
|
|
} as ICanvasDomEvent)
|
|
this.touchTimeTid = setTimeout(() => {
|
|
_this.buildEvents('longpress', {
|
|
type: 'longpress',
|
|
x: changedTouches[0].clientX - offsetLeft,
|
|
y: changedTouches[0].clientY - offsetTop,
|
|
detail: [{
|
|
startX: this.touch_x,
|
|
startY: this.touch_y,
|
|
endX: this.touch_end_x,
|
|
endY: this.touch_end_y,
|
|
moveX: this.touch_move_x,
|
|
moveY: this.touch_move_y,
|
|
moveLenX: this.touch_move_len_x,
|
|
moveLenY: this.touch_move_len_y,
|
|
endLenX: this.touch_end_len_x,
|
|
endLenY: this.touch_end_len_y
|
|
}],
|
|
touches: changedTouches.map((el) : ICanvasDomEvent => {
|
|
return {
|
|
type: 'longpress',
|
|
x: el.clientX - offsetLeft,
|
|
y: el.clientY - offsetTop,
|
|
touches: [],
|
|
detail: [{
|
|
startX: this.touch_x,
|
|
startY: this.touch_y,
|
|
endX: this.touch_end_x,
|
|
endY: this.touch_end_y,
|
|
moveX: this.touch_move_x,
|
|
moveY: this.touch_move_y,
|
|
moveLenX: this.touch_move_len_x,
|
|
moveLenY: this.touch_move_len_y,
|
|
endLenX: this.touch_end_len_x,
|
|
endLenY: this.touch_end_len_y
|
|
}],
|
|
} as ICanvasDomEvent
|
|
})
|
|
} as ICanvasDomEvent)
|
|
}, 500)
|
|
} else if (eventType.type == 'touchmove') {
|
|
|
|
this.touch_move_len_x = this.touch_move_x - clientX
|
|
this.touch_move_len_y = this.touch_move_y - clientY
|
|
|
|
this.touch_end_len_x = clientX - this.touch_x
|
|
this.touch_end_len_y = clientY - this.touch_y
|
|
|
|
this.touch_move_x = clientX
|
|
this.touch_move_y = clientY
|
|
|
|
this.buildEvents('move', {
|
|
type: 'move',
|
|
x: changedTouches[0].clientX - offsetLeft,
|
|
y: changedTouches[0].clientY - offsetTop,
|
|
detail: [{
|
|
startX: this.touch_x,
|
|
startY: this.touch_y,
|
|
endX: this.touch_end_x,
|
|
endY: this.touch_end_y,
|
|
moveX: this.touch_move_x,
|
|
moveY: this.touch_move_y,
|
|
moveLenX: this.touch_move_len_x,
|
|
moveLenY: this.touch_move_len_y,
|
|
endLenX: this.touch_end_len_x,
|
|
endLenY: this.touch_end_len_y
|
|
}],
|
|
touches: changedTouches.map((el) : ICanvasDomEvent => {
|
|
return {
|
|
type: 'move',
|
|
x: el.clientX - offsetLeft,
|
|
y: el.clientY - offsetTop,
|
|
touches: [],
|
|
detail: [{
|
|
startX: this.touch_x,
|
|
startY: this.touch_y,
|
|
endX: this.touch_end_x,
|
|
endY: this.touch_end_y,
|
|
moveX: this.touch_move_x,
|
|
moveY: this.touch_move_y,
|
|
moveLenX: this.touch_move_len_x,
|
|
moveLenY: this.touch_move_len_y,
|
|
endLenX: this.touch_end_len_x,
|
|
endLenY: this.touch_end_len_y
|
|
}],
|
|
} as ICanvasDomEvent
|
|
})
|
|
} as ICanvasDomEvent)
|
|
|
|
} else if (eventType.type == 'touchend') {
|
|
this.touch_end_x = clientX
|
|
this.touch_end_y = clientY
|
|
this.touch_end_len_x = this.touch_end_x - this.touch_x
|
|
this.touch_end_len_y = this.touch_end_y - this.touch_y
|
|
|
|
let nowTIme = Date.now()
|
|
this.buildEvents('up', {
|
|
type: 'up',
|
|
x: changedTouches[0].clientX - offsetLeft,
|
|
y: changedTouches[0].clientY - offsetTop,
|
|
detail: [{
|
|
startX: this.touch_x,
|
|
startY: this.touch_y,
|
|
endX: this.touch_end_x,
|
|
endY: this.touch_end_y,
|
|
moveX: this.touch_move_x,
|
|
moveY: this.touch_move_y,
|
|
moveLenX: this.touch_move_len_x,
|
|
moveLenY: this.touch_move_len_y,
|
|
endLenX: this.touch_end_len_x,
|
|
endLenY: this.touch_end_len_y
|
|
}],
|
|
touches: changedTouches.map((el) : ICanvasDomEvent => {
|
|
return {
|
|
type: 'up',
|
|
x: el.clientX - offsetLeft,
|
|
y: el.clientY - offsetTop,
|
|
touches: [],
|
|
detail: [{
|
|
startX: this.touch_x,
|
|
startY: this.touch_y,
|
|
endX: this.touch_end_x,
|
|
endY: this.touch_end_y,
|
|
moveX: this.touch_move_x,
|
|
moveY: this.touch_move_y,
|
|
moveLenX: this.touch_move_len_x,
|
|
moveLenY: this.touch_move_len_y,
|
|
endLenX: this.touch_end_len_x,
|
|
endLenY: this.touch_end_len_y
|
|
}],
|
|
} as ICanvasDomEvent
|
|
})
|
|
} as ICanvasDomEvent)
|
|
// 判断是不是单击
|
|
const difftime = nowTIme - this.touchStartTime
|
|
if (difftime > 50 && difftime < 250) {
|
|
this.buildEvents('click', {
|
|
type: 'click',
|
|
x: changedTouches[0].clientX - offsetLeft,
|
|
y: changedTouches[0].clientY - offsetTop,
|
|
detail: [{
|
|
startX: this.touch_x,
|
|
startY: this.touch_y,
|
|
endX: this.touch_end_x,
|
|
endY: this.touch_end_y,
|
|
moveX: this.touch_move_x,
|
|
moveY: this.touch_move_y,
|
|
moveLenX: this.touch_move_len_x,
|
|
moveLenY: this.touch_move_len_y,
|
|
endLenX: this.touch_end_len_x,
|
|
endLenY: this.touch_end_len_y
|
|
}],
|
|
touches: changedTouches.map((el) : ICanvasDomEvent => {
|
|
return {
|
|
type: 'click',
|
|
x: el.clientX - offsetLeft,
|
|
y: el.clientY - offsetTop,
|
|
touches: [],
|
|
detail: [{
|
|
startX: this.touch_x,
|
|
startY: this.touch_y,
|
|
endX: this.touch_end_x,
|
|
endY: this.touch_end_y,
|
|
moveX: this.touch_move_x,
|
|
moveY: this.touch_move_y,
|
|
moveLenX: this.touch_move_len_x,
|
|
moveLenY: this.touch_move_len_y,
|
|
endLenX: this.touch_end_len_x,
|
|
endLenY: this.touch_end_len_y
|
|
}],
|
|
} as ICanvasDomEvent
|
|
})
|
|
} as ICanvasDomEvent)
|
|
}
|
|
// 判断是不是双击
|
|
const diffEndtime = nowTIme - this.touchEndTime
|
|
if (diffEndtime > 100 && diffEndtime < 280) {
|
|
this.buildEvents('dbclick', {
|
|
type: 'dbclick',
|
|
x: changedTouches[0].clientX - offsetLeft,
|
|
y: changedTouches[0].clientY - offsetTop,
|
|
detail: [{
|
|
startX: this.touch_x,
|
|
startY: this.touch_y,
|
|
endX: this.touch_end_x,
|
|
endY: this.touch_end_y,
|
|
moveX: this.touch_move_x,
|
|
moveY: this.touch_move_y,
|
|
moveLenX: this.touch_move_len_x,
|
|
moveLenY: this.touch_move_len_y,
|
|
endLenX: this.touch_end_len_x,
|
|
endLenY: this.touch_end_len_y
|
|
}],
|
|
touches: [] as ICanvasDomEvent[]
|
|
})
|
|
}
|
|
this.touchEndTime = nowTIme
|
|
} else if (eventType.type == 'touchcancel') {
|
|
this.touch_end_x = clientX
|
|
this.touch_end_y = clientY
|
|
this.touch_end_len_x = this.touch_end_x - this.touch_x
|
|
this.touch_end_len_y = this.touch_end_y - this.touch_y
|
|
const touchesList = changedTouches.map((el) : ICanvasDomEvent => {
|
|
return {
|
|
type: 'cancel',
|
|
x: el.clientX - offsetLeft,
|
|
y: el.clientY - offsetTop,
|
|
touches: [],
|
|
detail: [{
|
|
startX: this.touch_x,
|
|
startY: this.touch_y,
|
|
endX: this.touch_end_x,
|
|
endY: this.touch_end_y,
|
|
moveX: this.touch_move_x,
|
|
moveY: this.touch_move_y,
|
|
moveLenX: this.touch_move_len_x,
|
|
moveLenY: this.touch_move_len_y,
|
|
endLenX: this.touch_end_len_x,
|
|
endLenY: this.touch_end_len_y
|
|
} as IcanvasDomEventDetail ] as IcanvasDomEventDetail[],
|
|
} as ICanvasDomEvent
|
|
})
|
|
this.buildEvents('cancel', {
|
|
type: 'cancel',
|
|
x: changedTouches[0].clientX - offsetLeft,
|
|
y: changedTouches[0].clientY - offsetTop,
|
|
detail: [{
|
|
startX: this.touch_x,
|
|
startY: this.touch_y,
|
|
endX: this.touch_end_x,
|
|
endY: this.touch_end_y,
|
|
moveX: this.touch_move_x,
|
|
moveY: this.touch_move_y,
|
|
moveLenX: this.touch_move_len_x,
|
|
moveLenY: this.touch_move_len_y,
|
|
endLenX: this.touch_end_len_x,
|
|
endLenY: this.touch_end_len_y
|
|
} as IcanvasDomEventDetail ] as IcanvasDomEventDetail[],
|
|
touches: touchesList as ICanvasDomEvent[]
|
|
} as ICanvasDomEvent)
|
|
}
|
|
}
|
|
// 兼容PC
|
|
// #ifdef WEB
|
|
|
|
if (eventType instanceof MouseEvent && !(eventType instanceof PointerEvent) && !isTouch) {
|
|
eventType.stopPropagation()
|
|
const clientX = eventType.layerX
|
|
const clientY = eventType.layerY
|
|
|
|
if (eventType.type == 'mousedown') {
|
|
this.touch_x = clientX
|
|
this.touch_y = clientY
|
|
this.touch_move_x = clientX
|
|
this.touch_move_y = clientY
|
|
this.touch_end_x = clientX
|
|
this.touch_end_y = clientY
|
|
|
|
|
|
this.touch_end_len_x = 0
|
|
this.touch_end_len_y = 0
|
|
this.touch_move_len_x = 0
|
|
this.touch_move_len_y = 0
|
|
|
|
this.touchStartTime = Date.now()
|
|
window.ICnavansId = this.id
|
|
this.buildEvents('down', {
|
|
type: 'down',
|
|
x: clientX,
|
|
y: clientY,
|
|
detail: [{
|
|
startX: this.touch_x,
|
|
startY: this.touch_y,
|
|
endX: this.touch_end_x,
|
|
endY: this.touch_end_y,
|
|
moveX: this.touch_move_x,
|
|
moveY: this.touch_move_y,
|
|
moveLenX: this.touch_move_len_x,
|
|
moveLenY: this.touch_move_len_y,
|
|
endLenX: this.touch_end_len_x,
|
|
endLenY: this.touch_end_len_y
|
|
}],
|
|
touches: [] as ICanvasDomEvent[]
|
|
})
|
|
|
|
this.touchTimeTid = setTimeout(() => {
|
|
_this.buildEvents('longpress', {
|
|
type: 'longpress',
|
|
x: clientX,
|
|
y: clientY,
|
|
detail: [{
|
|
startX: this.touch_x,
|
|
startY: this.touch_y,
|
|
endX: this.touch_end_x,
|
|
endY: this.touch_end_y,
|
|
moveX: this.touch_move_x,
|
|
moveY: this.touch_move_y,
|
|
moveLenX: this.touch_move_len_x,
|
|
moveLenY: this.touch_move_len_y,
|
|
endLenX: this.touch_end_len_x,
|
|
endLenY: this.touch_end_len_y
|
|
}],
|
|
touches: [] as ICanvasDomEvent[]
|
|
} as ICanvasDomEvent)
|
|
}, 500)
|
|
}
|
|
if (eventType.type == 'mousemove' && window.ICnavansId === this.id) {
|
|
this.touch_move_len_x = this.touch_move_x - clientX
|
|
this.touch_move_len_y = this.touch_move_y - clientY
|
|
|
|
this.touch_end_len_x = clientX - this.touch_x
|
|
this.touch_end_len_y = clientY - this.touch_y
|
|
|
|
this.touch_move_x = clientX
|
|
this.touch_move_y = clientY
|
|
|
|
this.buildEvents('move', {
|
|
type: 'move',
|
|
x: clientX,
|
|
y: clientY,
|
|
detail: [{
|
|
startX: this.touch_x,
|
|
startY: this.touch_y,
|
|
endX: this.touch_end_x,
|
|
endY: this.touch_end_y,
|
|
moveX: this.touch_move_x,
|
|
moveY: this.touch_move_y,
|
|
moveLenX: this.touch_move_len_x,
|
|
moveLenY: this.touch_move_len_y,
|
|
endLenX: this.touch_end_len_x,
|
|
endLenY: this.touch_end_len_y
|
|
}],
|
|
touches: [] as ICanvasDomEvent[]
|
|
})
|
|
}
|
|
if ((eventType.type == 'mouseup') && window.ICnavansId === this.id) {
|
|
this.touch_end_x = clientX
|
|
this.touch_end_y = clientY
|
|
this.touch_end_len_x = this.touch_end_x - this.touch_x
|
|
this.touch_end_len_y = this.touch_end_y - this.touch_y
|
|
|
|
let nowTIme = Date.now()
|
|
window.ICnavansId = ""
|
|
|
|
this.buildEvents('up', {
|
|
type: 'up',
|
|
x: clientX,
|
|
y: clientY,
|
|
detail: [{
|
|
startX: this.touch_x,
|
|
startY: this.touch_y,
|
|
endX: this.touch_end_x,
|
|
endY: this.touch_end_y,
|
|
moveX: this.touch_move_x,
|
|
moveY: this.touch_move_y,
|
|
moveLenX: this.touch_move_len_x,
|
|
moveLenY: this.touch_move_len_y,
|
|
endLenX: this.touch_end_len_x,
|
|
endLenY: this.touch_end_len_y
|
|
}],
|
|
touches: [] as ICanvasDomEvent[]
|
|
})
|
|
|
|
// 判断是不是单击
|
|
const difftime = nowTIme - this.touchStartTime
|
|
if (difftime > 50 && difftime < 250) {
|
|
this.buildEvents('click', {
|
|
type: 'click',
|
|
x: clientX,
|
|
y: clientY,
|
|
detail: [{
|
|
startX: this.touch_x,
|
|
startY: this.touch_y,
|
|
endX: this.touch_end_x,
|
|
endY: this.touch_end_y,
|
|
moveX: this.touch_move_x,
|
|
moveY: this.touch_move_y,
|
|
moveLenX: this.touch_move_len_x,
|
|
moveLenY: this.touch_move_len_y,
|
|
endLenX: this.touch_end_len_x,
|
|
endLenY: this.touch_end_len_y
|
|
}],
|
|
touches: [] as ICanvasDomEvent[]
|
|
} as ICanvasDomEvent)
|
|
}
|
|
|
|
// 判断是不是双击
|
|
const diffEndtime = nowTIme - this.touchEndTime
|
|
if (diffEndtime > 100 && diffEndtime < 280) {
|
|
this.buildEvents('dbclick', {
|
|
type: 'dbclick',
|
|
x: clientX,
|
|
y: clientY,
|
|
detail: [],
|
|
touches: [] as ICanvasDomEvent[]
|
|
})
|
|
}
|
|
this.touchEndTime = nowTIme
|
|
}
|
|
if ((eventType.type == 'mouseleave') && window.ICnavansId === this.id) {
|
|
this.touch_end_x = clientX
|
|
this.touch_end_y = clientY
|
|
this.touch_end_len_x = this.touch_end_x - this.touch_x
|
|
this.touch_end_len_y = this.touch_end_y - this.touch_y
|
|
|
|
window.ICnavansId = ""
|
|
this.buildEvents('cancel', {
|
|
type: 'cancel',
|
|
x: clientX,
|
|
y: clientY,
|
|
detail: [{
|
|
startX: this.touch_x,
|
|
startY: this.touch_y,
|
|
endX: this.touch_end_x,
|
|
endY: this.touch_end_y,
|
|
moveX: this.touch_move_x,
|
|
moveY: this.touch_move_y,
|
|
moveLenX: this.touch_move_len_x,
|
|
moveLenY: this.touch_move_len_y,
|
|
endLenX: this.touch_end_len_x,
|
|
endLenY: this.touch_end_len_y
|
|
}],
|
|
touches: [] as ICanvasDomEvent[]
|
|
})
|
|
}
|
|
|
|
}
|
|
// #endif
|
|
|
|
|
|
}
|
|
|
|
addEventListener(eventName : CanvasEventType, listener : IEventListener) : ICanvas {
|
|
if (!this.eventListeners.has(eventName)) {
|
|
this.eventListeners.set(eventName, []);
|
|
}
|
|
this.eventListeners.get(eventName)!.push(listener);
|
|
return this;
|
|
}
|
|
|
|
removeEventListener(eventName : CanvasEventType, listener : IEventListener) : ICanvas {
|
|
const listeners = this.eventListeners.get(eventName);
|
|
if (listeners == null) return this;
|
|
const index = listeners.indexOf(listener);
|
|
if (index != -1) {
|
|
listeners.splice(index, 1);
|
|
}
|
|
return this;
|
|
}
|
|
|
|
private getTargetShape(eventName : CanvasEventType, x : number, y : number) : ShapeType[] {
|
|
let shapes = [] as ShapeType[]
|
|
// 只针对开命中事件进行检测
|
|
if (!this.checkPointInHitEvents.includes(eventName) && this.checkPointInHitEvents.length > 0) return shapes;
|
|
for (let i = this.shapes.length - 1; i >= 0; i--) {
|
|
const shape = this.shapes[i];
|
|
if (shape instanceof Shape) {
|
|
if (shape.isPointInPath(x, y, shape.id)) {
|
|
shapes.push(shape)
|
|
if (!shape.bubbleEvent) {
|
|
return shapes;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return shapes;
|
|
}
|
|
|
|
private buildEvents(eventName : CanvasEventType, eventDetail : ICanvasDomEvent) {
|
|
this._resizePos()
|
|
const listeners = this.eventListeners.get(eventName);
|
|
const target = this.getTargetShape(eventName, eventDetail.x, eventDetail.y);
|
|
|
|
|
|
const event : ICanvasEvent = {
|
|
type: eventName,
|
|
x: eventDetail.x,
|
|
y: eventDetail.y,
|
|
target: target,
|
|
detail: eventDetail.detail,
|
|
touches: eventDetail.touches.map((el : ICanvasDomEvent) : ICanvasEvent => {
|
|
return {
|
|
type: eventName,
|
|
x: el.x,
|
|
y: el.y,
|
|
target: target,
|
|
detail: el.detail,
|
|
touches: [] as ICanvasEvent[]
|
|
} as ICanvasEvent
|
|
})
|
|
};
|
|
if (listeners != null) {
|
|
for (let i = 0; i < listeners.length; i++) {
|
|
let children = listeners[i]
|
|
//执行画布的监听事件
|
|
children(event);
|
|
}
|
|
}
|
|
|
|
for (let i = 0; i < this.shapes.length; i++) {
|
|
const shape = this.shapes[i];
|
|
if (shape instanceof Shape) {
|
|
if (event.detail.length == 0) continue;
|
|
let startX = event.detail[0].startX
|
|
let startY = event.detail[0].startY
|
|
if (shape.isPointInPath(startX, startY, shape.id) && shape.draggable && eventName == 'down') {
|
|
shape.draggableing = true;
|
|
}
|
|
if (shape.draggable && (eventName == 'up' || eventName == 'cancel') && shape.draggableing) {
|
|
shape.draggableing = false;
|
|
}
|
|
if (shape.draggableing && eventName == 'move') {
|
|
shape.drag(eventName, event)
|
|
}
|
|
}
|
|
}
|
|
|
|
if (target.length > 0) {
|
|
let isUpdate = false;
|
|
for (let i = 0; i < target.length; i++) {
|
|
const shape = target[i];
|
|
if (shape instanceof Shape) {
|
|
shape.buildEvents(eventName, event)
|
|
if(shape.draggable&&!isUpdate){
|
|
isUpdate = true;
|
|
}
|
|
}
|
|
}
|
|
if(isUpdate){
|
|
this.render()
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
} |