Newer
Older
urbanLifeline_YanAn / public / static / libs / mapbox / extend / CanvasLayer.js
@wudi wudi on 7 Oct 5 KB 1
(function (global, factory) {
	typeof exports === 'object' && typeof module !== 'undefined' ?
		module.exports = factory() :
		typeof define === 'function' && define.amd ? define(factory) :
			(global = typeof globalThis !== 'undefined' ? globalThis :
				global || self, global.mapboxgl1.CanvasLayer = factory());
}(window,(function(){

	function loadAllImages(imgUrls) {
		var _load = function (imgUrl) {
			//创建img标签
			var img = new Image();
			img.src = imgUrl;
			//跨域选项
			img.setAttribute('crossOrigin', 'Anonymous');
			return new Promise((resolve, reject) => {
				//文件加载完毕
				img.onload = function () {
					resolve(img);
				};
				//文件加载失败处理
				img.onerror = function (e) {
					console.log(imgUrl);
					reject();
				};
			});
		};
		var _loadAll = function (imgUrls) {
			var loadedImageUrls = [];
			for (var i = 0, len = imgUrls.length; i < len; i++) {
				loadedImageUrls.push(_load(imgUrls[i]));
			}
			return loadedImageUrls;
		};
		return Promise.all(_loadAll(imgUrls));
	}

	function generateUUID() {
		let d = new Date().getTime();
		let uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
			let r = (d + Math.random()*16)%16 | 0;
			d = Math.floor(d/16);
			return (c=='x' ? r : (r&0x3|0x8)).toString(16);
		});
		return uuid;
	}

	return class CanvasLayer {
		id=null;
		map=null;
		images=[];
		type="raster";
		canvas=null;
		params=null;
		index=0;
		loaded=false;
		constructor(options={id:'',canvasId:'',bbox:undefined,images:undefined,width:undefined,height:undefined,callback:()=>{}}) {
			this.canvas = document.getElementById(options.canvasId);
			if(!(this.canvas)) {
				this.canvas  = document.createElement('canvas');
				this.canvas.setAttribute("id", options.canvasId || generateUUID());
			}
			if(!(options.images.length)) console.warn(`Please set the photo set! → images:${options.images}`);
			if(!(options.bbox)) console.warn(`Please set the bbox! → images:${options.bbox}`);
			if(!options.width || !options.height) console.warn(`Please set the canvas width and height! → width:${options.width};height:${options.height}`);
			this.params = options;
			this.id = options.id || generateUUID();
			loadAllImages(options.images).then(res => this.images = res, this.loaded = true,options.callback && options.callback());
		}

		remove(){
			if(!this.map) return console.warn(`Please trigger "addTo" This method is called after the "map" instance is passed in;`);
			let layer = this.map.getLayer(this.id);
			if(!layer) return console.warn(`The current layer has not been added to the map;`);
			this.map.removeLayer(this.id);
			this.map.removeSource(this.id);
		}

		addTo(map){
			if(!map) return console.warn(`Configure the map instance;`);
			this.map = map;
			if(!this.params.bbox || !this.params.bbox.length) return console.error(`The current object is missing important parameters. Please add them and trigger the method again; url:${this.params.url};url:${this.params.layers}`);
			let coordinates = [
				[this.params.bbox[0],this.params.bbox[3]],
				[this.params.bbox[2],this.params.bbox[3]],
				[this.params.bbox[2],this.params.bbox[1]],
				[this.params.bbox[0],this.params.bbox[1]],
			];
			this.map.addSource(this.id, {'type':'canvas',coordinates,canvas:this.canvas,animate:true});
			this.map.addLayer({'id':this.id, 'type':this.type, 'source': this.id});
		}

		show(){
			this.setLayerParams({visibility:'visible'});
		}

		hide(){
			this.setLayerParams({visibility:'none'});
		}

		setOpacity(opacity){
			this.setLayerParams({},{'raster-opacity':opacity});
		}

		async setInitializeParams(params={}){
			this.loaded = false;
			this.params = Object.assign(this.params,params);
			let res = await loadAllImages(this.params.images);
			if(this.params.bbox) this.map.getSource(this.id).setCoordinates([[this.params.bbox[0],this.params.bbox[3]], [this.params.bbox[2],this.params.bbox[3]], [this.params.bbox[2],this.params.bbox[1]], [this.params.bbox[0],this.params.bbox[1]]]);
			this.images = res;
			this.loaded = true;
			this.index= 0;
			params.callback && params.callback();
		}

		setLayerParams(layout={},paint={}){
			let layoutKeys = Object.keys(layout);
			let paintKeys = Object.keys(paint);
			layoutKeys.forEach(key => this.map.setLayoutProperty(this.id,key,layout[key]));
			paintKeys.forEach(key => this.map.setPaintProperty(this.id,key,paint[key]));
		}

		prev(time=1000){
			let flag =false;
			let opacity = 1;
			let step = 1;
			let stepNum = opacity / step;
			let interval = setInterval(()=> {
				if(!flag) opacity = Number((opacity - stepNum).toFixed(2));
				if(opacity == 0) flag = true,this.setIndex(this.index - 1);
				// console.log(opacity,this.index);
				if(flag) opacity = Number((opacity + stepNum).toFixed(2));
				this.refresh(opacity);
				if(opacity == 1) clearInterval(interval);
			},time / step);
		}

		next(time=1000){
			let flag =false;
			let opacity = 1;
			let step = 1;
			let stepNum = opacity / step;
			let interval = setInterval(()=> {
				if(!flag) opacity = Number((opacity - stepNum).toFixed(2));
				if(opacity == 0) flag = true,this.setIndex(this.index + 1);
				// console.log(opacity,this.index);
				if(flag) opacity = Number((opacity + stepNum).toFixed(2));
				this.refresh(opacity);
				if(opacity == 1) clearInterval(interval);
			},time / step);
		}

		setIndex(index){
			index = index<0?this.params.images.length-1:index;
			index = this.params.images.length<=index?0:index;
			this.index = index;
		}

		refresh(alpha=1){
			if(!this.loaded) return;
			this.canvas.width = this.params.width;
			this.canvas.height = this.params.height;
			let context = this.canvas.getContext('2d');
			context.globalAlpha = alpha;
			context.drawImage(this.images[this.index], 0, 0, this.params.width, this.params.height);
		}

		static loadAllImages1(imgUrls){
			return loadAllImages(imgUrls);
		}
	}
})));