| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380 | const cacheChart = {}const fontSizeReg = /([\d\.]+)px/;class EventEmit {	constructor() {		this.__events = {};	}	on(type, listener) {		if (!type || !listener) {			return;		}		const events = this.__events[type] || [];		events.push(listener);		this.__events[type] = events;	}	emit(type, e) {		if (type.constructor === Object) {			e = type;			type = e && e.type;		}		if (!type) {			return;		}		const events = this.__events[type];		if (!events || !events.length) {			return;		}		events.forEach((listener) => {			listener.call(this, e);		});	}	off(type, listener) {		const __events = this.__events;		const events = __events[type];		if (!events || !events.length) {			return;		}		if (!listener) {			delete __events[type];			return;		}		for (let i = 0, len = events.length; i < len; i++) {			if (events[i] === listener) {				events.splice(i, 1);				i--;			}		}	}}class Image {	constructor() {		this.currentSrc = null		this.naturalHeight = 0		this.naturalWidth = 0		this.width = 0		this.height = 0		this.tagName = 'IMG'	}	set src(src) {		this.currentSrc = src		uni.getImageInfo({			src,			success: (res) => {				this.naturalWidth = this.width = res.width				this.naturalHeight = this.height = res.height				this.onload()			},			fail: () => {				this.onerror()			}		})	}	get src() {		return this.currentSrc	}}class OffscreenCanvas {	constructor(ctx, com, canvasId) {		this.tagName = 'canvas'		this.com = com		this.canvasId = canvasId		this.ctx = ctx	}	set width(w) {		this.com.offscreenWidth = w	}	set height(h) {		this.com.offscreenHeight = h	}	get width() {		return this.com.offscreenWidth || 0	}	get height() {		return this.com.offscreenHeight || 0	}	getContext(type) {		return this.ctx	}	getImageData() {		return new Promise((resolve, reject) => {			this.com.$nextTick(() => {				uni.canvasGetImageData({					x:0,					y:0,					width: this.com.offscreenWidth,					height: this.com.offscreenHeight,					canvasId: this.canvasId,					success: (res) => {						resolve(res)					},					fail: (err) => {						reject(err)					},				}, this.com)			})		})	}}export class Canvas {	constructor(ctx, com, isNew, canvasNode={}) {		cacheChart[com.canvasId] = {ctx}		this.canvasId = com.canvasId;		this.chart = null;		this.isNew = isNew		this.tagName = 'canvas'		this.canvasNode = canvasNode;		this.com = com;		if (!isNew) {this._initStyle(ctx)}		this._initEvent();		this._ee = new EventEmit()	}	getContext(type) {		if (type === '2d') {			return this.ctx;		}	}	setAttribute(key, value) {		if(key === 'aria-label') {			this.com['ariaLabel'] = value		}	}	setChart(chart) {		this.chart = chart;	}	createOffscreenCanvas(param){		if(!this.children) {			this.com.isOffscreenCanvas = true			this.com.offscreenWidth = param.width||300			this.com.offscreenHeight = param.height||300			const com = this.com			const canvasId = this.com.offscreenCanvasId			const context = uni.createCanvasContext(canvasId, this.com)			this._initStyle(context)			this.children = new OffscreenCanvas(context, com, canvasId)		} 		return this.children	}	appendChild(child) {		console.log('child', child)	}	dispatchEvent(type, e) {		if(typeof type == 'object') {			this._ee.emit(type.type, type);		} else {			this._ee.emit(type, e);		}		return true	}	attachEvent() {	}	detachEvent() {	}	addEventListener(type, listener) {		this._ee.on(type, listener)	}	removeEventListener(type, listener) {		this._ee.off(type, listener)	}	_initCanvas(zrender, ctx) {		zrender.util.getContext = function() {			return ctx;		};		zrender.util.$override('measureText', function(text, font) {			ctx.font = font || '12px sans-serif';			return ctx.measureText(text, font);		});	}	_initStyle(ctx, child) {		const styles = [			'fillStyle',			'strokeStyle',			'fontSize',			'globalAlpha',			'opacity',			'textAlign',			'textBaseline',			'shadow',			'lineWidth',			'lineCap',			'lineJoin',			'lineDash',			'miterLimit',			'font'		];		const colorReg = /#([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])\b/g;		styles.forEach(style => {			Object.defineProperty(ctx, style, {				set: value => {					if (style === 'font' && fontSizeReg.test(value)) {						const match = fontSizeReg.exec(value);						ctx.setFontSize(match[1]);						return;					}					if (style === 'opacity') {						ctx.setGlobalAlpha(value)						return;					}					if (style !== 'fillStyle' && style !== 'strokeStyle' || value !== 'none' && value !== null) {						// #ifdef H5 || APP-PLUS || MP-BAIDU						if(typeof value == 'object') {							if (value.hasOwnProperty('colorStop') || value.hasOwnProperty('colors')) {								ctx['set' + style.charAt(0).toUpperCase() + style.slice(1)](value);							}							return						} 						// #endif						// #ifdef MP-TOUTIAO						if(colorReg.test(value)) {							value = value.replace(colorReg, '#$1$1$2$2$3$3')						}						// #endif						ctx['set' + style.charAt(0).toUpperCase() + style.slice(1)](value);					}				}			});		});		if(!this.isNew && !child) {			ctx.uniDrawImage = ctx.drawImage			ctx.drawImage = (...a) => {				a[0] = a[0].src				ctx.uniDrawImage(...a)			}		}		if(!ctx.createRadialGradient) {			ctx.createRadialGradient = function() {				return ctx.createCircularGradient(...[...arguments].slice(-3))			};		}		// 字节不支持		if (!ctx.strokeText) {			ctx.strokeText = (...a) => {				ctx.fillText(...a)			}		}		// 钉钉不支持 		if (!ctx.measureText) {			const strLen = (str) => {				let len = 0;				for (let i = 0; i < str.length; i++) {					if (str.charCodeAt(i) > 0 && str.charCodeAt(i) < 128) {						len++;					} else {						len += 2;					}				}				return len;			}			ctx.measureText = (text, font) => {				let fontSize = 12;				if (font) {					fontSize = parseInt(font.match(/([\d\.]+)px/)[1])				}				fontSize /= 2;				return {					width: strLen(text) * fontSize				};			}		}	}	_initEvent(e) {		this.event = {};		const eventNames = [{			wxName: 'touchStart',			ecName: 'mousedown'		}, {			wxName: 'touchMove',			ecName: 'mousemove'		}, {			wxName: 'touchEnd',			ecName: 'mouseup'		}, {			wxName: 'touchEnd',			ecName: 'click'		}];		eventNames.forEach(name => {			this.event[name.wxName] = e => {				const touch = e.touches[0];				this.chart.getZr().handler.dispatch(name.ecName, {					zrX: name.wxName === 'tap' ? touch.clientX : touch.x,					zrY: name.wxName === 'tap' ? touch.clientY : touch.y				});			};		});	}	set width(w) {		this.canvasNode.width = w	}	set height(h) {		this.canvasNode.height = h	}	get width() {		return this.canvasNode.width || 0	}	get height() {		return this.canvasNode.height || 0	}	get ctx() {		return cacheChart[this.canvasId]['ctx'] || null	}	set chart(chart) {		cacheChart[this.canvasId]['chart'] = chart	}	get chart() {		return cacheChart[this.canvasId]['chart'] || null	}}export function dispatch(name, {x,y, wheelDelta}) {	this.dispatch(name, {		zrX: x,		zrY: y,		zrDelta: wheelDelta,		preventDefault: () => {},		stopPropagation: () =>{}	});}export function setCanvasCreator(echarts, {canvas, node}) {	// echarts.setCanvasCreator(() => canvas);	if(echarts && !echarts.registerPreprocessor) {		return console.warn('echarts 版本不对或未传入echarts,vue3请使用esm格式')	}	echarts.registerPreprocessor(option => {		if (option && option.series) {			if (option.series.length > 0) {				option.series.forEach(series => {					series.progressive = 0;				});			} else if (typeof option.series === 'object') {				option.series.progressive = 0;			}		}	});	function loadImage(src, onload, onerror) {		let img = null		if(node && node.createImage) {			img = node.createImage()			img.onload = onload.bind(img);			img.onerror = onerror.bind(img);			img.src = src;			return img		} else {			img = new Image()			img.onload = onload.bind(img)			img.onerror = onerror.bind(img);			img.src = src			return img		}	}	if(echarts.setPlatformAPI) {		echarts.setPlatformAPI({			loadImage: canvas.setChart ? loadImage : null,			createCanvas(){				return canvas			}		})	}}
 |