| <!doctype html> |
| <html> |
| <head> |
| <meta charset="utf-8"> |
| <title>Globe - ECHARTS-GL</title> |
| <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no"> |
| <meta name="apple-mobile-web-app-capable" content="yes"> <!-- Fullscreen Landscape on iOS --> |
| <link rel="stylesheet" href="../common/reset.css"> |
| </head> |
| <body> |
| <div id="main"></div> |
| <script src="../common/d3-contour.js"></script> |
| <script src="../common/d3-geo.js"></script> |
| <script src="../common/d3-timer.js"></script> |
| <script src="../common/echarts.min.js"></script> |
| <script src="../common/jquery.min.js"></script> |
| <script src="../common/echarts-gl.js"></script> |
| <script src="../common/stackBlur.js"></script> |
| <script src="../common/dat.gui.js"></script> |
| <script> |
| |
| var config = { |
| color: '#c0101a', |
| levels: 50, |
| intensity: 200, |
| threshold: 0.01 |
| } |
| |
| var canvas = document.createElement('canvas'); |
| canvas.width = 4096; |
| canvas.height = 2048; |
| context = canvas.getContext("2d"); |
| |
| context.lineWidth = 0.2; |
| context.strokeStyle = config.color; |
| context.fillStyle = config.color; |
| context.shadowColor = config.color; |
| |
| var gui = new dat.GUI(); |
| |
| image("../texture/bathymetry_bw_composite_4k.jpg").then(function(image) { |
| var m = image.height, |
| n = image.width, |
| values = new Array(n * m), |
| contours = d3.contours().size([n, m]).smooth(true), |
| projection = d3.geoIdentity().scale(canvas.width / n), |
| path = d3.geoPath(projection, context); |
| |
| StackBlur.R(image, 5); |
| |
| for (var j = 0, k = 0; j < m; ++j) { |
| for (var i = 0; i < n; ++i, ++k) { |
| values[k] = image.data[(k << 2)] / 255; |
| } |
| } |
| |
| var option = { |
| image: canvas |
| } |
| |
| var results = []; |
| function update(threshold, levels) { |
| context.clearRect(0, 0, canvas.width, canvas.height); |
| var thresholds = []; |
| for (var i = 0; i < levels; i++) { |
| thresholds.push((threshold + 1 / levels * i) % 1); |
| } |
| results = contours.thresholds(thresholds)(values); |
| redraw(); |
| } |
| |
| function redraw() { |
| results.forEach(function (d, idx) { |
| context.beginPath(); |
| path(d); |
| context.globalAlpha = 1; |
| context.stroke(); |
| if (idx > config.levels / 5 * 3) { |
| context.globalAlpha = 0.01; |
| context.fill(); |
| } |
| }); |
| option.onupdate(); |
| } |
| |
| initCharts(option); |
| |
| update(config.threshold, config.levels); |
| |
| gui.add(config, 'levels', 0, 100).step(1).onFinishChange(function () { |
| update(config.threshold, config.levels); |
| }); |
| |
| gui.addColor(config, 'color').onChange(function () { |
| context.strokeStyle = context.fillStyle = context.shadowColor = config.color; |
| redraw(); |
| }); |
| }); |
| |
| function image(url) { |
| return new Promise(function(resolve) { |
| var image = new Image; |
| image.src = url; |
| image.onload = function() { |
| var canvas = document.createElement("canvas"); |
| canvas.width = image.width / 4; |
| canvas.height = image.height / 4; |
| var context = canvas.getContext("2d"); |
| context.drawImage(image, 0, 0, canvas.width, canvas.height); |
| resolve(context.getImageData(0, 0, canvas.width, canvas.height)); |
| }; |
| }); |
| } |
| |
| |
| function initCharts(option) { |
| var chart = echarts.init(document.getElementById('main')); |
| |
| var contourChart = echarts.init(document.createElement('canvas'), null, { |
| width: 4096, |
| height: 2048 |
| }); |
| |
| var img = new echarts.graphic.Image({ |
| style: { |
| image: option.image, |
| x: -1, |
| y: -1, |
| width: option.image.width + 2, |
| height: option.image.height + 2 |
| } |
| }); |
| contourChart.getZr().add(img); |
| |
| option.onupdate = function () { |
| img.dirty(); |
| } |
| |
| // https://www.behance.net/gallery/50293671/T-GLOBEhttps://bl.ocks.org/mbostock/818053c76d79d4841790c332656bf9da |
| |
| chart.setOption({ |
| globe: { |
| |
| environment: '../texture/starfield.jpg', |
| |
| heightTexture: '../texture/bathymetry_bw_composite_4k.jpg', |
| |
| displacementScale: 0.05, |
| displacementQuality: 'high', |
| |
| baseColor: '#111', |
| |
| shading: 'realistic', |
| realisticMaterial: { |
| roughness: 0.2, |
| metalness: 0 |
| }, |
| |
| postEffect: { |
| enable: true, |
| bloom: { |
| intensity: 0.05 |
| } |
| }, |
| temporalSuperSampling: { |
| enable: true |
| }, |
| light: { |
| ambient: { |
| intensity: 0 |
| }, |
| main: { |
| intensity: 0.1, |
| shadow: false |
| }, |
| ambientCubemap: { |
| texture: '../texture/lake.hdr', |
| exposure: 1, |
| diffuseIntensity: 0.5, |
| specularIntensity: 2 |
| } |
| }, |
| viewControl: { |
| autoRotate: false |
| }, |
| |
| layers: [{ |
| type: 'blend', |
| blendTo: 'albedo', |
| texture: contourChart, |
| intensity: config.intensity |
| }] |
| } |
| }); |
| |
| window.addEventListener('resize', function () { |
| chart.resize(); |
| }); |
| } |
| </script> |
| </body> |
| </html> |