マップにアニメーションアイコンを追加
Canvasで実行時に生成されたマップにアニメーションアイコンを追加します。
<!DOCTYPE html><html><head><meta charset="utf-8"><title>マップにアニメーションアイコンを追加</title><meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no"><link href="https://api.mapbox.com/mapbox-gl-js/v2.14.1/mapbox-gl.css" rel="stylesheet"><script src="https://api.mapbox.com/mapbox-gl-js/v2.14.1/mapbox-gl.js"></script><style>body { margin: 0; padding: 0; }#map { position: absolute; top: 0; bottom: 0; width: 100%; }</style></head><body><div id="map"></div> <script> // TO MAKE THE MAP APPEAR YOU MUST // ADD YOUR ACCESS TOKEN FROM // https://account.mapbox.com mapboxgl.accessToken = 'YOUR_MAPBOX_ACCESS_TOKEN';const map = new mapboxgl.Map({container: 'map',style: 'mapbox://styles/mapbox/streets-v9'}); const size = 200; // This implements `StyleImageInterface`// to draw a pulsing dot icon on the map.const pulsingDot = {width: size,height: size,data: new Uint8Array(size * size * 4), // When the layer is added to the map,// get the rendering context for the map canvas.onAdd: function () {const canvas = document.createElement('canvas');canvas.width = this.width;canvas.height = this.height;this.context = canvas.getContext('2d');}, // Call once before every frame where the icon will be used.render: function () {const duration = 1000;const t = (performance.now() % duration) / duration; const radius = (size / 2) * 0.3;const outerRadius = (size / 2) * 0.7 * t + radius;const context = this.context; // Draw the outer circle.context.clearRect(0, 0, this.width, this.height);context.beginPath();context.arc(this.width / 2,this.height / 2,outerRadius,0,Math.PI * 2);context.fillStyle = `rgba(255, 200, 200, ${1 - t})`;context.fill(); // Draw the inner circle.context.beginPath();context.arc(this.width / 2,this.height / 2,radius,0,Math.PI * 2);context.fillStyle = 'rgba(255, 100, 100, 1)';context.strokeStyle = 'white';context.lineWidth = 2 + 4 * (1 - t);context.fill();context.stroke(); // Update this image's data with data from the canvas.this.data = context.getImageData(0,0,this.width,this.height).data; // Continuously repaint the map, resulting// in the smooth animation of the dot.map.triggerRepaint(); // Return `true` to let the map know that the image was updated.return true;}}; map.on('load', () => {map.addImage('pulsing-dot', pulsingDot, { pixelRatio: 2 }); map.addSource('dot-point', {'type': 'geojson','data': {'type': 'FeatureCollection','features': [{'type': 'Feature','geometry': {'type': 'Point','coordinates': [0, 0] // icon position [lng, lat]}}]}});map.addLayer({'id': 'layer-with-pulsing-dot','type': 'symbol','source': 'dot-point','layout': {'icon-image': 'pulsing-dot'}});});</script> </body></html>