• maptalks 开发GIS地图(12)maptalks.three.05 bar-music


    1. 说明

    使用柱状图,并根据音乐节奏显示动画效果。

    2. 初始化地图

     1 var map = new maptalks.Map("map", {
     2             center: [120.88083857368815, 31.494732837748273],
     3             zoom: 10,
     4             pitch: 35,
     5             bearing: -43.600000000000136,
     6 
     7             centerCross: true,
     8             doubleClickZoom: false,
     9             // baseLayer: new maptalks.TileLayer('tile', {
    10             //     urlTemplate: 'https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png',
    11             //     subdomains: ['a', 'b', 'c', 'd'],
    12             //     attribution: '&copy; <a href="http://osm.org">OpenStreetMap</a> contributors, &copy; <a href="https://carto.com/">CARTO</a>'
    13             // })
    14         });

    3. 添加threelayer 图层,并设置环境。

    其中 oReq 对象读取 MP3文件的数据,并进行解析。

     1  // the ThreeLayer to draw
     2         var threeLayer = new maptalks.ThreeLayer('t', {
     3             forceRenderOnMoving: true,
     4             forceRenderOnRotating: true
     5             // animation: true
     6         });
     7         threeLayer.prepareToDraw = function (gl, scene, camera) {
     8             var light = new THREE.PointLight(0xffffff);
     9             // light.position.set(0, -10, 10).normalize();
    10             camera.add(light);
    11 
    12             var ambientlight = new THREE.AmbientLight(0x999999, 1.57);
    13             scene.add(ambientlight);
    14 
    15             var oReq = new XMLHttpRequest();
    16             oReq.open('GET', './data/roll-it-up.mp3', true);
    17             oReq.responseType = 'arraybuffer';
    18 
    19             oReq.onload = function (e) {
    20                 audioContext.decodeAudioData(oReq.response, initVisualizer);
    21             };
    22             oReq.send();
    23             // threeLayer.config('animation', true);
    24             animation();
    25         };
    26 
    27         threeLayer.addTo(map);

    4. MP3数据解析

     1   // code from https://www.echartsjs.com/examples/zh/editor.html?c=bar3d-music-visualization&gl=1
     2         function initVisualizer(audioBuffer) {
     3             inited = true;
     4 
     5             var source = audioContext.createBufferSource();
     6             source.buffer = audioBuffer;
     7 
     8             // Must invoked right after click event
     9             if (source.noteOn) {
    10                 source.noteOn(0);
    11             } else {
    12                 source.start(0);
    13             }
    14 
    15             var analyzer = audioContext.createAnalyser();
    16             var gainNode = audioContext.createGain();
    17             analyzer.fftSize = 4096;
    18 
    19             gainNode.gain.value = 1;
    20             source.connect(gainNode);
    21             gainNode.connect(analyzer);
    22             analyzer.connect(audioContext.destination);
    23 
    24             var frequencyBinCount = analyzer.frequencyBinCount;
    25             var dataArray = new Uint8Array(frequencyBinCount);
    26 
    27 
    28             function update() {
    29                 analyzer.getByteFrequencyData(dataArray);
    30 
    31                 var item = [];
    32                 var size = 50;
    33                 var dataProvider = [];
    34 
    35                 for (var i = 0; i < size * size; i++) {
    36                     var x = i % size;
    37                     var y = Math.floor(i / size);
    38                     var dx = x - size / 2;
    39                     var dy = y - size / 2;
    40 
    41                     var angle = Math.atan2(dy, dx);
    42                     if (angle < 0) {
    43                         angle = Math.PI * 2 + angle;
    44                     }
    45                     var dist = Math.sqrt(dx * dx + dy * dy);
    46                     var idx = Math.min(
    47                         frequencyBinCount - 1, Math.round(angle / Math.PI / 2 * 60 + dist * 60) + 100
    48                     );
    49 
    50                     var val = Math.pow(dataArray[idx] / 100, 3);
    51                     dataProvider.push([x, y, Math.max(val, 0.1)]);
    52                 }
    53                 var musdata = [];
    54                 for (var i = 0; i < dataProvider.length; i++) {
    55                     var d = dataProvider[i];
    56                     var x = d[0],
    57                         y = d[1],
    58                         z = d[2];
    59                     var lng = minLng + x * averageLng;
    60                     var lat = minLat + y * averageLat;
    61                     var height = z * scale;
    62                     if (height < 2000) continue;
    63                     musdata.push({
    64                         // name: Math.random() * 10000,
    65                         value: [lng, lat, height]
    66                     });
    67                 }
    68                 addBars(musdata);
    69 
    70                 setTimeout(update, UPDATE_DURATION);
    71             }
    72             update();
    73         }

    5. 更新数据柱状图

     1     function addBars(data) {
     2             if (bars) {
     3                 threeLayer.removeMesh(bars, false);
     4             }
     5             bars = data.map(function (d) {
     6                 var value = d.value;
     7                 minValue = Math.min(minValue, value[2]);
     8                 maxValue = Math.max(maxValue, value[2]);
     9                 const material = getMaterial(value[2]);
    10                 if (!barCache[value[2]]) {
    11                     barCache[value[2]] = threeLayer.toBox(value.slice(0, 2), {
    12                         height: value[2],
    13                         radius: 600,
    14                         topColor: '#fff',
    15                         interactive: false
    16                     }, material);
    17                 }
    18                 //复用geometry
    19                 const geometry = barCache[value[2]].getObject3d().geometry;
    20                 const options = barCache[value[2]].getOptions();
    21                 const coordinate = value.slice(0, 2);
    22                 const bar = new maptalks.BaseObject();
    23                 bar._initOptions(Object.assign({}, options, { coordinate }));
    24                 bar._createMesh(geometry, material);
    25                 const position = threeLayer.coordinateToVector3(coordinate);
    26                 bar.getObject3d().position.copy(position);
    27                 return bar;
    28             });
    29             threeLayer.addMesh(bars, false);
    30         }

    6. 显示效果

    这个动画确实是根据音乐节奏来的, 音乐可参考 ../data/roll-it-up.mp3。

    这让我想起了windowsXP自带的音乐播放器。

    7. 源码参考

    https://github.com/WhatGIS/maptalkMap

  • 相关阅读:
    用魔数防范文件上传攻击
    nginx http跳转到https
    tengine安装
    版本标记说明
    nginx基于域名的虚拟主机 反向代理配置实例
    非ROOT用户启动Tomcat
    使用druid连接池的超时回收机制排查连接泄露问题
    Jenkins入门系列之
    centos7 关闭SELINUX 防火墙
    mac安装IE浏览器
  • 原文地址:https://www.cnblogs.com/googlegis/p/14722194.html
Copyright © 2020-2023  润新知