一、问题来源:

接触Openlayers 一段时间了,最近做了一个农业产业系统,项目中涉及到产业图例,最后考虑用canvas来绘制图例图像。当中带图片的图例移动时,图片会实现闪烁留白情况。闪烁是因为绘制图片本身的复杂性,导致canvas绘制频率和浏览器绘制频率不同步,出现图片出不来或者延迟出现,这过程中间就出现了空白显示为canvas底图颜色白色的情况。这里说的闪烁是,在单击地图移动图例时,文字前面的图片并没有出来。但是单击地图准备移动图例时别松开鼠标图片能出来,这个有点奇怪....

有些解决方案是用一个叫双缓冲的技术实现,这种办法确实能行,这里就不写了,用我们的办法实现。

双缓冲实现原理:创建一个临时canvas,先把下一帧动画绘制到临时canvas上。在每次真正绘制的时候,擦除正式canvas后,马上drawImage把临时canvas的内容copy过去,而这个copy过程是非常非常高效的,所以基本可以杜绝闪烁。

二 、实现步骤

1、new一个layer层,new一个Feature要素。

2、绘制一个canvas图像。

3、new一个样式,设置样式的Icon图片为上一步绘制好的canvas,并设置Icon宽高为canvas宽高。

4、设置要素Feature的样式为上一步new的样式,将要素Feature添加到layer层上。

5、最后将layer层添加到地图中。

三、加载ol地图,加载天地图矢量图为底图

var projection = ol.proj.get('EPSG:4326');

var projectionExtent = projection.getExtent();

var size = ol.extent.getWidth(projectionExtent) / ;

var resolutions = new Array(),

matrixIds = new Array(),

shapeArr = [];

for(var z = ; z <= ; ++z) {

resolutions[z] = size / Math.pow(, z);

matrixIds[z] = z;

}

//天地图矢量图

var tdt_road_layer = new ol.layer.Tile({

name: '矢量底图',

source: new ol.source.WMTS({

url: 'http://t1.tianditu.com/vec_c/wmts',

layer: 'vec',

matrixSet: 'c',

format: 'tiles',

projection: projection,

tileGrid: new ol.tilegrid.WMTS({

origin: ol.extent.getTopLeft(projectionExtent),

resolutions: resolutions,

matrixIds: matrixIds

}),

style: 'default'

}),

visible: true,

zIndex:

});

var view = new ol.View({

center: [118.77, 32.05],

zoom: 9.5,

projection: "EPSG:4326",

maxZoom:

});

var map = new ol.Map({

// 设置地图控件,默认的三个控件都不显示

controls: ol.control.defaults({

attribution: true,

rotate: true,

zoom: true

}).extend([

new ol.control.FullScreen(),

new ol.control.ScaleLine()

]),

layers: [

tdt_road_layer

],

target: 'map',

loadTilesWhileAnimating: true,

view: view

});

四、实现代码,实现文字前面带图片和带色块图例,有背景色的代码为方法调用,调用即可

window.onload = function() {

getMapPoint();

drawMapTuliMethod();

}

/*

* 图例数据

*/

var dataObj = [{

tname: '国家级文物保护建筑',

color: '#365e96',

}, {

tname: '省级文物保护建筑',

color: '#d1702f',

}, {

tname: '市级级文物保护建筑',

color: '#4fa1dc',

}, {

tname: '区县级文物保护建筑',

color: '#368829',

}]

/*

* 图例经纬度坐标,地图绑定了单击事件

* 单击返回经纬度并重新绘制canvas

*/

var removeData = {

tx: 118.82368355230953,

ty: 32.2359887979324

}

var canvas = document.createElement('canvas');

//绘制图例

function drawMapTuliMethod() {

var layers = new ol.layer.Vector({

type: 'tuli',

source: new ol.source.Vector(),

zIndex:

})

var shape = new ol.Feature({

geometry: new ol.geom.Point([removeData.tx, removeData.ty])

});

var ctx = canvas.getContext("2d");

var yheight = ;

yheight += dataObj.length * ; //计算canvas高度

canvas.width = ;

canvas.height = yheight;

/*设置图例样式*/

ctx.fillStyle = "#fff";

ctx.fillRect(, , , yheight); //绘制底图

ctx.font = "16px Arial";

ctx.fillStyle = "#000";

ctx.fillText('图例', canvas.width / 2.5, );

for(var i = ; i < dataObj.length; i++) {

//实现文字前面带色块

//ctx.fillStyle = dataObj[i].color; //块颜色

//ctx.fillRect(10, 60 + (i - 1) * 25, 15, 15); //颜色块:x,y,w,h

ctx.font = "12px Arial";

ctx.fillStyle = "#555";

ctx.fillText(dataObj[i].tname, , + (i - ) * ); //文字

//添加图片方法一,实现文字前面带图片,移动图例不会出现闪烁

drawImg_first('xiushan.png', i);

//添加图片方法二,移动图例会出现闪烁

//drawImg_Second(ctx, 'xiushan.png', i);

}

//将canvas添加到样式中

var style = new ol.style.Style({

image: new ol.style.Icon({

img: canvas,

imgSize: [canvas.width, canvas.height],

})

});

shape.setStyle(style);

layers.getSource().addFeature(shape);

map.addLayer(layers);

}

/*

* 将绘制完成的图片添加到canvas上

* @imgObj:图片对象

* @p:循环序号,确定图片坐标

*/

function drawTuliImage(imgObj, p) {

var ctxImge = canvas.getContext("2d");

ctxImge.drawImage(imgObj, , + (p * ), , );

}

/*

* 绘制图例上的图片,方法一

* 此方法能解决重绘canvas时图片闪烁留白的问题

* @imgs:图片名称

* @p:序号

* @complete:HTMLImageElement对象的一个属性,可以判断图片加载完成

*/

function drawImg_first(imgs, p) {

var imgObj = new Image();

imgObj.src = 'img/' + imgs;

//如果图片加载完成

if(imgObj.complete) {

drawTuliImage(imgObj, p);

} else {

//onload:重绘,重新加载

imgObj.onload = function() {

drawTuliImage(imgObj, p);

};

//加载失败

imgObj.onerror = function() {

console.log('canvas图片加载失败,请重试!')

};

}

}

/*

* 添加数据前面的图片,方法二

* 此方法绘制图片会出现闪烁留白情况,

* @ctx:绘图环境

* @imgs:图片名称

* @p:循环序号

*/

function drawImg_Second(ctx, imgs, p) {

var imgObj = new Image();

imgObj.src = 'img/' + imgs;

imgObj.onload = function() {

ctx.drawImage(imgObj, , + (p * ), , );

}

}

/*

* 添加图例之前删除原来

* 引用类型。length会变化,for循环倒着删除

* @deType:要删除的覆盖物名称

*/

function addNewsChartsDelectOring(deType) {

var layersArr = map.getLayers().getArray(); //获取所有覆盖物

//移除全部

if(deType == 'all') {

for(var i = layersArr.length - ; i >= ; i--) {

var ltype = layersArr[i].get('type');

if(ltype == 'tuli') map.removeLayer(layersArr[i]);

}

return;

}

//移除具体

else {

for(var i = layersArr.length - ; i >= ; i--) {

var ltype = layersArr[i].get('type');

if(ltype == deType) map.removeLayer(layersArr[i]);

}

return;

}

}

//地图单击事件

function getMapPoint() {

map.on('click', function(evt) {

var point = evt.coordinate; //鼠标单击点坐标

removeData.tx = point[];

removeData.ty = point[];

addNewsChartsDelectOring('all');

drawMapTuliMethod();

});

}

①文字前面带图片的图例,移动图例时canvas绘制图片频率和浏览器绘制频率不一导致图片不出来的效果图:

②文字前面带图片的效果图:

③文字前面带色块的效果图:

技术群 : 192713488

Android 如何将Canvas上绘制的内容保存成本地图片(转)

效果如下图所示 保存在sd卡上的文件为 手机上显示效果为: 1>>在Manifest文件中增加相应权限

canvas纯绘制雨伞、飞机、五角星、桃心,无逻辑

由于网上很多都是用很多算法和逻辑使用canvas进行绘制,但有时也无法解决一些小众需求 . 为了满足需求不能写运算纯手写,感觉真的很浪费时间,只有自己踩过的坑,才不想看到别人也被坑.我很懒,也想过弄个 ...

canvas高效绘制10万图形&comma;你必须知道的高效绘制技巧

最近的一个客户项目中,简化的需求是绘制按照行列绘制很多个圆圈.需求看起来不难,上手就可以做,写两个for循环. 原始绘制方法 首先定义了很多Circle对象,在遍历循环中调用该对象的draw方法.代码 ...

HTML5 Canvas中绘制椭圆的几种方法

1.canvas自带的绘制椭圆的方法 ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise)是后来 ...

HTML5使用Canvas来绘制图形

一.Canvas标签: 1.HTML5元素用于图形的绘制,通过脚本(通常是javascript)来完成. 2.标签只是图形容器,必须使用脚本来绘 ...

Canvas 实现绘制图表

这里用canvas实现了两个简单的图表,用到了canvas的基本用法,效果如下 新建 chart.js 文件,封装绘制方法 构造方法 function myChart(config){ this.wi ...

canvas&plus;js绘制序列帧动画&plus;面向对象

效果: 素材: 源码:(一般的绘制方式)

软件项目技术点&lpar;7&rpar;——在canvas上绘制自定义图形

AxeSlide软件项目梳理   canvas绘图系列知识点整理 图形种类 目前我们软件可以绘制出来的形状有如下这几种,作为开发者我们一直想支持用户可以拖拽的类似word里面图形库,但目前还没有找到比 ...

Canvas:绘制路径

Canvas:绘制路径 绘制路径 图形的基本元素是路径.路径是[通过不同颜色和宽度的线段或曲线相连形成的不同形状的]点的集合.一个路径,甚至一个子路径,都是闭合的. 使用路径绘制图形需要一些额外的步骤 ...

随机推荐

Android 上实现像微信一样的用Fragment来实现的Tab切页效果 提供源码下载

网有不少的例子,但是要么是像微信一样可是没有使用Fragment实现,要么是只实现了一个很简单的切换,没有下面的菜单页.这个例子有实现了,我觉得暂时够我用了##实现类:+ MainTabFragmen ...

第一章 UI实战开发 UIWindow UIView

@import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/c ...

x01&period;os&period;11&colon; IPC 路线图

学习的最好方法就是看代码,所以我们不妨跟着 IPC 的调用路线图,来学习学习 IPC. 从 x01.Lab.Download 下载代码后,首先进入 main.c 文件,在 TestA 中,有这么一句: ...

ASP&period;net 关于TextBox的TextMode&equals;&OpenCurlyDoubleQuote;PassWord”时的动态赋值

1.在界面创建一个新的TBPwdTemp并设置TextMode=“SingleLine”,visible=“false”,将数据库密码值传给该TextBox: 2.然后分别用 this.TBPwd.A ...

Paper&period;js - Paper&period;js

Paper.js - Paper.js   Paper.js is an open source vector graphics scripting framework that runs on to ...

python 之栈的实现

#!/usr/bin/env python # --------------------------------------- # author : Geng Jie # email : gengji ...

Java图的邻接矩阵实现

/** * * 图的邻接矩阵实现 * @author John * * @param */ class AMWGraph { private ArrayList& ...

笔记:Spring Cloud Zuul 快速入门

Spring Cloud Zuul 实现了路由规则与实例的维护问题,通过 Spring Cloud Eureka 进行整合,将自身注册为 Eureka 服务治理下的应用,同时从 Eureka 中获取了 ...

IdentityServer4【QuickStart】之使用ResourceOwnerPassword流程来保护API

使用ResourceOwnerPassword流程来保护API OAuth2.0中的ResourceOwnerPassword授权流程允许一个客户端发送username和password到token服 ...

openlayers3线段添加闪烁_openLayers 4 canvas图例绘制,canvas循环添加图片,解决图片闪烁问题...相关推荐

  1. openLayers 4 canvas图例绘制,canvas循环添加图片,解决图片闪烁问题

    一.问题来源: 接触Openlayers 一段时间了,最近做了一个农业产业系统,项目中涉及到产业图例,最后考虑用canvas来绘制图例图像.当中带图片的图例移动时,图片会实现闪烁留白情况.闪烁是因为绘 ...

  2. Android 如何将Canvas上绘制的内容保存成本地图片

    效果如下图所示 保存在sd卡上的文件为 手机上显示效果为: 1>>在Manifest文件中增加相应权限 <!-- 在SDCard中创建与删除文件权限 --><uses-p ...

  3. html5绘制缩放雨伞,canvas纯绘制雨伞、飞机、五角星、桃心,无逻辑

    由于网上很多都是用很多算法和逻辑使用canvas进行绘制,但有时也无法解决一些小众需求 . 为了满足需求不能写运算纯手写,感觉真的很浪费时间,只有自己踩过的坑,才不想看到别人也被坑.我很懒,也想过弄个 ...

  4. 微信小程序(数据可视化、Canvas、绘制线段、图形、太极图、文本、图像、渐变、变形)

    一.数据可视化 1数据可视化概述 数据可视化Data Visualization:就是指将结构或非结构数据转换成适当的可视化图表,然后将隐藏在数据中的信息直接展现于人们面前. 2应用场景 数据报表 特 ...

  5. SVG、canvas、绘制线段和填充多边形、矩形、曲线的绘制和填充

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 目录 文章目录 1.了解网页中的两个绘图技术 (1)SVG (2)canvas (3)画布的尺寸和坐标 2.绘制线段和填充多 ...

  6. 微信小程序 | canvas为你的天气预报添加雨雪效果

    在 Canvas 开发中,经常会提到粒子系统,使用粒子系统可以模拟出火.雾.云.雪等抽象视觉效果.它是HTML5新增的为页面添加多样化效果的绝佳实践. 正巧最近做的一个天气类微信小程序紧接尾声,寻思着 ...

  7. canvas为你的天气预报添加雨雪效果 | 微信小程序

    关注 前端瓶子君,回复"交流" 加入我们一起学习,天天进步 来源:行舟客 https://yunxiaomeng.blog.csdn.net/article/details/110 ...

  8. 图片在canvas中显示,给canvas添加文字,文字描边,将canvas保存成图片下载到本地

    Canvas简介 HTML5新增标签 Canvas API(画布)是在HTML5中新增的标签用于在网页实时生成图像,并且可以操作图像内容,基本上它是一个可以用JavaScript操作的位图(bitma ...

  9. C# Winform的panel控件添加背景图片后窗体闪烁问题解决办法

    C# Winform的panel控件添加背景图片后窗体闪烁问题解决办法 参考文章: (1)C# Winform的panel控件添加背景图片后窗体闪烁问题解决办法 (2)https://www.cnbl ...

最新文章

  1. 2015上半年软件设计师考点,难点3
  2. 心电信号去噪(part4)--经验模态分解法(EMD)
  3. C# 监控字段_有哪些好的C#开源项目推荐?
  4. 动态创建 Plist 文件
  5. jquery-weui滚动加载问题解决
  6. stopwatch类使用
  7. Java常用算法二:分治法
  8. vsftpd系统用户配置详解
  9. redis如何进行分库存储和选择模糊清除缓存
  10. 树莓派 USB摄像头 实现网络监控
  11. 华为云服务器测试并用docker快速搭建2048网站
  12. 控制器Ryu+Mininet完成集线器、自学习交换机、流量监控实例开发
  13. 解决微信屏蔽淘宝链接的方法
  14. P2627 [USACO11OPEN]Mowing the Lawn G(单调队列优化dp)
  15. H5及H5页面是什么意思?如何制作H5页面?
  16. 第二课,绘制几何图形
  17. Python 外星人入侵(一):武装飞船
  18. 我的博客 http://aofengblog.blog.163.com/
  19. 钉钉小程序企业内部应用开发总结
  20. dpdk实例flow_classify

热门文章

  1. AI预测世界杯冠军?附完整代码!
  2. 本人开发的网上考勤系统简介
  3. 给自己的APP添加自定义字体
  4. AssemblyInfo.cs文件的作用(转)
  5. master slavle mysql_MySQL 不停服务来启用 innodb_file_per_table
  6. 电子商务行业支付解决方案
  7. 【软件工程】软件测试目标定义 黑盒测试、白盒测试
  8. 福禄克FLUKE LinkIQ智能链路通工业以太网线缆+ 网络测试仪 解决工业以太网故障的头号原因
  9. Three.js初识:渲染立方体、3d字体、修改渲染背景颜色
  10. RunZeBlog项目开发流程