赞
踩
项目需要地图上实现不断报警的闪烁样式,之前是通过Overlay来处理的,但Overlay遮挡要素,无法很好的触发事件,所以就转而使用Canvas原生实现。过程主要参考:openlayers4中闪烁点的实现、canvas-flashMarker-RunJS。
原本的做法是通过构造新的对象new FlashMarker(map, citys),每次构造新增一个Canvas,没有办法清除,那么我针对这些问题进行适应性的修改。
经测试,过多的样式绘制会有卡顿,目前没有太好的方法解决,不过Canvas绘制仍然效果比Openlayers好。
这里效果就不展示了,效果可以在背景贴的原文那里看,我只是改动调用和优化实现。
- (function (global, factory) {
- typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
- typeof define === 'function' && define.amd ? define(factory) :
- (global.CanvasLayer = factory());
- }(this, (function () { 'use strict';
-
-
- //封装一个兼容性良好的方法
- window.requestAnimFrame= (function(){
- return window.requestAnimationFrame ||
- window.webkitRequestAnimationFrame ||
- window.mozRequestAnimationFrame ||
- function(callback){
- window.setTimeout(callback, 1000 / 60);
- }
- })();
- window.cancelAnimFrame = (function(){
- return window.cancelAnimationFrame ||
- window.webkitCancelAnimationFrame ||
- window.mozCancelAnimationFrame ||
- function(id){
- window.clearTimeout(id);
- }
- })();
-
- function CanvasLayer(options) {
- this.options = options || {};
- this.paneName = this.options.paneName || 'labelPane';
- this.zIndex = this.options.zIndex || 0;
- this._map = options.map;
- this._lastDrawTime = null;
- this.show();
- }
-
- CanvasLayer.prototype.initialize = function () {
- var map = this._map;
- var canvas = this.canvas = document.createElement('canvas');
- var ctx = this.ctx = this.canvas.getContext('2d');
- canvas.style.cssText = 'position:absolute;' + 'left:0;' + 'top:0;' + 'z-index:' + this.zIndex + ';';
- this.animationIds = [];
- this.adjustSize();
- this.adjustRatio(ctx);
- map.getViewport().appendChild(canvas);
- var that = this;
- map.getView().on('propertychange',function(){
- $(canvas).hide();
- });
- map.on("moveend",function(){
- $(canvas).show();
- that.adjustSize();
- //that._draw();
- });
- };
-
- // Wilson
- CanvasLayer.prototype.clear = function () {
- var animationCtx = this.ctx;
- var width = this._map.getSize()[0];
- var height = this._map.getSize()[1];
- var animationIds = this.animationIds;
- for (var i = 0; i < animationIds.length; i++) {
- window.cancelAnimationFrame(animationIds[i]);
- }
- this.animationIds = [];
- animationCtx.clearRect(0, 0, width, height);
- };
-
- // Wilson
- CanvasLayer.prototype.addMarkers = function (dataSet) {
- var animationCtx = this.ctx;
- var width = this._map.getSize()[0];
- var height = this._map.getSize()[1];
- var markers = [];
- var length = this.animationIds.length;
- var that = this;
- for (var i = 0; i < dataSet.length; i++) {
- markers.push(new Marker(dataSet[i]));
- }
-
- //开始动画
- var startAnim = function() {
- var animationId = window.requestAnimFrame(render);
- that.animationIds[length] = animationId;
-
- }
-
- function render() {
- startAnim();
-
- animationCtx.fillStyle = 'rgba(0,0,0,.95)';
- var prev = animationCtx.globalCompositeOperation;
- animationCtx.globalCompositeOperation = 'destination-in';
- animationCtx.fillRect(0, 0, width, height);
- animationCtx.globalCompositeOperation = prev;
-
- for (var i = 0; i < markers.length; i++) {
- var marker = markers[i];
- marker.draw(animationCtx);
- }
- };
-
- startAnim();
- };
-
- CanvasLayer.prototype.adjustSize = function () {
- var size = this._map.getSize();
- var canvas = this.canvas;
- canvas.width = size[0];
- canvas.height = size[1];
- canvas.style.width = canvas.width + 'px';
- canvas.style.height = canvas.height + 'px';
- };
-
- CanvasLayer.prototype.adjustRatio = function (ctx) {
- var backingStore = ctx.backingStorePixelRatio || ctx.webkitBackingStorePixelRatio || ctx.mozBackingStorePixelRatio || ctx.msBackingStorePixelRatio || ctx.oBackingStorePixelRatio || ctx.backingStorePixelRatio || 1;
- var pixelRatio = (window.devicePixelRatio || 1) / backingStore;
- var canvasWidth = ctx.canvas.width;
- var canvasHeight = ctx.canvas.height;
- ctx.canvas.width = canvasWidth * pixelRatio;
- ctx.canvas.height = canvasHeight * pixelRatio;
- ctx.canvas.style.width = canvasWidth + 'px';
- ctx.canvas.style.height = canvasHeight + 'px';
- ctx.scale(pixelRatio, pixelRatio);
- };
-
- /*CanvasLayer.prototype._draw = function () {
- var map = this._map;
- var size = map.getSize();
- var center = map.getView().getCenter();
- if (center) {
- var pixel = map.getPixelFromCoordinate(center);
- this.canvas.style.left = pixel[0] - size[0] / 2 + 'px';
- this.canvas.style.top = pixel[1] - size[1] / 2 + 'px';
- //this.options.update && this.options.update.call(this);
- }
- };*/
-
- CanvasLayer.prototype.getContainer = function () {
- return this.canvas;
- };
-
- CanvasLayer.prototype.show = function () {
- this.initialize();
- this.canvas.style.display = 'block';
- };
-
- CanvasLayer.prototype.hide = function () {
- this.canvas.style.display = 'none';
- };
-
- CanvasLayer.prototype.setZIndex = function (zIndex) {
- this.canvas.style.zIndex = zIndex;
- };
-
- CanvasLayer.prototype.getZIndex = function () {
- return this.zIndex;
- };
-
- CanvasLayer.prototype.getZIndex = function () {
- return this.zIndex;
- };
-
- function Marker(opts) {
- this.city = opts.name;
- this.location = [opts.lnglat[0], opts.lnglat[1]];
- this.color = opts.color;
- this.type = opts.type || 'circle';
- this.speed = opts.speed || 0.15;
- this.size = 0;
- this.max = opts.max || 20;
- }
-
- Marker.prototype.draw = function (context) {
- context.save();
- context.beginPath();
- switch (this.type) {
- case 'circle':
- this._drawCircle(context);
- break;
- case 'ellipse':
- this._drawEllipse(context);
- break;
- default:
- break;
- }
- context.closePath();
- context.restore();
-
- this.size += this.speed;
- if (this.size > this.max) {
- this.size = 0;
- }
- };
-
- Marker.prototype._drawCircle = function (context) {
- var pixel = this.pixel||map.getPixelFromCoordinate(this.location);
- if(pixel) {
- context.strokeStyle = this.color;
- context.moveTo(pixel[0] + pixel.size, pixel[1]);
- context.arc(pixel[0], pixel[1], this.size, 0, Math.PI * 2);
- context.stroke();
- }
- };
-
- Marker.prototype._drawEllipse = function (context) {
- var pixel = this.pixel || map.getPixelFromCoordinate(this.location);
- if(pixel) {
- var x = pixel[0],
- y = pixel[1],
- w = this.size,
- h = this.size / 2,
- kappa = 0.5522848,
-
- // control point offset horizontal
- ox = w / 2 * kappa,
-
- // control point offset vertical
- oy = h / 2 * kappa,
-
- // x-start
- xs = x - w / 2,
-
- // y-start
- ys = y - h / 2,
-
- // x-end
- xe = x + w / 2,
-
- // y-end
- ye = y + h / 2;
-
- context.strokeStyle = this.color;
- context.moveTo(xs, y);
- context.bezierCurveTo(xs, y - oy, x - ox, ys, x, ys);
- context.bezierCurveTo(x + ox, ys, xe, y - oy, xe, y);
- context.bezierCurveTo(xe, y + oy, x + ox, ye, x, ye);
- context.bezierCurveTo(x - ox, ye, xs, y + oy, xs, y);
- context.stroke();
- }
- };
-
- return CanvasLayer;
- })));
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。