记vue+leaflet的一次canvas渲染爆栈
Posted cqq626
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了记vue+leaflet的一次canvas渲染爆栈相关的知识,希望对你有一定的参考价值。
背景:
在地图上绘制大量的circleMarker,leaflet能选择使用canvas来渲染,比起默认的svg渲染来说在大量绘制的情况下会更加流畅。但当触发其中某一个circleMarker的tooltip或popup时,浏览器报错“Uncaught RangeError: Maximum call stack size exceeded”:
解决过程:
1、写了个测试代码来复现问题:
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset=‘utf-8‘ /> 5 <title>Add a raster tile source</title> 6 <meta name=‘viewport‘ content=‘initial-scale=1,maximum-scale=1,user-scalable=no‘ /> 7 <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script> 8 <script src="https://unpkg.com/[email protected]/dist/leaflet-src.js"></script> 9 <!--<script src="./vue.js"></script>--> 10 <!--<script src="./leaflet.js"></script>--> 11 <link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" 12 integrity="sha512-Rksm5RenBEKSKFjgI3a41vrjkw4EVPlJ3+OiI65vTjIdo9brlAacEuKOiQ5OFh7cOI1bkDwLqdLw3Zg0cRJAAQ==" 13 crossorigin=""/> 14 <style> 15 * { margin:0; padding:0; } 16 html,body,#vue-wrap,#map { height: 100%; } 17 </style> 18 </head> 19 <body> 20 <div id="vue-wrap"> 21 <div id="map">test</div> 22 </div> 23 <script> 24 new Vue({ 25 el: ‘#vue-wrap‘, 26 data: function () { 27 return { 28 map: ‘‘, 29 canvas: L.canvas() 30 }; 31 }, 32 mounted: function () { 33 this.init(); 34 }, 35 methods: { 36 init () { 37 this.map = new L.Map(‘map‘, { 38 center: [39.928953, 116.389129], 39 zoom: 11, 40 maxZoom: 18, 41 attributionControl: false, 42 zoomControl: true 43 }); 44 45 this.paintMarkers(); 46 }, 47 paintMarkers () { 48 console.log(‘start paint‘); 49 console.time(‘paint‘); 50 for (let i = 0; i < 50000; i++) { 51 let marker = L.circleMarker(this.generateLatlng(), { 52 color: ‘#000‘, 53 weight: 1, 54 opacity: 1, 55 fillOpacity: 0.8, 56 radius: 6, 57 fillColor: ‘orange‘, 58 59 renderer: this.canvas 60 }); 61 marker.bindTooltip(i + ‘‘); 62 marker.bindPopup(`i: ${i}`); 63 this.map.addLayer(marker); 64 } 65 console.timeEnd(‘paint‘); 66 }, 67 generateLatlng () { 68 let lat_min = 39.70111, 69 lat_max = 40.14660, 70 lng_min = 116.05843, 71 lng_max = 116.63521; 72 73 let lat = this.getRandomNum(lat_min, lat_max), 74 lng = this.getRandomNum(lng_min, lng_max); 75 76 return [lat, lng]; 77 }, 78 getRandomNum (min, max) { 79 max = Math.max(min, max); 80 min = Math.min(min, max); 81 return Math.random() * (max - min) + min; 82 } 83 } 84 }); 85 </script> 86 87 </body> 88 </html>
以上是关于记vue+leaflet的一次canvas渲染爆栈的主要内容,如果未能解决你的问题,请参考以下文章
SVG 与 HTML5 的 canvas 各有啥优点,哪个更有前途