簡體   English   中英

在 Mapbox GL JS 中制作動畫時如何顯示多段線覆蓋的距離?

[英]How can I show the distance a polyline has covered while animating it in Mapbox GL JS?

我正在使用 Mapbox GL JS 逐幀捕獲 geoJson 的 animation 視頻(類似於此處描述的內容: https://docs.mapbox.com/mapbox-gl-js/example/animate-a-line/ ).

這里描述了將 mapbox 動畫編碼為 mp4 的策略: https://github.com/mapbox/mapbox-gl-js/issues/5297https://github.com/mapbox/mapbox-gl-js/pull /10172

我想在繪制每一幀時顯示折線所覆蓋的距離。 我需要距離位於 GL 本身中(例如,與畫布頂部的 HTML 元素相反),因為這是我從中捕獲視頻的地方。

有人可以幫助描述對我執行此操作的高效策略嗎?

除了拆開 Mapbox GL JS,為什么不直接嘗試在 mapbox canvas 上繪圖呢?

在這個例子中,有兩個畫布,創建相同。

第二個是另一個添加覆蓋的requestAnimationFrame循環。

我還展示了如何使用 MediaRecorder 進行錄制。

 const canvas1 = document.getElementById('canvas1') const canvas2 = document.getElementById('canvas2') const video = document.getElementById('output') const status = document.getElementById('status') let x = 0 // Value to be displayed const setupCanvas = (canvas) => { canvas.height = 300 canvas.width = 300 const canvas1Ctx = canvas.getContext('2d') canvas1Ctx.fillStyle = 'black' canvas1Ctx.fillRect(300, 100, 100, 100) const animateCanvas = () => { x += 2; if (x > 300) x = 10 canvas1Ctx.fillStyle = 'rgba(20,20,20,1)' canvas1Ctx.fillRect(0, 0, canvas.width, canvas.height) canvas1Ctx.beginPath() canvas1Ctx.arc(x, 100, 20, 0, 2 * Math.PI) canvas1Ctx.fillStyle = 'rgba(250,0,0,1)' canvas1Ctx.fill() requestAnimationFrame(animateCanvas) } animateCanvas() } const addOverlay = (canvas) => { const canvasCtx = canvas2.getContext('2d') function animateOverlay() { canvasCtx.font = '48px serif' canvasCtx.fillStyle = 'white' canvasCtx.fillText(`X: ${x}`, 10, 50) requestAnimationFrame(animateOverlay) } animateOverlay() } const initVideoCapture = () => { var videoStream = canvas2.captureStream(30) var mediaRecorder = new MediaRecorder(videoStream) var chunks = [] mediaRecorder.ondataavailable = function(e) { chunks.push(e.data) } mediaRecorder.onstop = function(e) { var blob = new Blob(chunks, { 'type': 'video/mp4' }) chunks = [] var videoURL = URL.createObjectURL(blob) video.src = videoURL } mediaRecorder.ondataavailable = function(e) { chunks.push(e.data) } mediaRecorder.start() status.textContent = 'Recording...' setTimeout(function() { mediaRecorder.stop() status.textContent = 'Complete' }, 5000) } setupCanvas(canvas1) setupCanvas(canvas2) addOverlay(canvas2) initVideoCapture()
 <canvas id="canvas1"></canvas> <canvas id="canvas2"></canvas> <video id="output" autoplay controls></video> <p>Status: <span id="status">Loading</span></p>

嘗試這個:

// show the distance a polyline has covered while animating it in mapbox gl js

var map = new mapboxgl.Map({
    container: 'map',
    style: 'mapbox://styles/mapbox/streets-v9',
    center: [-74.5, 40],
    zoom: 9,
})

var geojson = {
    type: 'Feature',
    properties: {},
    geometry: {
        type: 'LineString',
        coordinates: [
            [-74.5, 40],
            [-74.45, 40.7],
            [-74.36, 40.8],
            [-74.36, 41.2],
        ],
    },
}

map.on('load', function () {
    map.addLayer({
        id: 'route',
        type: 'line',
        source: {
            type: 'geojson',
            data: geojson,
        },
        layout: {
            'line-join': 'round',
            'line-cap': 'round',
        },
        paint: {
            'line-color': '#888',
            'line-width': 8,
        },
    })

    var lineDistance = turf.lineDistance(geojson, 'kilometers')
    var arc = []
    var maxTravelTime = 0

    for (var i = 0; i < lineDistance; i += lineDistance / 200) {
        var segment = turf.along(geojson, i, 'kilometers')
        arc.push(segment.geometry.coordinates)
    }

    map.addLayer({
        id: 'point',
        type: 'symbol',
        source: {
            type: 'geojson',
            data: {
                type: 'FeatureCollection',
                features: [
                    {
                        type: 'Feature',
                        properties: {},
                        geometry: {
                            type: 'Point',
                            coordinates: arc[0],
                        },
                    },
                ],
            },
        },
        layout: {
            'icon-image': 'car',
            'icon-rotate': ['get', 'bearing'],
            'icon-rotation-alignment': 'map',
            'icon-allow-overlap': true,
            'icon-ignore-placement': true,
        },
    })

    function animate() {
        map.getSource('point').setData(geojson)
        if (maxTravelTime < lineDistance) {
            maxTravelTime += lineDistance / 200
        } else {
            maxTravelTime = 0
        }

        requestAnimationFrame(animate)
    }

    animate()
})

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM