8
.babelrc
|
@ -3,12 +3,6 @@
|
|||
"transform-remove-strict-mode"
|
||||
],
|
||||
"presets": [
|
||||
[
|
||||
"env",
|
||||
{
|
||||
"loose": true,
|
||||
"modules": false
|
||||
}
|
||||
]
|
||||
"@babel/preset-env"
|
||||
]
|
||||
}
|
||||
|
|
|
@ -6,3 +6,4 @@ mocks/
|
|||
node_modules/
|
||||
demos/assets/
|
||||
demos/index.html
|
||||
demos/*
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
const path = require('path');
|
||||
|
||||
module.exports = {
|
||||
babelrc: {
|
||||
presets: [
|
||||
'es2015',
|
||||
'stage-0'
|
||||
],
|
||||
sourceMaps: 'inline'
|
||||
"@babel/preset-env"
|
||||
]
|
||||
},
|
||||
extensions: ['.js'],
|
||||
include: [
|
||||
'node_modules/**/src/gl-matrix/**/*.js '
|
||||
'src/**/*.js',
|
||||
'test/**/*.js',
|
||||
'node_modules/three/**/*.js'
|
||||
],
|
||||
exclude: [
|
||||
'bower_components/**/*.js',
|
||||
'node_modules/@babel/**/*.js'
|
||||
]
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
<meta name="geometry" content="diagram">
|
||||
<link rel="stylesheet" href="./assets/common.css">
|
||||
<link rel="stylesheet" href="./assets/info.css">
|
||||
<title>point_circle</title>
|
||||
<style>
|
||||
#map { position:absolute; top:0; bottom:0; width:100%; }
|
||||
|
@ -14,40 +15,95 @@
|
|||
|
||||
<body>
|
||||
<div id="map"></div>
|
||||
<div class='info-panel top-right'>
|
||||
<h4>杭州市微博签到数据</h4>
|
||||
<p>
|
||||
<label>min</label><input name="minaqi" type="range" step="1" min="0" max="30000" value=500> <label>500</label>
|
||||
</p>
|
||||
<p>
|
||||
<label>max</label><input name="maxaqi" type="range" step="1" min="0" max="30000" value=30000><label>30000</label>
|
||||
</p>
|
||||
<p><label>color</label><select>
|
||||
<option value ="blue">blue</option>
|
||||
<option value ="red">red</option>
|
||||
<option value="orange">orange</option>
|
||||
<option value="green">green</option>
|
||||
<option value="yellow">yellow</option>
|
||||
<option value="purple">purple</option>
|
||||
</select> </p>
|
||||
<p><label>shape</label><select>
|
||||
<option value ="circle">circle</option>
|
||||
<option value ="triangle">triangle</option>
|
||||
<option value="hexagon">hexagon</option>
|
||||
<option value="square">square</option>
|
||||
</select> </p>
|
||||
<div>
|
||||
<script src="https://webapi.amap.com/maps?v=1.4.8&key=15cd8a57710d40c9b7c0e3cc120f1200&plugin=Map3D"></script>
|
||||
<script src="./assets/jquery-3.2.1.min.js"></script>
|
||||
<script src="./assets/dat.gui.min.js"></script>
|
||||
<script src="../build/L7.js"></script>
|
||||
<script>
|
||||
const colorObj ={
|
||||
blue: ["#E8FCFF", "#CFF6FF", "#A1E9ff", "#65CEF7", "#3CB1F0", "#2894E0", "#1772c2", "#105CB3", "#0D408C", "#002466"].reverse(),
|
||||
red: ["#FFF4F2", "#FFDFDB", "#FAADAA", "#F77472", "#F04850", "#D63147", "#BD223E", "#A81642", "#820C37", "#5C0023"].reverse(),
|
||||
orange:["#FFF7EB", "#FFECD4", "#FAD09D", "#F7B16A", "#F08D41", "#DB6C2C", "#C2491D", "#AD2B11", "#871D0C", "#610800"].reverse(),
|
||||
green:["#FAFFF0", "#EBF7D2", "#C8E695", "#A5D660", "#7DC238", "#59A616", "#3F8C0B", "#237804", "#125200", "#082B00"].reverse(),
|
||||
yellow:["#FFFFE8", "#FFFECC", "#FAF896", "#F7E463", "#F0CE3A", "#DBB125", "#C29117", "#AD7410", "#87500C", "#613000"].reverse(),
|
||||
purple:["#FCF2FF", "#F5DEFF", "#DDB3F2", "#BE7BE3", "#9B4ECF", "#7737B3", "#5B2899", "#411C85", "#270F5E", "#100338"].reverse()
|
||||
}
|
||||
|
||||
|
||||
const color1 = [ 'rgba(37, 140, 249, 0.8)', 'rgba(14, 241, 242, 0.8)', 'rgba(255, 255, 255, 0.8)' ];
|
||||
const scene = new L7.Scene({
|
||||
id: 'map',
|
||||
mapStyle: 'amap://styles/5a64d4f1af910091f9cc3367dfc4a1dc', // 样式URL
|
||||
mapStyle: 'light', // 样式URL
|
||||
center: [ 120.19382669582967, 30.258134 ],
|
||||
pitch: 0,
|
||||
zoom: 12.6
|
||||
zoom: 11.6
|
||||
});
|
||||
window.scene = scene;
|
||||
scene.on('load', () => {
|
||||
scene.on('loaded', () => {
|
||||
$.get('https://gw.alipayobjects.com/os/rmsportal/epnZEheZeDgsiSjSPcCv.json', data => {
|
||||
scene.PointLayer({
|
||||
const circleLayer = scene.PointLayer({
|
||||
zIndex: 2
|
||||
})
|
||||
.source(data)
|
||||
.shape('2d:circle')
|
||||
.size('value', [ 8, 80 ]) // default 1
|
||||
.filter('value', field_8 => {
|
||||
return field_8 * 1 > 500;
|
||||
.source(data,{
|
||||
scale:{
|
||||
min:0,
|
||||
max:1000,
|
||||
type:'linear'
|
||||
}
|
||||
})
|
||||
.color('type', [ '#002466', '#0D408C', '#105CB3', '#1A76C7', '#2894E0', '#3CB4F0', '#65CEF7', '#98E3FA', '#CFF6FF', '#E8FCFF' ])
|
||||
.shape('2d:circle')
|
||||
.size('value', [ 0, 60]) // default 1
|
||||
//.size('value', [ 10, 300]) // default 1
|
||||
.active(true)
|
||||
.filter('value', field_8 => {
|
||||
return field_8 * 1 > 500;
|
||||
})
|
||||
.color('type', colorObj.red)
|
||||
.style({
|
||||
stroke: 'rgb(255,255,255)',
|
||||
strokeWidth: 1,
|
||||
opacity: 0.9
|
||||
})
|
||||
.render();
|
||||
$('.info-panel input').change(function(){
|
||||
$(this).next().text($(this).val());
|
||||
const min = $('.info-panel input').val();
|
||||
const max = $($('.info-panel input')[1]).val();
|
||||
circleLayer.filter('value',(value)=>{
|
||||
return (value>=min && value<=max)
|
||||
}).render();
|
||||
})
|
||||
$('.info-panel select').change(function(){
|
||||
const color = $(this).val();
|
||||
console.time('color');
|
||||
circleLayer.color('type',colorObj[color]).render();
|
||||
console.timeEnd('color')
|
||||
})
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
</script>
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
<meta name="geometry" content="diagram">
|
||||
<link rel="stylesheet" href="./assets/common.css">
|
||||
<title>point_circle</title>
|
||||
<style>
|
||||
#map { position:absolute; top:0; bottom:0; width:100%; }
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="map"></div>
|
||||
<script src="https://webapi.amap.com/maps?v=1.4.8&key=15cd8a57710d40c9b7c0e3cc120f1200&plugin=Map3D"></script>
|
||||
<script src="./assets/jquery-3.2.1.min.js"></script>
|
||||
<script src="./assets/dat.gui.min.js"></script>
|
||||
<script src="../build/L7.js"></script>
|
||||
<script>
|
||||
|
||||
const scene = new L7.Scene({
|
||||
id: 'map',
|
||||
mapStyle: 'dark', // 样式URL
|
||||
center: [ 120.037828998113099, 30.086317611850635 ],
|
||||
pitch: 36.002858,
|
||||
zoom: 5.44
|
||||
});
|
||||
window.scene = scene;
|
||||
scene.on('loaded', () => {
|
||||
$.get('./data/rainfall.json', data => {
|
||||
scene.PointLayer({
|
||||
zIndex: 2
|
||||
})
|
||||
.source(data.list, {
|
||||
type: 'array',
|
||||
x: 'j',
|
||||
y: 'w',
|
||||
})
|
||||
.shape('3d:circle')
|
||||
.size('t',(level)=> {
|
||||
return [4,4,(level+40)];
|
||||
})
|
||||
.active(true)
|
||||
.color('t', ["#002466","#105CB3","#2894E0","#CFF6FF","#FFF5B8","#FFAB5C","#F27049","#730D1C"])
|
||||
.render();
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -19,18 +19,17 @@
|
|||
<script src="./assets/dat.gui.min.js"></script>
|
||||
<script src="../build/L7.js"></script>
|
||||
<script>
|
||||
|
||||
const color1 = [ 'rgba(37, 140, 249, 0.8)', 'rgba(14, 241, 242, 0.8)', 'rgba(255, 255, 255, 0.8)' ];
|
||||
const scene = new L7.Scene({
|
||||
id: 'map',
|
||||
mapStyle: 'amap://styles/5a64d4f1af910091f9cc3367dfc4a1dc', // 样式URL
|
||||
mapStyle: 'dark', // 样式URL
|
||||
center: [ 121.51222019389274, 31.23572578718841 ],
|
||||
pitch: 0,
|
||||
zoom: 11
|
||||
});
|
||||
window.scene = scene;
|
||||
scene.on('load', () => {
|
||||
$.get('https://gw.alipayobjects.com/os/rmsportal/mUQPWCYaxOfiSznuANvG.txt', data => {
|
||||
scene.on('loaded', () => {
|
||||
// ./data/mUQPWCYaxOfiSznuANvG.txt
|
||||
$.get('./data/00.csv', data => {
|
||||
scene.PointLayer({
|
||||
zIndex: 2
|
||||
})
|
||||
|
@ -39,33 +38,8 @@ scene.on('load', () => {
|
|||
y: 'lat',
|
||||
x: 'lng'
|
||||
})
|
||||
.shape('2d:circle')
|
||||
.size(2.0)
|
||||
/**
|
||||
.size('name*zoom', function(name, zoom) {
|
||||
if (zoom < 7) {
|
||||
return 1;
|
||||
} else if (zoom < 9) {
|
||||
return 10;
|
||||
} else if (zoom < 12) {
|
||||
return 15;
|
||||
}
|
||||
return 50;
|
||||
|
||||
})
|
||||
|
||||
.color('count', function(count) {
|
||||
if (count < 3) {
|
||||
return color1[0];
|
||||
} else if (count < 15) {
|
||||
return color1[1];
|
||||
}
|
||||
return color1[2];
|
||||
|
||||
|
||||
})
|
||||
**/
|
||||
.color('#0198BD')
|
||||
.size(1.0)
|
||||
.color('#0D408C')
|
||||
.style({
|
||||
stroke: 'rgb(255,255,255)',
|
||||
strokeWidth: 0,
|
||||
|
|
|
@ -0,0 +1,137 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
<meta name="geometry" content="diagram">
|
||||
<link rel="stylesheet" href="./assets/common.css">
|
||||
<link rel="stylesheet" href="./assets/info.css">
|
||||
<title>point_distribute</title>
|
||||
<style>
|
||||
body {
|
||||
margin:0px;
|
||||
}
|
||||
#map { position:absolute; top:0; bottom:0; width:100%; }
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="map"></div>
|
||||
<div class ='info'>
|
||||
<div class="input-card" style='width: 12rem;'>
|
||||
<div class="input-item">
|
||||
<input type="radio" name='func' checked=true value=0><span class="input-text">全部</span>
|
||||
<input type="radio" name='func' value=0><span class="input-text">可用车</span>
|
||||
<input type="radio" name='func' value=1><span class="input-text">不可用</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="https://webapi.amap.com/maps?v=1.4.8&key=15cd8a57710d40c9b7c0e3cc120f1200&plugin=Map3D"></script>
|
||||
<script src="https://unpkg.com/supercluster@4.1.1/dist/supercluster.min.js"></script>
|
||||
<script src="./assets/jquery-3.2.1.min.js"></script>
|
||||
<script src="../build/L7.js"></script>
|
||||
<script>
|
||||
|
||||
const scene = new L7.Scene({
|
||||
id: 'map',
|
||||
mapStyle: 'light', // 样式URL
|
||||
center: [ 120.1243238, 30.27331571 ],
|
||||
pitch: 0,
|
||||
zoom: 14,
|
||||
minZoom: 9
|
||||
});
|
||||
window.scene = scene;
|
||||
scene.on('loaded', () => {
|
||||
|
||||
$.get('./data/pointbike.json', data => {
|
||||
var extent = [ 110,29.2378,122.189,33.3173]
|
||||
var dataindex = supercluster({radius:80});
|
||||
dataindex.load(data.features);
|
||||
|
||||
var clusterData = dataindex.getClusters(extent,13);
|
||||
scene.PointLayer({
|
||||
zIndex: 4,
|
||||
maxZoom:15.5
|
||||
})
|
||||
.source({
|
||||
"type": "FeatureCollection",
|
||||
"features":clusterData
|
||||
})
|
||||
.color('#6492E9')
|
||||
.size('point_count',[1,30])
|
||||
.shape('2d:circle')
|
||||
.style({
|
||||
opacity:0.8
|
||||
})
|
||||
.render();
|
||||
|
||||
// 自行车数据
|
||||
scene.PointLayer({
|
||||
zIndex: 4,
|
||||
minZoom:15.5,
|
||||
|
||||
})
|
||||
.source(data)
|
||||
.color('power',(v)=>{
|
||||
return v > 5 ? '#4F93EA' :'#F5684A'
|
||||
})
|
||||
.active({fill:'#91C25B'})
|
||||
.size(8)
|
||||
.shape('2d:circle')
|
||||
.style({
|
||||
opacity:1.0
|
||||
})
|
||||
.render();
|
||||
|
||||
});
|
||||
|
||||
$.get('./data/fence.json', data => {
|
||||
scene.LineLayer({
|
||||
zIndex: 5
|
||||
})
|
||||
.source(data)
|
||||
.shape('line')
|
||||
.size([2,0])
|
||||
.color('#2F54EB')
|
||||
.style({
|
||||
opacity:1.0,
|
||||
})
|
||||
.render();
|
||||
scene.PolygonLayer({
|
||||
zIndex: 0
|
||||
})
|
||||
.source(data)
|
||||
.shape('fill')
|
||||
.size([2,0])
|
||||
.color('#2F54EB')
|
||||
.style({
|
||||
opacity:0.05,
|
||||
})
|
||||
.render();
|
||||
});
|
||||
|
||||
|
||||
$.getJSON('./data/pointZone.json', data => {
|
||||
const fenceLayer = scene.LineLayer({
|
||||
zIndex: 1,
|
||||
minZoom:16,
|
||||
})
|
||||
.source(data)
|
||||
.size([1.5,0])
|
||||
.shape('line')
|
||||
.color("#2F54EB")
|
||||
.style({
|
||||
opacity:1.0,
|
||||
})
|
||||
.render();
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -17,34 +17,34 @@
|
|||
<script src="https://webapi.amap.com/maps?v=1.4.8&key=15cd8a57710d40c9b7c0e3cc120f1200&plugin=Map3D"></script>
|
||||
<script src="./assets/jquery-3.2.1.min.js"></script>
|
||||
<script src="./assets/dat.gui.min.js"></script>
|
||||
<script src="./assets/geotiff.browserify.min.js"></script>
|
||||
<script src="../build/L7.js"></script>
|
||||
<script>
|
||||
|
||||
const color1 = [ 'rgba(37, 140, 249, 0.8)', 'rgba(14, 241, 242, 0.8)', 'rgba(255, 255, 255, 0.8)' ];
|
||||
const scene = new L7.Scene({
|
||||
id: 'map',
|
||||
mapStyle: 'amap://styles/5a64d4f1af910091f9cc3367dfc4a1dc', // 样式URL
|
||||
center: [ 116.2825, 39.9 ],
|
||||
pitch: 0,
|
||||
zoom: 3
|
||||
mapStyle: 'dark', // 样式URL
|
||||
center: [ 102.615023, 23.107799],
|
||||
pitch: 15,
|
||||
zoom: 14,
|
||||
});
|
||||
scene.on('load', () => {
|
||||
$.get('https://gw.alipayobjects.com/os/rmsportal/UEXQMifxtkQlYfChpPwT.txt', data => {
|
||||
scene.on('loaded', () => {
|
||||
$.get('./data/contour.geojson', data => {
|
||||
// data.features = data.features.slice(0,1);
|
||||
scene.LineLayer({
|
||||
zIndex: 2
|
||||
})
|
||||
.source(data, { // lng1,lat1,lng2,lat2
|
||||
type: 'csv',
|
||||
x: 'lng1',
|
||||
y: 'lat1',
|
||||
x1: 'lng2',
|
||||
y1: 'lat2'
|
||||
})
|
||||
.shape('arc')
|
||||
.size(2.0)
|
||||
.color('value', [ '#002466', '#0D408C', '#105CB3', '#1A76C7', '#2894E0', '#3CB4F0', '#65CEF7', '#98E3FA', '#CFF6FF', '#E8FCFF' ])
|
||||
.source(data)
|
||||
.size('ELEV',(value)=>{
|
||||
return [1,(value-1000)*7];
|
||||
})
|
||||
.active(true)
|
||||
.shape('line')
|
||||
.color('ELEV',["#E8FCFF", "#CFF6FF", "#A1E9ff", "#65CEF7", "#3CB1F0", "#2894E0", "#1772c2", "#105CB3", "#0D408C", "#002466"].reverse())
|
||||
.render();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
</script>
|
|
@ -0,0 +1,107 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
<meta name="geometry" content="diagram">
|
||||
<link rel="stylesheet" href="./assets/common.css">
|
||||
<title>one belt one road </title>
|
||||
<style>
|
||||
#map { position:absolute; top:0; bottom:0; width:100%; }
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="map"></div>
|
||||
<script src="https://webapi.amap.com/maps?v=1.4.8&key=15cd8a57710d40c9b7c0e3cc120f1200&plugin=Map3D"></script>
|
||||
<script src="./assets/jquery-3.2.1.min.js"></script>
|
||||
<script src="./assets/dat.gui.min.js"></script>
|
||||
<script src="../build/L7.js"></script>
|
||||
<script>
|
||||
const scene = new L7.Scene({
|
||||
id: 'map',
|
||||
mapStyle: 'light', // 样式URL
|
||||
center: [ 120.3672, 36.0968 ],
|
||||
pitch: 0,
|
||||
zoom: 3
|
||||
});
|
||||
|
||||
scene.on('loaded', () => {
|
||||
scene.image.addImage('marker', './data/onebelt/marker.png');
|
||||
scene.image.addImage('local', './image/local.png');
|
||||
|
||||
|
||||
$.getJSON('./data/onebelt/regions.json', region => {
|
||||
const color = [ 'rgb(22,32,101)', 'rgb(28,43,127)', 'rgb(36,68,142)', 'rgb(45,94,158)', 'rgb(53,119,174)', 'rgb(61,145,190)', 'rgb(70,170,206)', 'rgb(98,190,210)', 'rgb(138,205,206)', 'rgb(179,221,204)', 'rgb(220,236,201)' ];
|
||||
var points = region.features.map((feature)=>{
|
||||
return feature.properties;
|
||||
})
|
||||
|
||||
const layer = scene.PolygonLayer({
|
||||
zIndex:1,
|
||||
})
|
||||
.source(region)
|
||||
.color('cname',(value)=>{
|
||||
return (value =='中国' ? 'rgba(46,149,169,0.45)': 'rgba(227,244,244,0.1)');
|
||||
})
|
||||
.shape('fill')
|
||||
.render();
|
||||
});
|
||||
$.getJSON('./data/onebelt/seaway.geojson', contourData => {
|
||||
|
||||
const layer = scene.LineLayer({
|
||||
zIndex:2}
|
||||
)
|
||||
.source(contourData)
|
||||
.color('rgb(79,147,234)')
|
||||
.size([ 1.5, 0 ])
|
||||
.shape('line')
|
||||
.style({
|
||||
'lineType':'solid'
|
||||
})
|
||||
.render();
|
||||
});
|
||||
$.getJSON('./data/onebelt/landway.json', contourData => {
|
||||
const landlayer = scene.LineLayer(
|
||||
{zIndex:2}
|
||||
)
|
||||
.source(contourData)
|
||||
.color('rgb(11,94,69)')
|
||||
.size([ 1.5, 0 ])
|
||||
.shape('line')
|
||||
.style({
|
||||
// 'lineType':'solid'
|
||||
})
|
||||
.render();
|
||||
});
|
||||
$.getJSON('./data/onebelt/city.geojson', city => {
|
||||
var makerLayer = scene.PointLayer({
|
||||
zIndex: 4
|
||||
})
|
||||
.source(city)
|
||||
.size(20.0)
|
||||
.shape('image:local')
|
||||
.color('#0D408C')
|
||||
.render();
|
||||
|
||||
var makerText = scene.PointLayer({
|
||||
zIndex: 8,
|
||||
minZoom:5,
|
||||
})
|
||||
.source(city)
|
||||
.size(14.0)
|
||||
.shape('name', 'text')
|
||||
.color('rgba(0,0,0,0.85)')
|
||||
.style({
|
||||
textOffset:[-20,22],
|
||||
stroke: '#fff',
|
||||
strokeWidth: 4,
|
||||
})
|
||||
.render();
|
||||
})
|
||||
|
||||
})
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -21,34 +21,41 @@
|
|||
<script src="./assets/dat.gui.min.js"></script>
|
||||
<script src="../build/L7.js"></script>
|
||||
<script>
|
||||
const gui = new dat.GUI({ autoPlace: false });
|
||||
const customContainer = document.getElementById('gui');
|
||||
customContainer.appendChild(gui.domElement);
|
||||
const province = { 全国: '00', 新疆维吾尔自治区: '65', 西藏自治区: '54', 内蒙古自治区: '15', 青海省: '63', 四川省: '51', 黑龙江省: '23', 甘肃省: '62', 云南省: '53', 广西壮族自治区: '45', 湖南省: '43', 陕西省: '61', 广东省: '44', 吉林省: '22', 河北省: '13', 湖北省: '42', 贵州省: '52', 山东省: '37', 江西省: '36', 河南省: '41', 辽宁省: '21', 山西省: '14', 安徽省: '34', 福建省: '35', 浙江省: '33', 江苏省: '32', 重庆市: '50', 宁夏回族自治区: '64', 海南省: '46', 台湾省: '71', 北京市: '11', 天津市: '12', 上海市: '31', 香港特别行政区: '81', 澳门特别行政区: '82' };
|
||||
const scene = new L7.Scene({
|
||||
id: 'map',
|
||||
mapStyle: 'amap://styles/5a64d4f1af910091f9cc3367dfc4a1dc', // 样式URL
|
||||
mapStyle: 'dark', // 样式URL
|
||||
center: [ 120.4047, 30.0679 ],
|
||||
pitch: 35,
|
||||
zoom: 4
|
||||
|
||||
});
|
||||
window.scene = scene;
|
||||
scene.on('load', () => {
|
||||
$.getJSON('https://gw.alipayobjects.com/os/rmsportal/oOzMjBOaxFROWLBYeqTB.json', city => {
|
||||
scene.on('loaded', () => {
|
||||
$.getJSON('./data/chinandvohexagon.geojson', city => {
|
||||
citylayer = scene.PolygonLayer()
|
||||
.source(city)
|
||||
.color('gdp', [ '#002466', '#0D408C', '#105CB3', '#1A76C7', '#2894E0', '#3CB4F0', '#65CEF7', '#98E3FA', '#CFF6FF', '#E8FCFF' ])
|
||||
.color('sum', ["#FAFFF0", "#EBF7D2", "#C8E695", "#A5D660", "#7DC238", "#59A616", "#3F8C0B", "#237804", "#125200", "#082B00"])
|
||||
.shape('extrude')
|
||||
.filter('gdp', gdp => {
|
||||
return gdp > 0;
|
||||
|
||||
.size('max',(value)=>{
|
||||
return value * 1000;
|
||||
})
|
||||
.size('gdp', [ 1000, 5000000 ])
|
||||
// .active({ fill: 'red' })
|
||||
.active(true)
|
||||
.style({
|
||||
opacity: 1
|
||||
opacity: 1.0
|
||||
})
|
||||
.render();
|
||||
|
||||
|
||||
const citylayer2 = scene.PolygonLayer()
|
||||
.source(city)
|
||||
.shape('line')
|
||||
.color('#fff')
|
||||
.style({
|
||||
opacity: 1
|
||||
})
|
||||
.render();
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -6,46 +6,82 @@
|
|||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
<meta name="geometry" content="diagram">
|
||||
<link rel="stylesheet" href="./assets/common.css">
|
||||
<link rel="stylesheet" href="./assets/info.css">
|
||||
|
||||
<title>hexagon demo</title>
|
||||
<style>
|
||||
body {margin: 0;}
|
||||
#map { position:absolute; top:0; bottom:0; width:100%; }
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id = 'gui' style="position:absolute;top:0px;right:0px;z-index:2;"></div>
|
||||
<div id="map"></div>
|
||||
<div id ="info" class ="tooltip" style="display:none">
|
||||
</div>
|
||||
<script src="https://webapi.amap.com/maps?v=1.4.8&key=15cd8a57710d40c9b7c0e3cc120f1200&plugin=Map3D"></script>
|
||||
<script src="./assets/jquery-3.2.1.min.js"></script>
|
||||
<script src="./assets/dat.gui.min.js"></script>
|
||||
<script src="../build/L7.js"></script>
|
||||
<script>
|
||||
const gui = new dat.GUI({ autoPlace: false });
|
||||
const customContainer = document.getElementById('gui');
|
||||
customContainer.appendChild(gui.domElement);
|
||||
const province = { 全国: '00', 新疆维吾尔自治区: '65', 西藏自治区: '54', 内蒙古自治区: '15', 青海省: '63', 四川省: '51', 黑龙江省: '23', 甘肃省: '62', 云南省: '53', 广西壮族自治区: '45', 湖南省: '43', 陕西省: '61', 广东省: '44', 吉林省: '22', 河北省: '13', 湖北省: '42', 贵州省: '52', 山东省: '37', 江西省: '36', 河南省: '41', 辽宁省: '21', 山西省: '14', 安徽省: '34', 福建省: '35', 浙江省: '33', 江苏省: '32', 重庆市: '50', 宁夏回族自治区: '64', 海南省: '46', 台湾省: '71', 北京市: '11', 天津市: '12', 上海市: '31', 香港特别行政区: '81', 澳门特别行政区: '82' };
|
||||
const colorObj ={
|
||||
blue: ["#E8FCFF", "#CFF6FF", "#98E3FA", "#65CEF7", "#3CB4F0", "#2894E0", "#1A76C7", "#105CB3", "#0D408C", "#002466"],
|
||||
red: ["#FFF4F2", "#FFDFDB", "#FAADAA", "#F77472", "#F04850", "#D63147", "#BD223E", "#A81642", "#820C37", "#5C0023"],
|
||||
orange:["#FFF7EB", "#FFECD4", "#FAD09D", "#F7B16A", "#F08D41", "#DB6C2C", "#C2491D", "#AD2B11", "#871D0C", "#610800"],
|
||||
green:["#FAFFF0", "#EBF7D2", "#C8E695", "#A5D660", "#7DC238", "#59A616", "#3F8C0B", "#237804", "#125200", "#082B00"],
|
||||
yellow:["#FFFFE8", "#FFFECC", "#FAF896", "#F7E463", "#F0CE3A", "#DBB125", "#C29117", "#AD7410", "#87500C", "#613000"],
|
||||
purple:["#FCF2FF", "#F5DEFF", "#DDB3F2", "#BE7BE3", "#9B4ECF", "#7737B3", "#5B2899", "#411C85", "#270F5E", "#100338"],
|
||||
}
|
||||
|
||||
const scene = new L7.Scene({
|
||||
id: 'map',
|
||||
mapStyle: 'amap://styles/5a64d4f1af910091f9cc3367dfc4a1dc', // 样式URL
|
||||
mapStyle: 'light', // 样式URL
|
||||
center: [ 120.4047, 30.0679 ],
|
||||
pitch: 0,
|
||||
zoom: 4
|
||||
|
||||
});
|
||||
window.scene = scene;
|
||||
scene.on('load', () => {
|
||||
|
||||
scene.on('loaded', () => {
|
||||
var colors = ["#FFF5B8","#FFDC7D","#FFAB5C","#F27049","#D42F31","#730D1C"];
|
||||
$.getJSON('https://gw.alipayobjects.com/os/rmsportal/JToMOWvicvJOISZFCkEI.json', city => {
|
||||
citylayer = scene.PolygonLayer()
|
||||
const citylayer = scene.PolygonLayer()
|
||||
.source(city)
|
||||
.color('pm2_5_24h', [ '#002466', '#0D408C', '#105CB3', '#1A76C7', '#2894E0', '#3CB4F0', '#65CEF7', '#98E3FA', '#CFF6FF', '#E8FCFF' ])
|
||||
//.color('pm2_5_24h',["#FFF5B8","#FFDC7D","#FFAB5C","#F27049","#D42F31","#730D1C"])
|
||||
.color('pm2_5_24h',(p)=>{
|
||||
if(p>120){
|
||||
return colors[5];
|
||||
} else if(p>65){
|
||||
return colors[4];
|
||||
} else if(p>30) {
|
||||
return colors[3];
|
||||
} else if(p>15){
|
||||
return colors[2];
|
||||
} else if(p>8){
|
||||
return colors[1];
|
||||
}else {
|
||||
return colors[0];
|
||||
}
|
||||
})
|
||||
.shape('fill')
|
||||
// .active({ fill: 'red' })
|
||||
.active(true)
|
||||
.style({
|
||||
opacity: 1
|
||||
})
|
||||
.render();
|
||||
const citylayer2 = scene.PolygonLayer()
|
||||
.source(city)
|
||||
.shape('line')
|
||||
.color('#fff')
|
||||
.style({
|
||||
opacity: 0.1
|
||||
})
|
||||
.render();
|
||||
|
||||
citylayer.on('click',(e)=>{
|
||||
$("#info").css({'left': e.pixel.x,'top':e.pixel.y, display:'block'});
|
||||
$("#info").html(`<p>${e.feature.properties.area || e.feature.properties.name }<span">${e.feature.properties.pm2_5_24h || 0}</span></p>`);
|
||||
})
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -14,30 +14,32 @@
|
|||
</head>
|
||||
|
||||
<body>
|
||||
<div id = 'gui' style="position:absolute;top:0px;right:0px;z-index:2;"></div>
|
||||
<div id="map"></div>
|
||||
<script src="https://webapi.amap.com/maps?v=1.4.8&key=15cd8a57710d40c9b7c0e3cc120f1200&plugin=Map3D"></script>
|
||||
<script src="./assets/jquery-3.2.1.min.js"></script>
|
||||
<script src="./assets/dat.gui.min.js"></script>
|
||||
<script src="../build/L7.js"></script>
|
||||
<script>
|
||||
const gui = new dat.GUI({ autoPlace: false });
|
||||
const customContainer = document.getElementById('gui');
|
||||
customContainer.appendChild(gui.domElement);
|
||||
|
||||
const scene = new L7.Scene({
|
||||
id: 'map',
|
||||
mapStyle: 'amap://styles/ba3e9759545cd618392ef073c0dfda8c?isPublic=true', // 样式URL
|
||||
center: [ 120.4047, 30.0679 ],
|
||||
pitch: 45,
|
||||
zoom: 4
|
||||
mapStyle: 'dark', // 样式URL
|
||||
center: [ 121.2680, 30.3628 ],
|
||||
pitch: 0,
|
||||
zoom: 15,
|
||||
minZoom: 4,
|
||||
maxZoom: 18
|
||||
});
|
||||
|
||||
scene.on('load', () => {
|
||||
scene.on('loaded', () => {
|
||||
// https://gw.alipayobjects.com/zos/rmsportal/wAQqmdcWOPdomuKUyHDF.png
|
||||
//
|
||||
const imageLayer = scene.ImageLayer().
|
||||
source({
|
||||
url: 'https://gw.alipayobjects.com/zos/rmsportal/wAQqmdcWOPdomuKUyHDF.png',
|
||||
extent: [ 73, 18, 136, 54 ]
|
||||
source('./image/hangzhoubay.jpg',{
|
||||
|
||||
extent: [ 121.1680, 30.2828, 121.3840, 30.4219 ]
|
||||
})
|
||||
.style({
|
||||
opacity:1.0,
|
||||
})
|
||||
.render();
|
||||
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
<meta name="geometry" content="diagram">
|
||||
<link rel="stylesheet" href="./assets/common.css">
|
||||
|
||||
<title>dem demo</title>
|
||||
<style>
|
||||
#map { position:absolute; top:0; bottom:0; width:100%; }
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id = 'gui' style="position:absolute;top:0px;right:0px;z-index:2;"></div>
|
||||
<div id="map"></div>
|
||||
<script src="https://webapi.amap.com/maps?v=1.4.8&key=15cd8a57710d40c9b7c0e3cc120f1200&plugin=Map3D"></script>
|
||||
<script src="./assets/jquery-3.2.1.min.js"></script>
|
||||
<script src="./assets/geotiff.browserify.min.js"></script>
|
||||
<script src="../build/L7.js"></script>
|
||||
<script>
|
||||
|
||||
const scene = new L7.Scene({
|
||||
id: 'map',
|
||||
viewMode: '3D',
|
||||
mapStyle: 'amap://styles/ba3e9759545cd618392ef073c0dfda8c?isPublic=true', // 样式URL
|
||||
center: [ 110.770672, 34.159869 ],
|
||||
pitch: 0,
|
||||
zoom: 4
|
||||
});
|
||||
|
||||
scene.on('loaded', () => {
|
||||
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhr.open('GET', ' https://gw.alipayobjects.com/os/rmsportal/XKgkjjGaAzRyKupCBiYW.dat', true);
|
||||
xhr.responseType = 'arraybuffer';
|
||||
xhr.onload = function(e) {
|
||||
if (this.status === 200) {
|
||||
// get binary data as a response
|
||||
const blob = this.response;
|
||||
const tiff = GeoTIFF.parse(blob);
|
||||
const image = tiff.getImage();
|
||||
const values = image.readRasters()[0];
|
||||
const m = image.getHeight();
|
||||
const n = image.getWidth();
|
||||
|
||||
const layer = scene.RasterLayer({ zIndex: 2 }).
|
||||
source(values, {
|
||||
type: 'raster',
|
||||
width: n,
|
||||
height: m,
|
||||
min: 0,
|
||||
max: 8000,
|
||||
extent: [ 73.482190241, 3.82501784112, 135.106618732, 57.6300459963 ]
|
||||
|
||||
})
|
||||
.style({
|
||||
rampColors: {
|
||||
colors: [ '#002466', '#0D408C', '#105CB3', '#1A76C7', '#2894E0', '#3CB4F0', '#65CEF7', '#98E3FA', '#CFF6FF', '#E8FCFF' ],
|
||||
positions: [ 0, 0.02, 0.05, 0.1, 0.2, 0.3, 0.5, 0.6, 0.8, 1.0 ]
|
||||
}
|
||||
})
|
||||
.render();
|
||||
}
|
||||
};
|
||||
xhr.send();
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -6,7 +6,7 @@
|
|||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
<meta name="geometry" content="diagram">
|
||||
<link rel="stylesheet" href="./assets/common.css">
|
||||
<title>hexagon demo</title>
|
||||
<title>point_circle</title>
|
||||
<style>
|
||||
#map { position:absolute; top:0; bottom:0; width:100%; }
|
||||
</style>
|
||||
|
@ -20,22 +20,29 @@
|
|||
<script src="../build/L7.js"></script>
|
||||
<script>
|
||||
|
||||
const color1 = [ 'rgba(37, 140, 249, 0.8)', 'rgba(14, 241, 242, 0.8)', 'rgba(255, 255, 255, 0.8)' ];
|
||||
const scene = new L7.Scene({
|
||||
id: 'map',
|
||||
mapStyle: 'amap://styles/5a64d4f1af910091f9cc3367dfc4a1dc', // 样式URL
|
||||
center: [ 116.2825, 39.9 ],
|
||||
mapStyle: 'dark', // 样式URL
|
||||
center: [ 120.19382669582967, 30.258134 ],
|
||||
pitch: 0,
|
||||
zoom: 3
|
||||
});
|
||||
scene.on('load', () => {
|
||||
$.get('https://gw.alipayobjects.com/os/rmsportal/lZGtNaYGNHtAIkcjVvfp.json', data => {
|
||||
scene.LineLayer({
|
||||
window.scene = scene;
|
||||
scene.on('loaded', () => {
|
||||
$.get('./data/provincePoint.geojson', data => {
|
||||
scene.PointLayer({
|
||||
zIndex: 2
|
||||
})
|
||||
.source(data)
|
||||
.color('#3CB4F0')
|
||||
.render();
|
||||
.source(data)
|
||||
.shape('name', 'text')
|
||||
.size(10) // default 1
|
||||
.color('#fff')
|
||||
.style({
|
||||
stroke: '#999',
|
||||
strokeWidth: 2,
|
||||
opacity: 0.85
|
||||
})
|
||||
.render();
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
<meta name="geometry" content="diagram">
|
||||
<link rel="stylesheet" href="./assets/common.css">
|
||||
<link rel="stylesheet" href="./assets/info.css">
|
||||
<title>city</title>
|
||||
<style>
|
||||
#map { position:absolute; top:0; bottom:0; width:100%; }
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="map">
|
||||
<div id ="info" class ="tooltip" style="display:none">
|
||||
</div>
|
||||
<script src="https://webapi.amap.com/maps?v=1.4.8&key=15cd8a57710d40c9b7c0e3cc120f1200&plugin=Map3D"></script>
|
||||
<script src="./assets/jquery-3.2.1.min.js"></script>
|
||||
<script src="../build/L7.js"></script>
|
||||
<script>
|
||||
|
||||
const scene = new L7.Scene({
|
||||
id: 'map',
|
||||
mapStyle: 'light', // 样式URL
|
||||
center: [120.173104, 30.244072],
|
||||
pitch: 66.50572,
|
||||
zoom: 15.79,
|
||||
minZoom:10
|
||||
});
|
||||
window.scene = scene;
|
||||
scene.on('loaded', () => {
|
||||
$.get('./data/water.geojson', data => {
|
||||
scene.PolygonLayer({
|
||||
zIndex: 0
|
||||
})
|
||||
.source(data)
|
||||
.shape('fill')
|
||||
.color('rgb(79,174,234)')
|
||||
.render();
|
||||
});
|
||||
$.get('./data/land.geojson', data => {
|
||||
scene.PolygonLayer({
|
||||
zIndex: 0
|
||||
})
|
||||
.source(data)
|
||||
.shape('fill')
|
||||
.color('rgb(156,194,116)')
|
||||
.render();
|
||||
});
|
||||
$.get('./data/river.geojson', data => {
|
||||
scene.LineLayer({
|
||||
zIndex: 2
|
||||
})
|
||||
.source(data)
|
||||
.shape('line')
|
||||
.size([3,0])
|
||||
.color('rgb(79,174,234)')
|
||||
.render();
|
||||
});
|
||||
|
||||
$.get('./data/build.geojson', data => {
|
||||
citylayer = scene.PolygonLayer({
|
||||
zIndex: 2
|
||||
})
|
||||
.source(data)
|
||||
.shape('extrude')
|
||||
.active({fill:'red'})
|
||||
.size('floor',[10,2000])
|
||||
.color('rgba(242,246,250,0.96)')
|
||||
.render();
|
||||
citylayer.on('click',(e)=>{
|
||||
$("#info").css({'left': e.pixel.x,'top':e.pixel.y, display:'block'});
|
||||
$("#info").html(`<p>楼高<span">${e.feature.properties.floor || 0}</span></p>`);
|
||||
})
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
<meta name="geometry" content="diagram">
|
||||
<link rel="stylesheet" href="./assets/common.css">
|
||||
<title>hexagon demo</title>
|
||||
<style>
|
||||
#map { position:absolute; top:0; bottom:0; width:100%; }
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="map"></div>
|
||||
<script src="https://webapi.amap.com/maps?v=1.4.8&key=15cd8a57710d40c9b7c0e3cc120f1200&plugin=Map3D"></script>
|
||||
<script src='https://npmcdn.com/@turf/turf/turf.min.js'></script>
|
||||
<script src="./assets/jquery-3.2.1.min.js"></script>
|
||||
<script src="./assets/dat.gui.min.js"></script>
|
||||
<script src="../build/L7.js"></script>
|
||||
<script>
|
||||
|
||||
const color1 = [ 'rgba(37, 140, 249, 0.8)', 'rgba(14, 241, 242, 0.8)', 'rgba(255, 255, 255, 0.8)' ];
|
||||
const scene = new L7.Scene({
|
||||
id: 'map',
|
||||
mapStyle: 'dark', // 样式URL
|
||||
center: [ 116.2825, 39.9 ],
|
||||
pitch: 0,
|
||||
zoom: 3
|
||||
});
|
||||
scene.on('loaded', () => {
|
||||
$.get('https://gw.alipayobjects.com/os/rmsportal/UEXQMifxtkQlYfChpPwT.txt', data => {
|
||||
const rows = data.split('\n');
|
||||
var features =[];
|
||||
for(var i =1;i<rows.length-1;i++){
|
||||
var row = rows[i].split(',');
|
||||
var start = turf.point([row[4], row[5]]);
|
||||
var end = turf.point([row[6], row[7]]);
|
||||
var greatCircle = turf.greatCircle(start, end, {'npoints': 50});
|
||||
features.push(greatCircle);
|
||||
}
|
||||
var fc = turf.featureCollection(features);
|
||||
scene.LineLayer({
|
||||
zIndex: 2
|
||||
})
|
||||
.source(fc)
|
||||
.color('rgb(13,64,140)')
|
||||
.style({
|
||||
opacity:0.6,
|
||||
})
|
||||
//.animate({enable:true})
|
||||
.render();
|
||||
/**
|
||||
scene.LineLayer({
|
||||
zIndex: 2
|
||||
})
|
||||
.source(data, { // lng1,lat1,lng2,lat2
|
||||
type: 'csv',
|
||||
x: 'lng1',
|
||||
y: 'lat1',
|
||||
x1: 'lng2',
|
||||
y1: 'lat2'
|
||||
})
|
||||
.shape('arc')
|
||||
.size(0.8)
|
||||
.color('rgb(13,64,140)')
|
||||
.style({
|
||||
opacity:0.6,
|
||||
})
|
||||
//.animate({enable:true})
|
||||
.render();
|
||||
**/
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
<meta name="geometry" content="diagram">
|
||||
<link rel="stylesheet" href="./assets/common.css">
|
||||
<title>point_circle</title>
|
||||
<style>
|
||||
#map { position:absolute; top:0; bottom:0; width:100%; }
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="map"></div>
|
||||
<script src="https://webapi.amap.com/maps?v=1.4.8&key=15cd8a57710d40c9b7c0e3cc120f1200&plugin=Map3D"></script>
|
||||
<script src="./assets/jquery-3.2.1.min.js"></script>
|
||||
<script src="./assets/dat.gui.min.js"></script>
|
||||
<script src="../build/L7.js"></script>
|
||||
<script>
|
||||
|
||||
const scene = new L7.Scene({
|
||||
id: 'map',
|
||||
mapStyle: 'dark', // 样式URL
|
||||
center: [ 120.037828998113099, 30.086317611850635 ],
|
||||
pitch: 0,
|
||||
zoom: 5.44
|
||||
});
|
||||
window.scene = scene;
|
||||
var colorObj={
|
||||
'黄色':'yellow',
|
||||
'蓝色':'blue',
|
||||
'橙色':'orange'
|
||||
|
||||
}
|
||||
scene.on('loaded', () => {
|
||||
$.get('./data/waringData.json', data => {
|
||||
scene.PointLayer({
|
||||
zIndex: 2
|
||||
})
|
||||
.source(data, {
|
||||
type: 'array',
|
||||
x: 'lon',
|
||||
y: 'lat',
|
||||
})
|
||||
.shape('2d:radar')
|
||||
.size(80 )
|
||||
.active(false)
|
||||
.color('signallevel',(v)=>{
|
||||
return colorObj[v];
|
||||
})
|
||||
.style({
|
||||
shape:'radar'
|
||||
})
|
||||
.render();
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
After Width: | Height: | Size: 198 KiB |
|
@ -0,0 +1,159 @@
|
|||
|
||||
.top-right{
|
||||
right: 10px;
|
||||
position:absolute;
|
||||
}
|
||||
.bottom-right{
|
||||
right: 0;
|
||||
bottom: 10px;
|
||||
position:absolute;
|
||||
}
|
||||
.info-panel {
|
||||
width: 250px;
|
||||
background: #fff;
|
||||
box-shadow: 0 0 4px rgba(0,0,0,.15);
|
||||
margin: 24px;
|
||||
padding: 12px 24px;
|
||||
outline: none;
|
||||
z-index: 10;
|
||||
}
|
||||
.info-panel p {
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
.info-panel h4 {
|
||||
font-size: 1em;
|
||||
font-weight: 500;
|
||||
margin: 8px 0;
|
||||
}
|
||||
.info-panel label {
|
||||
display: inline-block;
|
||||
width: 30px;
|
||||
margin-right: 10%;
|
||||
color: #5a666d;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.tooltip {
|
||||
position:absolute;
|
||||
pointer-events: none;
|
||||
transition: opacity .2s;
|
||||
padding: 4px;
|
||||
background: rgba(0,0,0,.8);
|
||||
color: #fff;
|
||||
max-width: 300px;
|
||||
font-size: 10px;
|
||||
z-index: 9;
|
||||
}
|
||||
.tooltip p {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
|
||||
}
|
||||
.input-item {
|
||||
position: relative;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-ms-flex-wrap: wrap;
|
||||
flex-wrap: wrap;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
height: 3rem;
|
||||
}
|
||||
|
||||
.input-item:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.input-item>select, .input-item>input[type=text], .input-item>input[type=date] {
|
||||
position: relative;
|
||||
-ms-flex: 1 1 auto;
|
||||
flex: 1 1 auto;
|
||||
width: 1%;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.input-item>select:not(:last-child), .input-item>input[type=text]:not(:last-child), .input-item>input[type=date]:not(:last-child) {
|
||||
border-top-right-radius: 0;
|
||||
border-bottom-right-radius: 0
|
||||
}
|
||||
|
||||
.input-item>select:not(:first-child), .input-item>input[type=text]:not(:first-child), .input-item>input[type=date]:not(:first-child) {
|
||||
border-top-left-radius: 0;
|
||||
border-bottom-left-radius: 0
|
||||
}
|
||||
|
||||
.input-item-prepend {
|
||||
margin-right: -1px;
|
||||
}
|
||||
|
||||
.input-item-text, input[type=text],input[type=date], select {
|
||||
height: calc(2.2rem + 2px);
|
||||
}
|
||||
|
||||
.input-item-text {
|
||||
width: 6rem;
|
||||
text-align: justify;
|
||||
padding: 0.4rem 0.7rem;
|
||||
display: inline-block;
|
||||
text-justify: distribute-all-lines;
|
||||
/*ie6-8*/
|
||||
text-align-last: justify;
|
||||
/* ie9*/
|
||||
-moz-text-align-last: justify;
|
||||
/*ff*/
|
||||
-webkit-text-align-last: justify;
|
||||
/*chrome 20+*/
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
margin-bottom: 0;
|
||||
font-size: 1rem;
|
||||
font-weight: 400;
|
||||
line-height: 1.5;
|
||||
color: #495057;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
background-color: #e9ecef;
|
||||
border: 1px solid #ced4da;
|
||||
border-radius: .25rem;
|
||||
border-bottom-right-radius: 0;
|
||||
border-top-right-radius: 0;
|
||||
}
|
||||
|
||||
.input-item-text input[type=checkbox], .input-item-text input[type=radio] {
|
||||
margin-top: 0
|
||||
}
|
||||
|
||||
.input-card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-width: 0;
|
||||
word-wrap: break-word;
|
||||
background-color: #fff;
|
||||
background-clip: border-box;
|
||||
width: 10rem;
|
||||
border-width: 0;
|
||||
position: fixed;
|
||||
top: 1rem;
|
||||
right: 1rem;
|
||||
-ms-flex: 1 1 auto;
|
||||
flex: 1 1 auto;
|
||||
padding: 0.1rem 0.6rem;
|
||||
}
|
||||
.info hr {
|
||||
margin-right: 0;
|
||||
margin-left: 0;
|
||||
border-top-color: grey;
|
||||
}
|
||||
|
||||
.info {
|
||||
padding: .75rem 1.25rem;
|
||||
margin-bottom: 1rem;
|
||||
position: fixed;
|
||||
top: 1rem;
|
||||
background-color: white;
|
||||
width: auto;
|
||||
border-width: 0;
|
||||
right: 1rem;
|
||||
z-index: 10;
|
||||
}
|
Before Width: | Height: | Size: 179 KiB After Width: | Height: | Size: 1.6 MiB |
After Width: | Height: | Size: 332 KiB |
Before Width: | Height: | Size: 7.2 KiB After Width: | Height: | Size: 1016 KiB |
After Width: | Height: | Size: 385 KiB |
After Width: | Height: | Size: 122 KiB |
Before Width: | Height: | Size: 499 KiB After Width: | Height: | Size: 1.1 MiB |
After Width: | Height: | Size: 647 KiB |
Before Width: | Height: | Size: 7.2 KiB After Width: | Height: | Size: 187 KiB |
After Width: | Height: | Size: 195 KiB |
Before Width: | Height: | Size: 222 KiB After Width: | Height: | Size: 438 KiB |
Before Width: | Height: | Size: 164 KiB After Width: | Height: | Size: 205 KiB |
Before Width: | Height: | Size: 303 KiB After Width: | Height: | Size: 2.7 MiB |
After Width: | Height: | Size: 3.6 MiB |
After Width: | Height: | Size: 496 KiB |
After Width: | Height: | Size: 2.1 MiB |
Before Width: | Height: | Size: 422 KiB |
Before Width: | Height: | Size: 892 KiB |
Before Width: | Height: | Size: 1.0 MiB |
Before Width: | Height: | Size: 367 KiB |
Before Width: | Height: | Size: 395 KiB |
Before Width: | Height: | Size: 738 KiB |
Before Width: | Height: | Size: 282 KiB |
Before Width: | Height: | Size: 160 KiB |
Before Width: | Height: | Size: 161 KiB |
Before Width: | Height: | Size: 7.2 KiB |
|
@ -0,0 +1,43 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
<meta name="geometry" content="diagram">
|
||||
<link rel="stylesheet" href="./assets/common.css">
|
||||
<title>line demo</title>
|
||||
<style>
|
||||
#map { position:absolute; top:0; bottom:0; width:100%; }
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="map"></div>
|
||||
<script src="https://webapi.amap.com/maps?v=1.4.8&key=15cd8a57710d40c9b7c0e3cc120f1200&plugin=Map3D"></script>
|
||||
<script src="./assets/jquery-3.2.1.min.js"></script>
|
||||
<script src="./assets/dat.gui.min.js"></script>
|
||||
<script src="../build/L7.js"></script>
|
||||
<script>
|
||||
const scene = new L7.Scene({
|
||||
id: 'map',
|
||||
mapStyle: 'dark', // 样式URL
|
||||
center: [ 120.3672, 36.0968 ],
|
||||
pitch: 0,
|
||||
zoom: 13
|
||||
});
|
||||
scene.on('loaded', () => {
|
||||
$.getJSON('./data/contour.json', contourData => {
|
||||
const color = [ 'rgb(22,32,101)', 'rgb(28,43,127)', 'rgb(36,68,142)', 'rgb(45,94,158)', 'rgb(53,119,174)', 'rgb(61,145,190)', 'rgb(70,170,206)', 'rgb(98,190,210)', 'rgb(138,205,206)', 'rgb(179,221,204)', 'rgb(220,236,201)' ];
|
||||
//contourData.features = contourData.features.slice(0,1);
|
||||
const layer = scene.LineLayer()
|
||||
.source(contourData)
|
||||
.color('ELEV', color)
|
||||
.size([ 1, 0 ])
|
||||
.shape('meshLine')
|
||||
.render();
|
||||
});
|
||||
})
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,107 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
<meta name="geometry" content="diagram">
|
||||
<link rel="stylesheet" href="./assets/common.css">
|
||||
<title>city demo</title>
|
||||
<style>
|
||||
#map { position:absolute; top:0; bottom:0; width:100%; }
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id = 'gui' style="position:absolute;top:0px;right:0px;z-index:2;"></div>
|
||||
<div id="map"></div>
|
||||
<script src="https://webapi.amap.com/maps?v=1.4.8&key=15cd8a57710d40c9b7c0e3cc120f1200&plugin=Map3D"></script>
|
||||
<script src="./assets/jquery-3.2.1.min.js"></script>
|
||||
<script src="./assets/dat.gui.min.js"></script>
|
||||
<script src="../build/L7.js"></script>
|
||||
<script>
|
||||
const gui = new dat.GUI({ autoPlace: false });
|
||||
const customContainer = document.getElementById('gui');
|
||||
customContainer.appendChild(gui.domElement);
|
||||
var palette = {
|
||||
baseColor: '#3CB4F0', // CSS string
|
||||
windowColor: '#65CEF7', // RGB array
|
||||
brightColor: '#98E3FA', // RGB with alpha
|
||||
};
|
||||
gui.addColor(palette, 'baseColor').onChange(()=>{
|
||||
changeStyle();
|
||||
});
|
||||
gui.addColor(palette, 'windowColor').onChange(()=>{
|
||||
changeStyle();
|
||||
});
|
||||
gui.addColor(palette, 'brightColor').onChange(()=>{
|
||||
changeStyle();
|
||||
});
|
||||
var buildLayer =null;
|
||||
const scene = new L7.Scene({
|
||||
id: 'map',
|
||||
mapStyle: 'dark', // 样式URL
|
||||
center: [ 121.507674, 31.223043 ],
|
||||
pitch: 65.59312320916906,
|
||||
zoom: 16.4,
|
||||
minZoom: 15,
|
||||
maxZoom: 18
|
||||
});
|
||||
scene.on('loaded', () => {
|
||||
$.get('./data/cityPoint.json', data => {
|
||||
scene.PointLayer({
|
||||
zIndex: 10
|
||||
})
|
||||
.source(data)
|
||||
.shape('2d:warn')
|
||||
.size(90)
|
||||
.color('#F00')
|
||||
.style({
|
||||
shape:'warn'
|
||||
})
|
||||
.render();
|
||||
});
|
||||
$.get('./data/road.json', data => {
|
||||
scene.LineLayer({
|
||||
zIndex: 2
|
||||
})
|
||||
.source(data)
|
||||
.color('#F08D41')
|
||||
.animate({enable:true})
|
||||
.render();
|
||||
});
|
||||
$.get('./data/2.geojson', data => {
|
||||
buildLayer = scene.PolygonLayer({
|
||||
zIndex: 2
|
||||
})
|
||||
.source(data)
|
||||
.shape('extrude')
|
||||
.size('floor',[0,2000])
|
||||
.color('rgba(242,246,250,1.0)')
|
||||
.animate({enable:true})
|
||||
.style({
|
||||
opacity:1.0,
|
||||
baseColor:'rgb(25,25,165)',
|
||||
windowColor:'rgb(30,60,89)',
|
||||
brightColor:'rgb(155,217,255)',
|
||||
|
||||
})
|
||||
.render();
|
||||
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
function changeStyle(e){
|
||||
buildLayer.style({
|
||||
opacity:0.8,
|
||||
baseColor:palette.baseColor,
|
||||
windowColor:palette.windowColor,
|
||||
brightColor:palette.brightColor,
|
||||
}
|
||||
).render();
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
31
package.json
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "@ali/l7",
|
||||
"version": "0.1.1",
|
||||
"description": "the Grammar of Graphics in Javascript",
|
||||
"name": "@antv/l7",
|
||||
"version": "1.0.0",
|
||||
"description": "Large-scale WebGL-powered Geospatial Data Visualization",
|
||||
"main": "build/l7.js",
|
||||
"browser": "build/l7.js",
|
||||
"module": "lib/index.js",
|
||||
|
@ -15,16 +15,17 @@
|
|||
},
|
||||
"keywords": [
|
||||
"l7",
|
||||
"chart"
|
||||
"gis",
|
||||
"geometry"
|
||||
],
|
||||
"author": "https://github.com/orgs/antvis/people",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@antv/util": "~1.2.5",
|
||||
"babel-cli": "~6.26.0",
|
||||
"babel-core": "~6.26.0",
|
||||
"@babel/cli": "~7.0.0",
|
||||
"@babel/core": "~7.0.0",
|
||||
"@babel/preset-env": "~7.1.0",
|
||||
"babel-eslint": "~8.0.3",
|
||||
"babel-loader": "^7.1.4",
|
||||
"babel-loader": "~8.0.0",
|
||||
"babel-plugin-transform-remove-strict-mode": "~0.0.2",
|
||||
"babel-preset-env": "~1.6.1",
|
||||
"body-parser": "^1.18.2",
|
||||
|
@ -33,7 +34,7 @@
|
|||
"connect": "^3.6.6",
|
||||
"d3-queue": "~3.0.7",
|
||||
"debug": "~3.1.0",
|
||||
"electron": "^1.8.4",
|
||||
"electron": "~2.0.2",
|
||||
"eslint": "~3.19.0",
|
||||
"eslint-config-airbnb": "~15.0.1",
|
||||
"eslint-config-egg": "~4.2.0",
|
||||
|
@ -50,7 +51,7 @@
|
|||
"serve-static": "^1.13.2",
|
||||
"shelljs": "~0.7.8",
|
||||
"string-replace-loader": "~1.3.0",
|
||||
"torchjs": "~1.0.4",
|
||||
"torchjs": "~2.1.0",
|
||||
"uglify-js": "~3.1.10",
|
||||
"webpack": "~3.10.0"
|
||||
},
|
||||
|
@ -76,11 +77,11 @@
|
|||
"prepublishOnly": "npm run build-lib && npm run dist",
|
||||
"screenshot": "node ./bin/screenshot.js",
|
||||
"start": "npm run dev",
|
||||
"test": "torch --compile --renderer --recursive ./test/unit",
|
||||
"test": "torch --compile --renderer --recursive test/unit",
|
||||
"test-all": "npm run test && npm run test-bugs",
|
||||
"test-bugs": "torch --compile --renderer --recursive ./test/bugs",
|
||||
"test-bugs-live": "torch --compile --interactive --watch --recursive ./test/bugs",
|
||||
"test-live": "torch --compile --interactive --watch --recursive ./test/unit",
|
||||
"test-bugs": "torch --compile --renderer --recursive test/bugs",
|
||||
"test-bugs-live": "torch --compile --interactive --watch --recursive test/bugs",
|
||||
"test-live": "torch --compile --interactive --watch --recursive test/unit",
|
||||
"watch": "webpack --config webpack-dev.config.js",
|
||||
"win-dev": "node ./bin/win-dev.js"
|
||||
},
|
||||
|
@ -96,6 +97,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@antv/g": "^3.1.3",
|
||||
"@antv/util": "~1.2.5",
|
||||
"@mapbox/tiny-sdf": "^1.1.0",
|
||||
"@turf/bbox": "^6.0.1",
|
||||
"@turf/clean-coords": "^6.0.1",
|
||||
|
@ -106,6 +108,7 @@
|
|||
"fecha": "^2.3.3",
|
||||
"gl-matrix": "^2.4.1",
|
||||
"lodash": "^4.17.5",
|
||||
"polyline-normals": "^2.0.2",
|
||||
"rbush": "^2.0.2",
|
||||
"three": "^0.96.0",
|
||||
"venn.js": "^0.2.20",
|
||||
|
|
|
@ -97,3 +97,4 @@ export const colorScales = {
|
|||
magma: new Uint8Array([ 0, 0, 4, 255, 1, 0, 5, 255, 1, 1, 6, 255, 1, 1, 8, 255, 2, 1, 9, 255, 2, 2, 11, 255, 2, 2, 13, 255, 3, 3, 15, 255, 3, 3, 18, 255, 4, 4, 20, 255, 5, 4, 22, 255, 6, 5, 24, 255, 6, 5, 26, 255, 7, 6, 28, 255, 8, 7, 30, 255, 9, 7, 32, 255, 10, 8, 34, 255, 11, 9, 36, 255, 12, 9, 38, 255, 13, 10, 41, 255, 14, 11, 43, 255, 16, 11, 45, 255, 17, 12, 47, 255, 18, 13, 49, 255, 19, 13, 52, 255, 20, 14, 54, 255, 21, 14, 56, 255, 22, 15, 59, 255, 24, 15, 61, 255, 25, 16, 63, 255, 26, 16, 66, 255, 28, 16, 68, 255, 29, 17, 71, 255, 30, 17, 73, 255, 32, 17, 75, 255, 33, 17, 78, 255, 34, 17, 80, 255, 36, 18, 83, 255, 37, 18, 85, 255, 39, 18, 88, 255, 41, 17, 90, 255, 42, 17, 92, 255, 44, 17, 95, 255, 45, 17, 97, 255, 47, 17, 99, 255, 49, 17, 101, 255, 51, 16, 103, 255, 52, 16, 105, 255, 54, 16, 107, 255, 56, 16, 108, 255, 57, 15, 110, 255, 59, 15, 112, 255, 61, 15, 113, 255, 63, 15, 114, 255, 64, 15, 116, 255, 66, 15, 117, 255, 68, 15, 118, 255, 69, 16, 119, 255, 71, 16, 120, 255, 73, 16, 120, 255, 74, 16, 121, 255, 76, 17, 122, 255, 78, 17, 123, 255, 79, 18, 123, 255, 81, 18, 124, 255, 82, 19, 124, 255, 84, 19, 125, 255, 86, 20, 125, 255, 87, 21, 126, 255, 89, 21, 126, 255, 90, 22, 126, 255, 92, 22, 127, 255, 93, 23, 127, 255, 95, 24, 127, 255, 96, 24, 128, 255, 98, 25, 128, 255, 100, 26, 128, 255, 101, 26, 128, 255, 103, 27, 128, 255, 104, 28, 129, 255, 106, 28, 129, 255, 107, 29, 129, 255, 109, 29, 129, 255, 110, 30, 129, 255, 112, 31, 129, 255, 114, 31, 129, 255, 115, 32, 129, 255, 117, 33, 129, 255, 118, 33, 129, 255, 120, 34, 129, 255, 121, 34, 130, 255, 123, 35, 130, 255, 124, 35, 130, 255, 126, 36, 130, 255, 128, 37, 130, 255, 129, 37, 129, 255, 131, 38, 129, 255, 132, 38, 129, 255, 134, 39, 129, 255, 136, 39, 129, 255, 137, 40, 129, 255, 139, 41, 129, 255, 140, 41, 129, 255, 142, 42, 129, 255, 144, 42, 129, 255, 145, 43, 129, 255, 147, 43, 128, 255, 148, 44, 128, 255, 150, 44, 128, 255, 152, 45, 128, 255, 153, 45, 128, 255, 155, 46, 127, 255, 156, 46, 127, 255, 158, 47, 127, 255, 160, 47, 127, 255, 161, 48, 126, 255, 163, 48, 126, 255, 165, 49, 126, 255, 166, 49, 125, 255, 168, 50, 125, 255, 170, 51, 125, 255, 171, 51, 124, 255, 173, 52, 124, 255, 174, 52, 123, 255, 176, 53, 123, 255, 178, 53, 123, 255, 179, 54, 122, 255, 181, 54, 122, 255, 183, 55, 121, 255, 184, 55, 121, 255, 186, 56, 120, 255, 188, 57, 120, 255, 189, 57, 119, 255, 191, 58, 119, 255, 192, 58, 118, 255, 194, 59, 117, 255, 196, 60, 117, 255, 197, 60, 116, 255, 199, 61, 115, 255, 200, 62, 115, 255, 202, 62, 114, 255, 204, 63, 113, 255, 205, 64, 113, 255, 207, 64, 112, 255, 208, 65, 111, 255, 210, 66, 111, 255, 211, 67, 110, 255, 213, 68, 109, 255, 214, 69, 108, 255, 216, 69, 108, 255, 217, 70, 107, 255, 219, 71, 106, 255, 220, 72, 105, 255, 222, 73, 104, 255, 223, 74, 104, 255, 224, 76, 103, 255, 226, 77, 102, 255, 227, 78, 101, 255, 228, 79, 100, 255, 229, 80, 100, 255, 231, 82, 99, 255, 232, 83, 98, 255, 233, 84, 98, 255, 234, 86, 97, 255, 235, 87, 96, 255, 236, 88, 96, 255, 237, 90, 95, 255, 238, 91, 94, 255, 239, 93, 94, 255, 240, 95, 94, 255, 241, 96, 93, 255, 242, 98, 93, 255, 242, 100, 92, 255, 243, 101, 92, 255, 244, 103, 92, 255, 244, 105, 92, 255, 245, 107, 92, 255, 246, 108, 92, 255, 246, 110, 92, 255, 247, 112, 92, 255, 247, 114, 92, 255, 248, 116, 92, 255, 248, 118, 92, 255, 249, 120, 93, 255, 249, 121, 93, 255, 249, 123, 93, 255, 250, 125, 94, 255, 250, 127, 94, 255, 250, 129, 95, 255, 251, 131, 95, 255, 251, 133, 96, 255, 251, 135, 97, 255, 252, 137, 97, 255, 252, 138, 98, 255, 252, 140, 99, 255, 252, 142, 100, 255, 252, 144, 101, 255, 253, 146, 102, 255, 253, 148, 103, 255, 253, 150, 104, 255, 253, 152, 105, 255, 253, 154, 106, 255, 253, 155, 107, 255, 254, 157, 108, 255, 254, 159, 109, 255, 254, 161, 110, 255, 254, 163, 111, 255, 254, 165, 113, 255, 254, 167, 114, 255, 254, 169, 115, 255, 254, 170, 116, 255, 254, 172, 118, 255, 254, 174, 119, 255, 254, 176, 120, 255, 254, 178, 122, 255, 254, 180, 123, 255, 254, 182, 124, 255, 254, 183, 126, 255, 254, 185, 127, 255, 254, 187, 129, 255, 254, 189, 130, 255, 254, 191, 132, 255, 254, 193, 133, 255, 254, 194, 135, 255, 254, 196, 136, 255, 254, 198, 138, 255, 254, 200, 140, 255, 254, 202, 141, 255, 254, 204, 143, 255, 254, 205, 144, 255, 254, 207, 146, 255, 254, 209, 148, 255, 254, 211, 149, 255, 254, 213, 151, 255, 254, 215, 153, 255, 254, 216, 154, 255, 253, 218, 156, 255, 253, 220, 158, 255, 253, 222, 160, 255, 253, 224, 161, 255, 253, 226, 163, 255, 253, 227, 165, 255, 253, 229, 167, 255, 253, 231, 169, 255, 253, 233, 170, 255, 253, 235, 172, 255, 252, 236, 174, 255, 252, 238, 176, 255, 252, 240, 178, 255, 252, 242, 180, 255, 252, 244, 182, 255, 252, 246, 184, 255, 252, 247, 185, 255, 252, 249, 187, 255, 252, 251, 189, 255, 252, 253, 191, 255 ]),
|
||||
plasma: new Uint8Array([ 13, 8, 135, 255, 16, 7, 136, 255, 19, 7, 137, 255, 22, 7, 138, 255, 25, 6, 140, 255, 27, 6, 141, 255, 29, 6, 142, 255, 32, 6, 143, 255, 34, 6, 144, 255, 36, 6, 145, 255, 38, 5, 145, 255, 40, 5, 146, 255, 42, 5, 147, 255, 44, 5, 148, 255, 46, 5, 149, 255, 47, 5, 150, 255, 49, 5, 151, 255, 51, 5, 151, 255, 53, 4, 152, 255, 55, 4, 153, 255, 56, 4, 154, 255, 58, 4, 154, 255, 60, 4, 155, 255, 62, 4, 156, 255, 63, 4, 156, 255, 65, 4, 157, 255, 67, 3, 158, 255, 68, 3, 158, 255, 70, 3, 159, 255, 72, 3, 159, 255, 73, 3, 160, 255, 75, 3, 161, 255, 76, 2, 161, 255, 78, 2, 162, 255, 80, 2, 162, 255, 81, 2, 163, 255, 83, 2, 163, 255, 85, 2, 164, 255, 86, 1, 164, 255, 88, 1, 164, 255, 89, 1, 165, 255, 91, 1, 165, 255, 92, 1, 166, 255, 94, 1, 166, 255, 96, 1, 166, 255, 97, 0, 167, 255, 99, 0, 167, 255, 100, 0, 167, 255, 102, 0, 167, 255, 103, 0, 168, 255, 105, 0, 168, 255, 106, 0, 168, 255, 108, 0, 168, 255, 110, 0, 168, 255, 111, 0, 168, 255, 113, 0, 168, 255, 114, 1, 168, 255, 116, 1, 168, 255, 117, 1, 168, 255, 119, 1, 168, 255, 120, 1, 168, 255, 122, 2, 168, 255, 123, 2, 168, 255, 125, 3, 168, 255, 126, 3, 168, 255, 128, 4, 168, 255, 129, 4, 167, 255, 131, 5, 167, 255, 132, 5, 167, 255, 134, 6, 166, 255, 135, 7, 166, 255, 136, 8, 166, 255, 138, 9, 165, 255, 139, 10, 165, 255, 141, 11, 165, 255, 142, 12, 164, 255, 143, 13, 164, 255, 145, 14, 163, 255, 146, 15, 163, 255, 148, 16, 162, 255, 149, 17, 161, 255, 150, 19, 161, 255, 152, 20, 160, 255, 153, 21, 159, 255, 154, 22, 159, 255, 156, 23, 158, 255, 157, 24, 157, 255, 158, 25, 157, 255, 160, 26, 156, 255, 161, 27, 155, 255, 162, 29, 154, 255, 163, 30, 154, 255, 165, 31, 153, 255, 166, 32, 152, 255, 167, 33, 151, 255, 168, 34, 150, 255, 170, 35, 149, 255, 171, 36, 148, 255, 172, 38, 148, 255, 173, 39, 147, 255, 174, 40, 146, 255, 176, 41, 145, 255, 177, 42, 144, 255, 178, 43, 143, 255, 179, 44, 142, 255, 180, 46, 141, 255, 181, 47, 140, 255, 182, 48, 139, 255, 183, 49, 138, 255, 184, 50, 137, 255, 186, 51, 136, 255, 187, 52, 136, 255, 188, 53, 135, 255, 189, 55, 134, 255, 190, 56, 133, 255, 191, 57, 132, 255, 192, 58, 131, 255, 193, 59, 130, 255, 194, 60, 129, 255, 195, 61, 128, 255, 196, 62, 127, 255, 197, 64, 126, 255, 198, 65, 125, 255, 199, 66, 124, 255, 200, 67, 123, 255, 201, 68, 122, 255, 202, 69, 122, 255, 203, 70, 121, 255, 204, 71, 120, 255, 204, 73, 119, 255, 205, 74, 118, 255, 206, 75, 117, 255, 207, 76, 116, 255, 208, 77, 115, 255, 209, 78, 114, 255, 210, 79, 113, 255, 211, 81, 113, 255, 212, 82, 112, 255, 213, 83, 111, 255, 213, 84, 110, 255, 214, 85, 109, 255, 215, 86, 108, 255, 216, 87, 107, 255, 217, 88, 106, 255, 218, 90, 106, 255, 218, 91, 105, 255, 219, 92, 104, 255, 220, 93, 103, 255, 221, 94, 102, 255, 222, 95, 101, 255, 222, 97, 100, 255, 223, 98, 99, 255, 224, 99, 99, 255, 225, 100, 98, 255, 226, 101, 97, 255, 226, 102, 96, 255, 227, 104, 95, 255, 228, 105, 94, 255, 229, 106, 93, 255, 229, 107, 93, 255, 230, 108, 92, 255, 231, 110, 91, 255, 231, 111, 90, 255, 232, 112, 89, 255, 233, 113, 88, 255, 233, 114, 87, 255, 234, 116, 87, 255, 235, 117, 86, 255, 235, 118, 85, 255, 236, 119, 84, 255, 237, 121, 83, 255, 237, 122, 82, 255, 238, 123, 81, 255, 239, 124, 81, 255, 239, 126, 80, 255, 240, 127, 79, 255, 240, 128, 78, 255, 241, 129, 77, 255, 241, 131, 76, 255, 242, 132, 75, 255, 243, 133, 75, 255, 243, 135, 74, 255, 244, 136, 73, 255, 244, 137, 72, 255, 245, 139, 71, 255, 245, 140, 70, 255, 246, 141, 69, 255, 246, 143, 68, 255, 247, 144, 68, 255, 247, 145, 67, 255, 247, 147, 66, 255, 248, 148, 65, 255, 248, 149, 64, 255, 249, 151, 63, 255, 249, 152, 62, 255, 249, 154, 62, 255, 250, 155, 61, 255, 250, 156, 60, 255, 250, 158, 59, 255, 251, 159, 58, 255, 251, 161, 57, 255, 251, 162, 56, 255, 252, 163, 56, 255, 252, 165, 55, 255, 252, 166, 54, 255, 252, 168, 53, 255, 252, 169, 52, 255, 253, 171, 51, 255, 253, 172, 51, 255, 253, 174, 50, 255, 253, 175, 49, 255, 253, 177, 48, 255, 253, 178, 47, 255, 253, 180, 47, 255, 253, 181, 46, 255, 254, 183, 45, 255, 254, 184, 44, 255, 254, 186, 44, 255, 254, 187, 43, 255, 254, 189, 42, 255, 254, 190, 42, 255, 254, 192, 41, 255, 253, 194, 41, 255, 253, 195, 40, 255, 253, 197, 39, 255, 253, 198, 39, 255, 253, 200, 39, 255, 253, 202, 38, 255, 253, 203, 38, 255, 252, 205, 37, 255, 252, 206, 37, 255, 252, 208, 37, 255, 252, 210, 37, 255, 251, 211, 36, 255, 251, 213, 36, 255, 251, 215, 36, 255, 250, 216, 36, 255, 250, 218, 36, 255, 249, 220, 36, 255, 249, 221, 37, 255, 248, 223, 37, 255, 248, 225, 37, 255, 247, 226, 37, 255, 247, 228, 37, 255, 246, 230, 38, 255, 246, 232, 38, 255, 245, 233, 38, 255, 245, 235, 39, 255, 244, 237, 39, 255, 243, 238, 39, 255, 243, 240, 39, 255, 242, 242, 39, 255, 241, 244, 38, 255, 241, 245, 37, 255, 240, 247, 36, 255, 240, 249, 33, 255 ])
|
||||
};
|
||||
// module.exports = colorScales;
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
* @author dxq613@gmail.com
|
||||
*/
|
||||
|
||||
const EventEmitter = require('wolfy87-eventemitter');
|
||||
const Util = require('../util');
|
||||
import EventEmitter from 'wolfy87-eventemitter';
|
||||
import Util from '../util';
|
||||
|
||||
class Base extends EventEmitter {
|
||||
|
||||
|
@ -29,16 +29,6 @@ class Base extends EventEmitter {
|
|||
set(name, value) {
|
||||
this._attrs[name] = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @protected
|
||||
* @param {Boolean} visible 是否可见
|
||||
* 显示、隐藏
|
||||
*/
|
||||
changeVisible(/* visible */) {
|
||||
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this._attrs = {};
|
||||
this.removeAllListeners();
|
||||
|
@ -46,4 +36,4 @@ class Base extends EventEmitter {
|
|||
}
|
||||
}
|
||||
|
||||
module.exports = Base;
|
||||
export default Base;
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
class Geometry extends BufferGeometry {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
updateAttribute(name, startIndex, size, value) {
|
||||
const attribute = this.attributes[name];
|
||||
for (let i = 0; i < size; i++) {
|
||||
attribute.array[startIndex + i] = value[i];
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
import EventEmitter from 'wolfy87-eventemitter';
|
||||
import * as THREE from '../three';
|
||||
import Scene from './scene';
|
||||
import Camera from './camera';
|
||||
import Renderer from './renderer';
|
||||
|
@ -11,8 +12,7 @@ export default class Engine extends EventEmitter {
|
|||
this._renderer = new Renderer(container).renderer;
|
||||
this._world = world;
|
||||
this._picking = Picking(this._world, this._renderer, this._camera, this._scene);
|
||||
this._renderer.context.getExtension('OES_texture_float');
|
||||
this._renderer.context.getExtension('OES_texture_float_linear');
|
||||
this.clock = new THREE.Clock();
|
||||
}
|
||||
_initPostProcessing() {
|
||||
|
||||
|
@ -26,10 +26,9 @@ export default class Engine extends EventEmitter {
|
|||
|
||||
}
|
||||
run() {
|
||||
this.engineID = requestAnimationFrame(() => {
|
||||
this.update();
|
||||
this.engineID = requestAnimationFrame(this.run.bind(this));
|
||||
});
|
||||
|
||||
this.update();
|
||||
this.engineID = requestAnimationFrame(this.run.bind(this));
|
||||
}
|
||||
stop() {
|
||||
cancelAnimationFrame(this.engineID);
|
||||
|
|
|
@ -1,20 +1,5 @@
|
|||
import PickingScene from './pickingScene';
|
||||
import * as THREE from '../../three';
|
||||
// TODO: Look into a way of setting this up without passing in a renderer and
|
||||
// camera from the engine
|
||||
|
||||
// TODO: Add a basic indicator on or around the mouse pointer when it is over
|
||||
// something pickable / clickable
|
||||
//
|
||||
// A simple transparent disc or ring at the mouse point should work to start, or
|
||||
// even just changing the cursor to the CSS 'pointer' style
|
||||
//
|
||||
// Probably want this on mousemove with a throttled update as not to spam the
|
||||
// picking method
|
||||
//
|
||||
// Relies upon the picking method not redrawing the scene every call due to
|
||||
// the way TileLayer invalidates the picking scene
|
||||
|
||||
let nextId = 1;
|
||||
|
||||
class Picking {
|
||||
|
@ -24,6 +9,7 @@ class Picking {
|
|||
this._camera = camera;
|
||||
this._raycaster = new THREE.Raycaster();
|
||||
this.scene = scene;
|
||||
this._envents = [];
|
||||
|
||||
// TODO: Match this with the line width used in the picking layers
|
||||
this._raycaster.linePrecision = 3;
|
||||
|
@ -52,15 +38,15 @@ class Picking {
|
|||
|
||||
this._mouseUpHandler = this._onMouseUp.bind(this);
|
||||
this._world._container.addEventListener('mouseup', this._mouseUpHandler, false);
|
||||
|
||||
// this._world.on('move', this._onWorldMove, this);
|
||||
this._world._container.addEventListener('mousemove', this._mouseUpHandler, false);
|
||||
this._world._container.addEventListener('mousemove', this._onWorldMove.bind(this), false);
|
||||
}
|
||||
|
||||
_onMouseUp(event) {
|
||||
// Only react to main button click
|
||||
if (event.button !== 0) {
|
||||
return;
|
||||
}
|
||||
// if (event.button !== 0) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
const point = { x: event.clientX, y: event.clientY };
|
||||
const normalisedPoint = { x: 0, y: 0 };
|
||||
|
@ -71,6 +57,7 @@ class Picking {
|
|||
}
|
||||
|
||||
_onWorldMove() {
|
||||
|
||||
this._needUpdate = true;
|
||||
}
|
||||
|
||||
|
@ -86,26 +73,31 @@ class Picking {
|
|||
|
||||
this._needUpdate = true;
|
||||
}
|
||||
|
||||
// TODO: Make this only re-draw the scene if both an update is needed and the
|
||||
// camera has moved since the last update
|
||||
//
|
||||
// Otherwise it re-draws the scene on every click due to the way LOD updates
|
||||
// work in TileLayer – spamming this.add() and this.remove()
|
||||
//
|
||||
// TODO: Pause updates during map move / orbit / zoom as this is unlikely to
|
||||
// be a point in time where the user cares for picking functionality
|
||||
_update(point) {
|
||||
// if (this._needUpdate) {
|
||||
const texture = this._pickingTexture;
|
||||
this._renderer.render(this._pickingScene, this._camera, this._pickingTexture);// this._pickingTexture this._pickingScene
|
||||
// Read the rendering texture
|
||||
|
||||
const texture = this._pickingTexture;
|
||||
if (this._needUpdate) {
|
||||
this._renderer.render(this._pickingScene, this._camera, this._pickingTexture);
|
||||
this._needUpdate = false;
|
||||
}
|
||||
this.pixelBuffer = new Uint8Array(4);
|
||||
this._renderer.readRenderTargetPixels(texture, point.x, this._height - point.y, 1, 1, this.pixelBuffer);
|
||||
|
||||
// this._needUpdate = false;
|
||||
// }
|
||||
|
||||
}
|
||||
// 添加dom事件 支持 mousedown ,mouseenter mouseleave mousemove mouseover mouseout mouse up
|
||||
on(type) {
|
||||
|
||||
this._mouseUpHandler = this._onMouseUp.bind(this);
|
||||
this._world._container.addEventListener(type, this._mouseUpHandler, false);
|
||||
this._envents.push([ type, this._mouseUpHandler ]);
|
||||
}
|
||||
off(type, hander) {
|
||||
this._world._container.removeEventListener(type, this._mouseUpHandler, false);
|
||||
this._envents = this._envents.filter(item => {
|
||||
return item[0] === 'type' && hander === item[1];
|
||||
});
|
||||
|
||||
}
|
||||
_updateRender() {
|
||||
this._renderer.render(this._pickingScene, this._camera, this._pickingTexture);
|
||||
|
@ -116,7 +108,7 @@ class Picking {
|
|||
// Interpret the pixel as an ID
|
||||
const id = (this.pixelBuffer[2] * 255 * 255) + (this.pixelBuffer[1] * 255) + (this.pixelBuffer[0]);
|
||||
// Skip if ID is 16646655 (white) as the background returns this
|
||||
if (id === 16646655) {
|
||||
if (id === 16646655 || this.pixelBuffer[3] === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -139,7 +131,7 @@ class Picking {
|
|||
//
|
||||
// TODO: Look into the leak potential for passing so much by reference here
|
||||
const item = {
|
||||
featureId: id,
|
||||
featureId: id - 1,
|
||||
point2d: _point2d,
|
||||
point3d: _point3d,
|
||||
intersects
|
||||
|
@ -171,7 +163,9 @@ class Picking {
|
|||
// TODO: Find a way to properly remove these listeners as they stay
|
||||
// active at the moment
|
||||
window.removeEventListener('resize', this._resizeHandler, false);
|
||||
this._world._container.removeEventListener('mouseup', this._mouseUpHandler, false);
|
||||
this._envents.forEach(event => {
|
||||
this._world._container.removeEventListener(event[0], event[1], false);
|
||||
});
|
||||
|
||||
this._world.off('move', this._onWorldMove);
|
||||
|
||||
|
|
|
@ -1,37 +1,15 @@
|
|||
import * as THREE from '../../three';
|
||||
import Material from '../../../geom/material/material';
|
||||
import picking_frag from './picking_frag.glsl';
|
||||
import picking_vert from './picking_vert.glsl';
|
||||
|
||||
// FROM: https://github.com/brianxu/GPUPicker/blob/master/GPUPicker.js
|
||||
const PickingMaterial = function() {
|
||||
THREE.ShaderMaterial.call(this, {
|
||||
export default function PickingMaterial(options) {
|
||||
const material = new Material({
|
||||
uniforms: {
|
||||
size: {
|
||||
type: 'f',
|
||||
value: 0.01
|
||||
},
|
||||
scale: {
|
||||
type: 'f',
|
||||
value: 400
|
||||
}
|
||||
u_zoom: { value: options.u_zoom || 1 }
|
||||
},
|
||||
vertexShader: picking_vert,
|
||||
fragmentShader: picking_frag
|
||||
fragmentShader: picking_frag,
|
||||
transparent: false
|
||||
});
|
||||
|
||||
this.linePadding = 2;
|
||||
};
|
||||
|
||||
PickingMaterial.prototype = Object.create(THREE.ShaderMaterial.prototype);
|
||||
|
||||
PickingMaterial.prototype.constructor = PickingMaterial;
|
||||
|
||||
PickingMaterial.prototype.setPointSize = function(size) {
|
||||
this.uniforms.size.value = size;
|
||||
};
|
||||
|
||||
PickingMaterial.prototype.setPointScale = function(scale) {
|
||||
this.uniforms.scale.value = scale;
|
||||
};
|
||||
|
||||
export default PickingMaterial;
|
||||
return material;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
#ifdef GL_ES
|
||||
|
||||
precision highp float;
|
||||
#endif
|
||||
varying vec4 worldId;
|
||||
void main() {
|
||||
if(worldId.x == 0. &&worldId.y == 0. && worldId.z==0.){
|
||||
discard;
|
||||
return;
|
||||
}
|
||||
gl_FragColor = worldId;
|
||||
}
|
|
@ -1,11 +1,28 @@
|
|||
attribute float pickingId;
|
||||
attribute float a_size;
|
||||
#ifdef polyline
|
||||
attribute float a_size;
|
||||
attribute float a_miter;
|
||||
#endif
|
||||
#ifdef point
|
||||
attribute vec3 a_size;
|
||||
attribute vec3 a_shape;
|
||||
#endif
|
||||
uniform float u_zoom;
|
||||
varying vec4 worldId;
|
||||
void main() {
|
||||
mat4 matModelViewProjection = projectionMatrix * modelViewMatrix;
|
||||
vec3 a = fract(vec3(1.0/255.0, 1.0/(255.0*255.0), 1.0/(255.0*255.0*255.0)) * pickingId);
|
||||
float scale = pow(2.0,(20.0 - u_zoom));
|
||||
vec3 newposition = position;
|
||||
#ifdef point
|
||||
newposition =position + a_size * scale * a_shape;
|
||||
#endif
|
||||
#ifdef polyline
|
||||
newposition = position.xyz + vec3(normal * a_size * pow(2.0,20.0-u_zoom) / 2.0 * a_miter);
|
||||
#endif
|
||||
float id = step(0.,pickingId) * pickingId;
|
||||
vec3 a = fract(vec3(1.0/255.0, 1.0/(255.0*255.0), 1.0/(255.0*255.0*255.0)) * id);
|
||||
a -= a.xxy * vec3(0.0, 1.0/255.0, 1.0/255.0);
|
||||
worldId = vec4(a,1);
|
||||
gl_PointSize = a_size;
|
||||
gl_Position = matModelViewProjection * vec4( position, 1.0 );
|
||||
//gl_PointSize = a_size;
|
||||
gl_Position = matModelViewProjection * vec4( newposition, 1.0 );
|
||||
}
|
|
@ -10,7 +10,7 @@ export class RenderPass {
|
|||
this._init(cfg);
|
||||
}
|
||||
|
||||
_init(cfg) {
|
||||
_init() {
|
||||
this.scene = new THREE.Scene();
|
||||
const parameters = { minFilter: THREE.NearestFilter,
|
||||
magFilter: THREE.NearestFilter,
|
||||
|
@ -19,7 +19,7 @@ export class RenderPass {
|
|||
depthBuffer: false
|
||||
};
|
||||
const size = this.renderer.getSize();
|
||||
this.pass = new THREE.WebGLRenderTarget(512, 512, parameters);
|
||||
this.pass = new THREE.WebGLRenderTarget(size.width, size.height, parameters);
|
||||
this.originClearColor = this.renderer.getClearColor();
|
||||
this.originClearAlpha = this.renderer.getClearAlpha();
|
||||
this.texture = this.pass.texture;
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
|
||||
import Material from '../../../geom/material/material';
|
||||
import draw_vert from './draw_vert.glsl';
|
||||
import draw_frag from './draw_frag.glsl';
|
||||
export default function DrawMaterial(options) {
|
||||
const material = new Material({
|
||||
uniforms: {
|
||||
u_color_ramp: { value: options.u_color_ramp },
|
||||
u_wind_max: { value: options.u_wind_max },
|
||||
u_particles_res: { value: options.u_particles_res },
|
||||
u_wind_min: { value: options.u_wind_min },
|
||||
u_opacity: { value: options.u_opacity },
|
||||
u_wind: { value: options.u_wind },
|
||||
u_particles: { value: options.u_particles },
|
||||
u_bbox: { value: options.u_bbox }
|
||||
},
|
||||
vertexShader: draw_vert,
|
||||
fragmentShader: draw_frag,
|
||||
transparent: true
|
||||
});
|
||||
// material.blending = THREE.AdditiveBlending
|
||||
return material;
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
precision mediump float;
|
||||
uniform sampler2D u_wind;
|
||||
uniform vec2 u_wind_min;
|
||||
uniform vec2 u_wind_max;
|
||||
uniform sampler2D u_color_ramp;
|
||||
uniform float u_opacity;
|
||||
varying vec2 v_particle_pos;
|
||||
|
||||
void main() {
|
||||
vec2 velocity = mix(u_wind_min, u_wind_max, texture2D(u_wind, v_particle_pos).rg);
|
||||
float speed_t = length(velocity) / length(u_wind_max);
|
||||
|
||||
// color ramp is encoded in a 16x16 texture
|
||||
vec2 ramp_pos = vec2(
|
||||
fract(16.0 * speed_t),
|
||||
floor(16.0 * speed_t) / 16.0);
|
||||
|
||||
gl_FragColor = texture2D(u_color_ramp, ramp_pos);
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
import { DataType, DrawMode } from '@ali/r3-base';
|
||||
import { BufferGeometry } from '@ali/r3-geometry';
|
||||
|
||||
/**
|
||||
* 创建点图层几何体
|
||||
*/
|
||||
export default class DrawGeometry extends BufferGeometry {
|
||||
|
||||
constructor(opts) {
|
||||
super(opts.name);
|
||||
this._index = opts.index;
|
||||
this.mode = DrawMode.POINTS;
|
||||
|
||||
this.primitive.indexType = DataType.UNSIGNED_INT;
|
||||
this.initialize();
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造多边形数据
|
||||
* @private
|
||||
*/
|
||||
initialize() {
|
||||
super.initialize([
|
||||
{ semantic: 'INDEX', size: 1, type: DataType.FLOAT, normalized: false }
|
||||
], this._index.length);
|
||||
|
||||
this._index.forEach((vert, j) => {
|
||||
this.setVertexValues(j, {
|
||||
INDEX: [ vert ]
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
precision mediump float;
|
||||
|
||||
attribute float a_index;
|
||||
uniform sampler2D u_particles;
|
||||
uniform vec4 u_bbox;
|
||||
uniform float u_particles_res;
|
||||
|
||||
varying vec2 v_particle_pos;
|
||||
void main() {
|
||||
mat4 matModelViewProjection = projectionMatrix * modelViewMatrix;
|
||||
vec4 color = texture2D(u_particles, vec2(
|
||||
fract(a_index / u_particles_res),
|
||||
1.0 - floor(a_index / u_particles_res) / u_particles_res));
|
||||
|
||||
// decode current particle position from the pixel's RGBA value
|
||||
v_particle_pos = vec2(
|
||||
color.r / 255.0 + color.b,
|
||||
1.0 - (color.g / 255.0 + color.a));
|
||||
vec2 xyrange = u_bbox.zw - u_bbox.xy;
|
||||
float x = u_bbox.x + v_particle_pos.x * xyrange.x;
|
||||
float y = u_bbox.w - v_particle_pos.y * xyrange.y;
|
||||
gl_PointSize = 1.0;
|
||||
//gl_Position = matModelViewProjection * vec4(v_particle_pos, 0.0, 1.0);
|
||||
gl_Position = vec4(2.0 * v_particle_pos.x - 1.0, 1.0 - 2.0 * v_particle_pos.y, 0, 1);
|
||||
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
import { RenderPass } from '@ali/r3-renderer-basic';
|
||||
import { TextureFilter } from '@ali/r3-base';
|
||||
export class GeoRenderPass extends RenderPass {
|
||||
|
||||
constructor(name, priority, renderTarget, mask, Material, id, done) {
|
||||
renderTarget.texture.setFilter(TextureFilter.NEAREST, TextureFilter.NEAREST);
|
||||
super(name, priority, renderTarget, Material, mask);
|
||||
typeof (id) === 'string' || typeof (id) === 'number' && (id = [ id ]);
|
||||
this.id = id;
|
||||
this.renderPassFlags = [];
|
||||
this.done = done;
|
||||
}
|
||||
/* eslint-disable */
|
||||
preRender(camera, opaquaQueue, transparentQueue) {
|
||||
/* eslint-disable */
|
||||
|
||||
opaquaQueue.items.forEach(item => {
|
||||
const nodeAbility = item.nodeAbility;
|
||||
this.renderPassFlags.push(nodeAbility.renderPassFlag);
|
||||
this.id.indexOf(nodeAbility.id) > -1 ? nodeAbility.renderPassFlag = 0 : nodeAbility.renderPassFlag = 1;
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
postRender(camera, opaquaQueue, transparentQueue) {
|
||||
opaquaQueue.items.forEach((item, index) => {
|
||||
const nodeAbility = item.nodeAbility;
|
||||
nodeAbility.renderPassFlag = this.renderPassFlags[index];
|
||||
});
|
||||
this.renderPassFlags.length = 0;
|
||||
if(this.done) {
|
||||
this.done();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
export { ColorRenderPass };
|
|
@ -1,7 +0,0 @@
|
|||
precision highp float;
|
||||
varying vec2 v_texCoord;
|
||||
void main() {
|
||||
v_texCoord = uv;
|
||||
|
||||
gl_Position = vec4(1.0 - 2.0 * vec2(position), 0., 1.0);
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
precision mediump float;
|
||||
uniform sampler2D u_texture;
|
||||
uniform float u_opacity;
|
||||
varying vec2 v_texCoord;
|
||||
|
||||
void main() {
|
||||
if(u_opacity == 0.0)
|
||||
discard;
|
||||
gl_FragColor = texture2D(u_texture,1.0 - v_texCoord) * u_opacity;
|
||||
// gl_FragColor.w =u_opacity;
|
||||
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
import Material from '../../../geom/material/material';
|
||||
import quad_vert from './quad.vert.glsl';
|
||||
import update_frag from './update_frag.glsl';
|
||||
export default function UpdateMaterial(options) {
|
||||
const material = new Material({
|
||||
uniforms: {
|
||||
u_wind_max: { value: options.u_wind_max },
|
||||
u_particles_res: { value: options.u_particles_res },
|
||||
u_wind_min: { value: options.u_wind_min },
|
||||
u_opacity: { value: options.u_opacity },
|
||||
u_wind: { value: options.u_wind },
|
||||
u_particles: { value: options.u_particles },
|
||||
u_drop_rate_bump: { value: options.u_drop_rate_bump },
|
||||
u_drop_rate: { value: options.u_drop_rate },
|
||||
u_speed_factor: { value: options.u_speed_factor },
|
||||
u_rand_seed: { value: options.u_rand_seed },
|
||||
u_extent: { value: options.u_extent },
|
||||
u_wind_res: { value: options.u_wind_res }
|
||||
},
|
||||
vertexShader: quad_vert,
|
||||
fragmentShader: update_frag,
|
||||
transparent: true
|
||||
});
|
||||
// material.blending = THREE.AdditiveBlending
|
||||
return material;
|
||||
}
|
|
@ -1,76 +0,0 @@
|
|||
precision highp float;
|
||||
|
||||
uniform sampler2D u_particles;
|
||||
uniform sampler2D u_wind;
|
||||
uniform vec2 u_wind_res;
|
||||
uniform vec2 u_wind_min;
|
||||
uniform vec2 u_wind_max;
|
||||
uniform float u_rand_seed;
|
||||
uniform float u_speed_factor;
|
||||
uniform float u_drop_rate;
|
||||
uniform float u_drop_rate_bump;
|
||||
uniform vec4 u_extent;
|
||||
uniform float u_particles_res;
|
||||
|
||||
varying vec2 v_texCoord;
|
||||
|
||||
// pseudo-random generator
|
||||
const vec3 rand_constants = vec3(12.9898, 78.233, 4375.85453);
|
||||
float rand(const vec2 co) {
|
||||
float t = dot(rand_constants.xy, co);
|
||||
return fract(sin(t) * (rand_constants.z + t));
|
||||
}
|
||||
|
||||
// wind speed lookup; use manual bilinear filtering based on 4 adjacent pixels for smooth interpolation
|
||||
vec2 lookup_wind(const vec2 uv) {
|
||||
// return texture2D(u_wind, uv).rg; // lower-res hardware filtering
|
||||
vec2 px = 1.0 / u_wind_res;
|
||||
vec2 vc = (floor(uv * u_wind_res)) * px;
|
||||
vec2 f = fract(uv * u_wind_res);
|
||||
vec2 tl = texture2D(u_wind, vc).rg;
|
||||
vec2 tr = texture2D(u_wind, vc + vec2(px.x, 0)).rg;
|
||||
vec2 bl = texture2D(u_wind, vc + vec2(0, px.y)).rg;
|
||||
vec2 br = texture2D(u_wind, vc + px).rg;
|
||||
return mix(mix(tl, tr, f.x), mix(bl, br, f.x), f.y);
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec4 color = texture2D(u_particles, v_texCoord);
|
||||
vec2 pos = vec2(
|
||||
color.r / 255.0 + color.b,
|
||||
color.g / 255.0 + color.a); // decode particle position from pixel RGBA
|
||||
|
||||
vec2 velocity = mix(u_wind_min, u_wind_max, lookup_wind(pos));
|
||||
float speed_t = length(velocity) / length(u_wind_max);
|
||||
|
||||
// pos = pos + vec2(0.001,0.001);
|
||||
// take EPSG:4236 distortion into account for calculating where the particle moved
|
||||
// float y = u_extent.w - pos.y * (u_extent.w - u_extent.y);
|
||||
// float distortion = cos(radians(y));
|
||||
// vec2 offset = vec2(velocity.x / distortion, -velocity.y) * 0.0001 * u_speed_factor;
|
||||
|
||||
// take EPSG:4236 distortion into account for calculating where the particle moved
|
||||
float distortion = cos(radians(pos.y * 180.0 - 90.0));
|
||||
vec2 offset = vec2(velocity.x / distortion, -velocity.y) * 0.0001 * u_speed_factor;
|
||||
// vec2 offset = vec2(velocity.x / distortion, -velocity.y) * 0.0001 * u_speed_factor;
|
||||
|
||||
// update particle position, wrapping around the date line
|
||||
pos = fract(1.0 + pos + offset);
|
||||
|
||||
// // a random seed to use for the particle drop
|
||||
vec2 seed = (pos + v_texCoord) * u_rand_seed;
|
||||
|
||||
// drop rate is a chance a particle will restart at random position, to avoid degeneration
|
||||
float drop_rate = u_drop_rate + speed_t * u_drop_rate_bump;
|
||||
float drop = step(1.0 - drop_rate, rand(seed));
|
||||
|
||||
vec2 random_pos = vec2(
|
||||
rand(seed + 1.3),
|
||||
rand(seed + 2.1));
|
||||
pos = mix(pos, random_pos, drop);
|
||||
|
||||
// encode the new particle position back into RGBA
|
||||
gl_FragColor = vec4(
|
||||
fract(pos * 255.0),
|
||||
floor(pos * 255.0) / 255.0);
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
|
||||
import image_vert from './wind_vert.glsl';
|
||||
import image_frag from './wind_frag.glsl';
|
||||
import Material from '../../../geom/material/material';
|
||||
export default function WindMaterial(options) {
|
||||
const material = new Material({
|
||||
uniforms: {
|
||||
u_texture: { value: options.u_texture },
|
||||
u_opacity: { value: options.u_opacity }
|
||||
},
|
||||
vertexShader: image_vert,
|
||||
fragmentShader: image_frag,
|
||||
transparent: true
|
||||
});
|
||||
// material.blending = THREE.AdditiveBlending
|
||||
return material;
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
precision mediump float;
|
||||
uniform sampler2D u_texture;
|
||||
uniform float u_opacity;
|
||||
varying vec2 v_texCoord;
|
||||
|
||||
void main() {
|
||||
if(u_opacity == 0.0)
|
||||
discard;
|
||||
gl_FragColor = texture2D(u_texture,1.0 - v_texCoord) * u_opacity;
|
||||
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
precision highp float;
|
||||
varying vec2 v_texCoord;
|
||||
void main() {
|
||||
v_texCoord = uv;
|
||||
gl_Position = vec4(1.0 - 2.0 * vec2(position), 0., 1.0);
|
||||
}
|
|
@ -1,15 +1,20 @@
|
|||
import * as THREE from './three';
|
||||
import EventEmitter from 'wolfy87-eventemitter';
|
||||
import { getImage } from '../util/ajax';
|
||||
export default class LoadImage {
|
||||
// 将图片标注绘制在512*512的画布上,每个大小 64*64 支持 64种图片
|
||||
export default class LoadImage extends EventEmitter {
|
||||
constructor() {
|
||||
|
||||
this.canvas = document.createElement('canvas');
|
||||
this.ctx = this.canvas.getContext('2d');
|
||||
super();
|
||||
this.imageWidth = 64;
|
||||
this.canvas = document.createElement('canvas');
|
||||
this.canvas.style.cssText += 'height: 512px;width: 512px;';
|
||||
this.canvas.width = this.imageWidth * 8;
|
||||
this.canvas.height = this.imageWidth * 8;
|
||||
this.ctx = this.canvas.getContext('2d');
|
||||
|
||||
|
||||
this.images = [];
|
||||
this.imagesCount = -1;
|
||||
this.imagesCount = 0;
|
||||
this.imagePos = {};
|
||||
}
|
||||
addImage(id, opt) {
|
||||
|
@ -17,18 +22,21 @@ export default class LoadImage {
|
|||
const imageCount = this.imagesCount;
|
||||
const x = imageCount % 8 * 64;
|
||||
const y = parseInt(imageCount / 8) * 64;
|
||||
|
||||
this.imagePos[id] = { x: x / 512, y: y / 512 };
|
||||
this.texture = new THREE.Texture(this.canvas);
|
||||
if (typeof opt === 'string') {
|
||||
getImage({ url: opt }, (err, img) => {
|
||||
img.id = id;
|
||||
this.images.push(img);
|
||||
this.ctx.drawImage(img, x, y, 64, 64);
|
||||
const texture = new THREE.Texture(this.canvas);
|
||||
texture.magFilter = THREE.LinearFilter;
|
||||
texture.minFilter = THREE.LinearFilter;
|
||||
texture.needsUpdate = true;
|
||||
this.texture = texture;
|
||||
this.imagePos[id] = { x: x / 512, y: y / 512 };
|
||||
|
||||
this.texture.magFilter = THREE.LinearFilter;
|
||||
this.texture.minFilter = THREE.LinearFilter;
|
||||
this.texture.needsUpdate = true;
|
||||
|
||||
if (this.images.length === this.imagesCount) {
|
||||
this.emit('imageLoaded');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
const { width, height, channels } = opt;
|
||||
|
@ -40,8 +48,11 @@ export default class LoadImage {
|
|||
image.id = id;
|
||||
this.images.push(image);
|
||||
this.ctx.drawImage(image, x, y, 64, 64);
|
||||
this.texture = new CanvasTexture(this.canvas);
|
||||
this.texture = new THREE.CanvasTexture(this.canvas);
|
||||
this.imagePos[id] = { x: x >> 9, y: y >> 9 };
|
||||
if (this.images.length === this.imagesCount) {
|
||||
this.emit('imageLoaded');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@ import Base from './base';
|
|||
import * as THREE from './three';
|
||||
import ColorUtil from '../attr/color-util';
|
||||
import * as source from '../source/index';
|
||||
import * as turfMeta from '@turf/meta';
|
||||
import PickingMaterial from '../core/engine/picking/pickingMaterial';
|
||||
import Attr from '../attr/index';
|
||||
import Util from '../util';
|
||||
|
@ -37,15 +36,18 @@ export default class Layer extends Base {
|
|||
attrs: {},
|
||||
// 样式配置项
|
||||
styleOptions: {
|
||||
stroke: 'rgb(255,255,255)',
|
||||
stroke: [ 1.0, 1.0, 1.0, 1.0 ],
|
||||
strokeWidth: 1.0,
|
||||
opacity: 1.0
|
||||
opacity: 1.0,
|
||||
texture: false
|
||||
},
|
||||
// 选中时的配置项
|
||||
selectedOptions: null,
|
||||
// active 时的配置项
|
||||
activedOptions: null,
|
||||
animateOptions: null
|
||||
animateOptions: {
|
||||
enable: false
|
||||
}
|
||||
};
|
||||
}
|
||||
constructor(scene, cfg) {
|
||||
|
@ -59,23 +61,37 @@ export default class Layer extends Base {
|
|||
const layerId = this._getUniqueId();
|
||||
this.layerId = layerId;
|
||||
this._activeIds = null;
|
||||
// todo 用户参数
|
||||
this._object3D.position.z = layerId * 1000;
|
||||
scene._engine._scene.add(this._object3D);
|
||||
this.layerMesh = null;
|
||||
|
||||
}
|
||||
/**
|
||||
* 将图层添加加到Object
|
||||
* @param {*} object
|
||||
* 将图层添加加到 Object
|
||||
* @param {*} object three 物体
|
||||
*/
|
||||
add(object) {
|
||||
this.layerMesh = object;
|
||||
this._visibleWithZoom();
|
||||
this.scene.on('zoomchange', () => {
|
||||
this._visibleWithZoom();
|
||||
});
|
||||
|
||||
this.layerMesh.onBeforeRender = () => {
|
||||
const zoom = this.scene.getZoom();
|
||||
this.layerMesh.material.setUniformsValue('u_time', this.scene._engine.clock.getElapsedTime());
|
||||
this.layerMesh.material.setUniformsValue('u_zoom', zoom);
|
||||
|
||||
};
|
||||
// 更新
|
||||
if (this._needUpdateFilter) {
|
||||
this._updateFilter();
|
||||
}
|
||||
this._object3D.add(object);
|
||||
this._addPickMesh(object);
|
||||
}
|
||||
remove(object) {
|
||||
this._object3D.remove(object);
|
||||
|
||||
}
|
||||
_getUniqueId() {
|
||||
return id++;
|
||||
|
@ -89,11 +105,13 @@ export default class Layer extends Base {
|
|||
const { type = dataType } = cfg;
|
||||
cfg.data = data;
|
||||
cfg.mapType = this.get('mapType');
|
||||
|
||||
this.layerSource = new source[type](cfg);
|
||||
|
||||
return this;
|
||||
}
|
||||
color(field, values) {
|
||||
this._needUpdateColor = true;// 标识颜色是否需要更新
|
||||
this._createAttrOption('color', field, values, Global.colors);
|
||||
return this;
|
||||
}
|
||||
|
@ -136,7 +154,7 @@ export default class Layer extends Base {
|
|||
}
|
||||
|
||||
style(field, cfg) {
|
||||
const colorItem = [ 'fill', 'stroke' ];
|
||||
const colorItem = [ 'fill', 'stroke', 'color', 'baseColor', 'brightColor', 'windowColor' ];
|
||||
let styleOptions = this.get('styleOptions');
|
||||
if (!styleOptions) {
|
||||
styleOptions = {};
|
||||
|
@ -153,7 +171,7 @@ export default class Layer extends Base {
|
|||
styleOptions.fields = fields;
|
||||
Util.assign(styleOptions, cfg);
|
||||
for (const item in cfg) {
|
||||
if (colorItem.indexOf(item) != -1) {
|
||||
if (colorItem.indexOf(item) !== -1) {
|
||||
styleOptions[item] = ColorUtil.color2RGBA(styleOptions[item]);
|
||||
}
|
||||
styleOptions[item] = styleOptions[item];
|
||||
|
@ -162,11 +180,27 @@ export default class Layer extends Base {
|
|||
return this;
|
||||
}
|
||||
filter(field, values) {
|
||||
this._needUpdateFilter = true;
|
||||
this._createAttrOption('filter', field, values, true);
|
||||
return this;
|
||||
}
|
||||
animate(callback) {
|
||||
this.set('animateOptions', callback);
|
||||
animate(field, cfg) {
|
||||
let animateOptions = this.get('animateOptions');
|
||||
if (!animateOptions) {
|
||||
animateOptions = {};
|
||||
this.set('animateOptions', animateOptions);
|
||||
}
|
||||
if (Util.isObject(field)) {
|
||||
cfg = field;
|
||||
field = null;
|
||||
}
|
||||
let fields;
|
||||
if (field) {
|
||||
fields = parseFields(field);
|
||||
}
|
||||
animateOptions.fields = fields;
|
||||
Util.assign(animateOptions, cfg);
|
||||
this.set('animateOptions', animateOptions);
|
||||
return this;
|
||||
}
|
||||
texture() {
|
||||
|
@ -211,10 +245,12 @@ export default class Layer extends Base {
|
|||
}
|
||||
this._setAttrOptions(attrName, attrCfg);
|
||||
}
|
||||
// 初始化图层
|
||||
init() {
|
||||
this._initAttrs();
|
||||
this._scaleByZoom();
|
||||
this._mapping();
|
||||
|
||||
const activeHander = this._addActiveFeature.bind(this);
|
||||
if (this.get('allowActive')) {
|
||||
|
||||
|
@ -227,53 +263,46 @@ export default class Layer extends Base {
|
|||
|
||||
_addActiveFeature(e) {
|
||||
const { featureId } = e;
|
||||
|
||||
const activeStyle = this.get('activedOptions');
|
||||
const data = this.layerSource.get('data');
|
||||
const selectFeatureIds = [];
|
||||
let featureStyleId = 0;
|
||||
/* eslint-disable */
|
||||
turfMeta.flattenEach(data, (currentFeature, featureIndex, multiFeatureIndex) => {
|
||||
/* eslint-disable */
|
||||
if (featureIndex === featureId) {
|
||||
selectFeatureIds.push(featureStyleId);
|
||||
}
|
||||
featureStyleId++;
|
||||
if (featureIndex > featureId) {
|
||||
return;
|
||||
}
|
||||
});
|
||||
const selectFeatureIds = this.layerSource.getSelectFeatureId(featureId);
|
||||
if (this.StyleData[selectFeatureIds[0]].hasOwnProperty('filter') && this.StyleData[selectFeatureIds[0]].filter === false) { return; }
|
||||
const style = Util.assign({}, this.StyleData[featureId]);
|
||||
style.color = ColorUtil.toRGB(activeStyle.fill).map(e => e / 255);
|
||||
this.updateStyle(selectFeatureIds, style);
|
||||
this.updateStyle([ featureId ], style);
|
||||
}
|
||||
|
||||
|
||||
_initAttrs() {
|
||||
const self = this;
|
||||
const attrs = this.get('attrs');
|
||||
const attrOptions = this.get('attrOptions');
|
||||
for (const type in attrOptions) {
|
||||
if (attrOptions.hasOwnProperty(type)) {
|
||||
const option = attrOptions[type];
|
||||
const className = Util.upperFirst(type);
|
||||
const fields = parseFields(option.field);
|
||||
const scales = [];
|
||||
for (let i = 0; i < fields.length; i++) {
|
||||
const field = fields[i];
|
||||
const scale = self._createScale(field);
|
||||
|
||||
if (type === 'color' && Util.isNil(option.values)) { // 设置 color 的默认色值
|
||||
option.values = Global.colors;
|
||||
}
|
||||
scales.push(scale);
|
||||
}
|
||||
option.scales = scales;
|
||||
const attr = new Attr[className](option);
|
||||
attrs[type] = attr;
|
||||
this._updateAttr(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
_updateAttr(type) {
|
||||
const self = this;
|
||||
const attrs = this.get('attrs');
|
||||
const attrOptions = this.get('attrOptions');
|
||||
const option = attrOptions[type];
|
||||
option.neadUpdate = true;
|
||||
const className = Util.upperFirst(type);
|
||||
const fields = parseFields(option.field);
|
||||
const scales = [];
|
||||
for (let i = 0; i < fields.length; i++) {
|
||||
const field = fields[i];
|
||||
const scale = self._createScale(field);
|
||||
|
||||
if (type === 'color' && Util.isNil(option.values)) { // 设置 color 的默认色值
|
||||
option.values = Global.colors;
|
||||
}
|
||||
scales.push(scale);
|
||||
}
|
||||
option.scales = scales;
|
||||
const attr = new Attr[className](option);
|
||||
attrs[type] = attr;
|
||||
}
|
||||
_updateSize(zoom) {
|
||||
const sizeOption = this.get('attrOptions').size;
|
||||
const fields = parseFields(sizeOption.field);
|
||||
|
@ -303,6 +332,7 @@ export default class Layer extends Base {
|
|||
for (const k in attrs) {
|
||||
if (attrs.hasOwnProperty(k)) {
|
||||
const attr = attrs[k];
|
||||
attr.needUpdate = false;
|
||||
const names = attr.names;
|
||||
const values = self._getAttrValues(attr, record);
|
||||
if (names.length > 1) { // position 之类的生成多个字段的属性
|
||||
|
@ -323,26 +353,30 @@ export default class Layer extends Base {
|
|||
this.StyleData = mappedData;
|
||||
return mappedData;
|
||||
}
|
||||
_updateMap(attrName) {
|
||||
// 更新地图映射
|
||||
_updateMaping() {
|
||||
const self = this;
|
||||
const attrs = self.get('attrs');
|
||||
|
||||
const data = this.layerSource.propertiesData;
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
const record = data[i];
|
||||
if (attrs.hasOwnProperty(attrName)) {
|
||||
const attr = attrs[attrName];
|
||||
const names = attr.names;
|
||||
const values = self._getAttrValues(attr, record);
|
||||
if (names.length > 1) { // position 之类的生成多个字段的属性
|
||||
for (let j = 0; j < values.length; j++) {
|
||||
const val = values[j];
|
||||
const name = names[j];
|
||||
this.StyleData[i][name] = (Util.isArray(val) && val.length === 1) ? val[0] : val; // 只有一个值时返回第一个属性值
|
||||
}
|
||||
} else {
|
||||
this.StyleData[i][names[0]] = values.length === 1 ? values[0] : values;
|
||||
for (const attrName in attrs) {
|
||||
if (attrs.hasOwnProperty(attrName) && attrs[attrName].neadUpdate) {
|
||||
const attr = attrs[attrName];
|
||||
const names = attr.names;
|
||||
const values = self._getAttrValues(attr, record);
|
||||
if (names.length > 1) { // position 之类的生成多个字段的属性
|
||||
for (let j = 0; j < values.length; j++) {
|
||||
const val = values[j];
|
||||
const name = names[j];
|
||||
this.StyleData[i][name] = (Util.isArray(val) && val.length === 1) ? val[0] : val; // 只有一个值时返回第一个属性值
|
||||
}
|
||||
} else {
|
||||
this.StyleData[i][names[0]] = values.length === 1 ? values[0] : values;
|
||||
|
||||
}
|
||||
attr.neadUpdate = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -385,17 +419,17 @@ export default class Layer extends Base {
|
|||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param {*} overwrite
|
||||
* @param {*} callback
|
||||
*
|
||||
* @param {*} overwrite
|
||||
* @param {*} callback
|
||||
*/
|
||||
on(type,callback) {
|
||||
on(type, callback) {
|
||||
|
||||
this._addPickingEvents();
|
||||
super.on(type, callback);
|
||||
}
|
||||
getPickingId() {
|
||||
return this.scene._engine._picking.getNextId();
|
||||
return this.scene._engine._picking.getNextId();
|
||||
}
|
||||
addToPicking(object) {
|
||||
this.scene._engine._picking.add(object);
|
||||
|
@ -403,11 +437,24 @@ export default class Layer extends Base {
|
|||
removeFromPicking(object) {
|
||||
this.scene._engine._picking.remove(object);
|
||||
}
|
||||
_addPickMesh(mesh){
|
||||
_addPickMesh(mesh) {
|
||||
this._pickingMesh = new THREE.Object3D();
|
||||
this._visibleWithZoom();
|
||||
this.scene.on('zoomchange', () => {
|
||||
this._visibleWithZoom();
|
||||
});
|
||||
|
||||
this.addToPicking(this._pickingMesh);
|
||||
const pickmaterial = new PickingMaterial();
|
||||
const pickmaterial = new PickingMaterial({
|
||||
u_zoom: this.scene.getZoom()
|
||||
});
|
||||
|
||||
const pickingMesh = new THREE[mesh.type](mesh.geometry, pickmaterial);
|
||||
pickmaterial.setDefinesvalue(this.type, true);
|
||||
pickingMesh.onBeforeRender = () => {
|
||||
const zoom = this.scene.getZoom();
|
||||
pickingMesh.material.setUniformsValue('u_zoom', zoom);
|
||||
};
|
||||
this._pickingMesh.add(pickingMesh);
|
||||
}
|
||||
_setPickingId() {
|
||||
|
@ -415,9 +462,20 @@ export default class Layer extends Base {
|
|||
}
|
||||
_addPickingEvents() {
|
||||
// TODO: Find a way to properly remove this listener on destroy
|
||||
this.scene.on('pick', (point2d, point3d, intersects) => {
|
||||
this.scene.on('pick', e => {
|
||||
// Re-emit click event from the layer
|
||||
this.emit('click', this, point2d, point3d, intersects);
|
||||
const { featureId, point2d, point3d, intersects } = e;
|
||||
if (intersects.length === 0) { return; }
|
||||
const source = this.layerSource.get('data');
|
||||
const feature = source.features[featureId];
|
||||
const lnglat = this.scene.containerToLngLat(point2d);
|
||||
const target = {
|
||||
feature,
|
||||
pixel: point2d,
|
||||
lnglat: { lng: lnglat.lng, lat: lnglat.lat }
|
||||
};
|
||||
this.emit('click', target);
|
||||
// this.emit('move', target);
|
||||
});
|
||||
}
|
||||
/**
|
||||
|
@ -426,126 +484,123 @@ export default class Layer extends Base {
|
|||
* @param {*} style 更新的要素样式
|
||||
*/
|
||||
updateStyle(featureStyleId, style) {
|
||||
const {indices} = this.buffer.bufferStruct;
|
||||
|
||||
if (this._activeIds) {
|
||||
this.resetStyle();
|
||||
}
|
||||
this._activeIds = featureStyleId;
|
||||
|
||||
const id = featureStyleId[0];
|
||||
let dataIndex = 0;
|
||||
if(indices){
|
||||
// 面图层和
|
||||
for (let i = 0; i < id; i++) {
|
||||
dataIndex += indices[i].length;
|
||||
}
|
||||
} else {
|
||||
dataIndex = id;
|
||||
}
|
||||
|
||||
featureStyleId.forEach((index,value) => {
|
||||
let vertindex =[value]
|
||||
if(indices)
|
||||
vertindex = indices[index];
|
||||
const color = style.color;
|
||||
const colorAttr =this.layerMesh.geometry.attributes.a_color;
|
||||
colorAttr.dynamic =true;
|
||||
vertindex.forEach(() => {
|
||||
colorAttr.array[dataIndex*4+0]=color[0];
|
||||
colorAttr.array[dataIndex*4+1]=color[1];
|
||||
colorAttr.array[dataIndex*4+2]=color[2];
|
||||
colorAttr.array[dataIndex*4+3]=color[3];
|
||||
dataIndex++;
|
||||
});
|
||||
colorAttr.needsUpdate =true
|
||||
});
|
||||
const pickingId = this.layerMesh.geometry.attributes.pickingId.array;
|
||||
const color = style.color;
|
||||
const colorAttr = this.layerMesh.geometry.attributes.a_color;
|
||||
const firstId = pickingId.indexOf(featureStyleId[0] + 1);
|
||||
for (let i = firstId; i < pickingId.length; i++) {
|
||||
if (pickingId[i] == featureStyleId[0] + 1) {
|
||||
colorAttr.array[i * 4 + 0] = color[0];
|
||||
colorAttr.array[i * 4 + 1] = color[1];
|
||||
colorAttr.array[i * 4 + 2] = color[2];
|
||||
colorAttr.array[i * 4 + 3] = color[3];
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
colorAttr.needsUpdate = true;
|
||||
return;
|
||||
}
|
||||
|
||||
_updateColor() {
|
||||
|
||||
this._updateMaping();
|
||||
|
||||
}
|
||||
/**
|
||||
* 用于过滤数据
|
||||
* @param {*} filterData 数据过滤标识符
|
||||
*/
|
||||
updateFilter(filterData) {
|
||||
_updateFilter() {
|
||||
this._updateMaping();
|
||||
const filterData = this.StyleData;
|
||||
this._activeIds = null; // 清空选中元素
|
||||
let dataIndex = 0;
|
||||
const colorAttr = this.layerMesh.geometry.attributes.a_color;
|
||||
if(this.layerMesh.type =='Points'){ //点图层更新
|
||||
filterData.forEach((item,index)=>{
|
||||
const color = [ ...this.StyleData[index].color ];
|
||||
if (item.hasOwnProperty('filter') && item.filter === false) {
|
||||
color[3] = 0;
|
||||
}
|
||||
colorAttr.array[index*4+0]=color[0];
|
||||
colorAttr.array[index*4+1]=color[1];
|
||||
colorAttr.array[index*4+2]=color[2];
|
||||
colorAttr.array[index*4+3]=color[3];
|
||||
})
|
||||
colorAttr.needsUpdate =true;
|
||||
return;
|
||||
}
|
||||
const {indices} = this.buffer.bufferStruct;
|
||||
indices.forEach((vertIndexs, i) => {
|
||||
const color = [ ...this.StyleData[i].color ];
|
||||
if (filterData[i].hasOwnProperty('filter') && filterData[i].filter === false) {
|
||||
color[3] = 0;
|
||||
const colorAttr = this.layerMesh.geometry.attributes.a_color;
|
||||
const pickAttr = this.layerMesh.geometry.attributes.pickingId;
|
||||
pickAttr.array.forEach((id, index) => {
|
||||
id = Math.abs(id);
|
||||
const color = [ ...this.StyleData[id - 1].color ];
|
||||
id = Math.abs(id);
|
||||
const item = filterData[id - 1];
|
||||
if (item.hasOwnProperty('filter') && item.filter === false) {
|
||||
colorAttr.array[index * 4 + 0] = 0;
|
||||
colorAttr.array[index * 4 + 1] = 0;
|
||||
colorAttr.array[index * 4 + 2] = 0;
|
||||
colorAttr.array[index * 4 + 3] = 0;
|
||||
pickAttr.array[index] = -id;
|
||||
} else {
|
||||
colorAttr.array[index * 4 + 0] = color[0];
|
||||
colorAttr.array[index * 4 + 1] = color[1];
|
||||
colorAttr.array[index * 4 + 2] = color[2];
|
||||
colorAttr.array[index * 4 + 3] = color[3];
|
||||
pickAttr.array[index] = id;
|
||||
}
|
||||
|
||||
vertIndexs.forEach(() => {
|
||||
colorAttr.array[dataIndex*4+0]=color[0];
|
||||
colorAttr.array[dataIndex*4+1]=color[1];
|
||||
colorAttr.array[dataIndex*4+2]=color[2];
|
||||
colorAttr.array[dataIndex*4+3]=color[3];
|
||||
dataIndex++;
|
||||
});
|
||||
colorAttr.needsUpdate =true;
|
||||
});
|
||||
colorAttr.needsUpdate = true;
|
||||
pickAttr.needsUpdate = true;
|
||||
this._needUpdateFilter = false;
|
||||
this._needUpdateColor = false;
|
||||
}
|
||||
_visibleWithZoom() {
|
||||
const zoom = this.scene.getZoom();
|
||||
const minZoom = this.get('minZoom');
|
||||
const maxZoom = this.get('maxZoom');
|
||||
// z-fighting
|
||||
let offset = 0;
|
||||
if (this.type === 'point') {
|
||||
offset = 5;
|
||||
} else if (this.type === 'polyline') {
|
||||
offset = 2;
|
||||
}
|
||||
this._object3D.position.z = offset * Math.pow(2, 20 - zoom);
|
||||
if (zoom < minZoom || zoom > maxZoom) {
|
||||
this._object3D.visible = false;
|
||||
} else if (this.get('visible')) {
|
||||
this._object3D.visible = true;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 重置高亮要素
|
||||
*/
|
||||
resetStyle() {
|
||||
const {indices} = this.buffer.bufferStruct;
|
||||
const colorAttr = this.layerMesh.geometry.attributes.a_color;
|
||||
let dataIndex = 0;
|
||||
const id = this._activeIds[0];
|
||||
if(indices){
|
||||
for (let i = 0; i < id; i++) {
|
||||
dataIndex += indices[i].length;
|
||||
}
|
||||
} else {
|
||||
dataIndex = id;
|
||||
}
|
||||
this._activeIds.forEach((index,value) => {
|
||||
const pickingId = this.layerMesh.geometry.attributes.pickingId.array;
|
||||
const colorAttr = this.layerMesh.geometry.attributes.a_color;
|
||||
this._activeIds.forEach((index, value) => {
|
||||
const color = this.StyleData[index].color;
|
||||
let vertindex = [value];
|
||||
if(indices){
|
||||
vertindex = indices[index];
|
||||
const firstId = pickingId.indexOf(index + 1);
|
||||
for (let i = firstId; i < pickingId.length; i++) {
|
||||
if (pickingId[i] == index + 1) {
|
||||
colorAttr.array[i * 4 + 0] = color[0];
|
||||
colorAttr.array[i * 4 + 1] = color[1];
|
||||
colorAttr.array[i * 4 + 2] = color[2];
|
||||
colorAttr.array[i * 4 + 3] = color[3];
|
||||
}
|
||||
}
|
||||
vertindex.forEach(() => {
|
||||
colorAttr.array[dataIndex*4+0]=color[0];
|
||||
colorAttr.array[dataIndex*4+1]=color[1];
|
||||
colorAttr.array[dataIndex*4+2]=color[2];
|
||||
colorAttr.array[dataIndex*4+3]=color[3];
|
||||
dataIndex++;
|
||||
});
|
||||
colorAttr.needsUpdate =true
|
||||
});
|
||||
colorAttr.needsUpdate = true;
|
||||
}
|
||||
destroy() {
|
||||
if(this._object3D && this._object3D.children){
|
||||
/**
|
||||
* 销毁Layer对象
|
||||
*/
|
||||
despose() {
|
||||
this.destroy();
|
||||
if (this._object3D && this._object3D.children) {
|
||||
let child;
|
||||
for(let i =0;i<this._object3D.children.length;i++){
|
||||
child = this._object3D.children[i];
|
||||
if(!child){
|
||||
continue;
|
||||
}
|
||||
this.remove(child);
|
||||
if(child.geometry){
|
||||
child.geometry.dispose();
|
||||
child.geometry = null;
|
||||
}
|
||||
if (child.material) {
|
||||
for (let i = 0; i < this._object3D.children.length; i++) {
|
||||
child = this._object3D.children[i];
|
||||
if (!child) {
|
||||
continue;
|
||||
}
|
||||
this.remove(child);
|
||||
if (child.geometry) {
|
||||
child.geometry.dispose();
|
||||
child.geometry = null;
|
||||
}
|
||||
if (child.material) {
|
||||
if (child.material.map) {
|
||||
child.material.map.dispose();
|
||||
child.material.map = null;
|
||||
|
@ -556,7 +611,7 @@ export default class Layer extends Base {
|
|||
}
|
||||
}
|
||||
}
|
||||
this._object3D =null;
|
||||
this._object3D = null;
|
||||
this.scene = null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,10 +3,8 @@ import * as THREE from './three';
|
|||
import * as layers from '../layer';
|
||||
import Base from './base';
|
||||
import LoadImage from './image';
|
||||
import Utils from '../util';
|
||||
import { MapProvider } from '../map/provider';
|
||||
import { MapBox } from '../map/mapbox';
|
||||
import AMap from '../map/AMap';
|
||||
import GaodeMap from '../map/gaodeMap';
|
||||
import Global from '../global';
|
||||
export default class Scene extends Base {
|
||||
getDefaultCfg() {
|
||||
|
@ -15,6 +13,7 @@ export default class Scene extends Base {
|
|||
constructor(cfg) {
|
||||
super(cfg);
|
||||
this._initMap();
|
||||
this._initAttribution();
|
||||
this.addImage();
|
||||
this._layers = [];
|
||||
}
|
||||
|
@ -28,26 +27,20 @@ export default class Scene extends Base {
|
|||
this._engine._picking.add(object);
|
||||
}
|
||||
_initMap() {
|
||||
const mapType = this.mapType = this.get('mapType');
|
||||
this.mapContainer = this.get('id');
|
||||
this._container = document.getElementById(this.mapContainer);
|
||||
let Map = null;
|
||||
if (mapType === 'mapbox') {
|
||||
Map = new MapBox(this.mapContainer, this.get('map'));
|
||||
|
||||
} else {
|
||||
Map = new MapProvider(this.mapContainer, this._attrs);
|
||||
}
|
||||
const Map = new MapProvider(this.mapContainer, this._attrs);
|
||||
Map.on('mapLoad', () => {
|
||||
this._initEngine(Map.renderDom);
|
||||
const sceneMap = new AMap(Map.map);
|
||||
Utils.assign(this.__proto__, sceneMap.__proto__);
|
||||
const sceneMap = new GaodeMap(Map.map);
|
||||
// eslint-disable-next-line
|
||||
Object.getOwnPropertyNames(sceneMap.__proto__).forEach((key)=>{
|
||||
if ('key' !== 'constructor') { this.__proto__[key] = sceneMap.__proto__[key]; }
|
||||
});
|
||||
this.map = Map.map;
|
||||
Map.asyncCamera(this._engine);
|
||||
// this._addLight();
|
||||
this.initLayer();
|
||||
// this.zoomAsync();
|
||||
this.emit('load');
|
||||
this.emit('loaded');
|
||||
});
|
||||
|
||||
}
|
||||
|
@ -61,11 +54,26 @@ export default class Scene extends Base {
|
|||
};
|
||||
}
|
||||
}
|
||||
on(type, hander) {
|
||||
if (this.map) { this.map.on(type, hander); }
|
||||
super.on(type, hander);
|
||||
}
|
||||
_initAttribution() {
|
||||
const message = '<a href="http://antv.alipay.com/zh-cn/index.html title="Large-scale WebGL-powered Geospatial Data Visualization">AntV | L7 </a>';
|
||||
const element = document.createElement('div');
|
||||
|
||||
element.innerHTML = message;
|
||||
element.style.cssText += 'position: absolute; pointer-events:none;background: rgba(255, 255, 255, 0.7);font-size: 11px;z-index:100; padding:4px;bottom: 0;right:0px;';
|
||||
this._container.appendChild(element);
|
||||
}
|
||||
addImage() {
|
||||
this.image = new LoadImage();
|
||||
}
|
||||
_initEvent() {
|
||||
|
||||
}
|
||||
getLayers() {
|
||||
return this._layers;
|
||||
}
|
||||
_addLight() {
|
||||
const scene = this._engine._scene;
|
||||
|
|
|
@ -1,101 +0,0 @@
|
|||
import Engine from './engine';
|
||||
import * as layers from '../layer';
|
||||
import Base from './base';
|
||||
import ImageData from './image';
|
||||
import ModelData from './model';
|
||||
import { MapProvider } from '../map/provider';
|
||||
import { MapBox } from '../map/mapbox';
|
||||
/**
|
||||
* const scene = new L7.Scene({
|
||||
* container:'',
|
||||
*
|
||||
* map:{
|
||||
* }
|
||||
* })
|
||||
*/
|
||||
export default class Scene extends Base {
|
||||
getDefaultCfg() {
|
||||
return {
|
||||
mapType: 'AMAP'
|
||||
};
|
||||
}
|
||||
constructor(cfg) {
|
||||
super(cfg);
|
||||
this.mapContainer = this.get('id');
|
||||
this.layers = [];
|
||||
this.render = new Render();
|
||||
this._engine = new Engine(this.mapContainer);
|
||||
this.initMap();
|
||||
this.addImage();
|
||||
this.addModel(this.render);
|
||||
|
||||
}
|
||||
initMap() {
|
||||
const mapType = this.mapType = this.get('mapType');
|
||||
let Map = null;
|
||||
if (mapType === 'mapbox') {
|
||||
Map = new MapBox(this.mapContainer, this.get('map'));
|
||||
|
||||
} else {
|
||||
Map = new MapProvider(this.mapContainer, this.get('map'));
|
||||
}
|
||||
Map.on('mapLoad', () => {
|
||||
this.renderCanvas = Map.canvas;
|
||||
this.map = Map.map;
|
||||
this.render.initScene(this.renderCanvas);
|
||||
this.addModel();
|
||||
Map.asyncCamera(this.render.camera, this.render.cameraNode, this.render.layerNode);
|
||||
this.initLayer();
|
||||
this.zoomAsync();
|
||||
this.emit('load');
|
||||
});
|
||||
|
||||
}
|
||||
initLayer() {
|
||||
for (const methodName in layers) {
|
||||
this[methodName] = cfg => {
|
||||
cfg ? cfg.mapType = this.mapType : cfg = { mapType: this.mapType };
|
||||
const layer = new layers[methodName](this, cfg);
|
||||
this.layers.push(layer);
|
||||
return layer;
|
||||
};
|
||||
}
|
||||
}
|
||||
removeLayer(layer) {
|
||||
layer.layerNode.destroy();
|
||||
this.layers = this.layers.filter(item => {
|
||||
return item.layerId != layer.layerId;
|
||||
});
|
||||
}
|
||||
getLayers() {
|
||||
return this.layers;
|
||||
}
|
||||
getLayer() {
|
||||
|
||||
}
|
||||
addImage() {
|
||||
this.image = new ImageData();
|
||||
}
|
||||
addModel() {
|
||||
this.Model = new ModelData(this.render);
|
||||
}
|
||||
zoomAsync() {
|
||||
this.map.on('zoomend', () => {
|
||||
this.layers.forEach(layer => {
|
||||
const id = layer.layerId;
|
||||
const layerNode = this.render.layerNode.findChildByName(id);
|
||||
const zoom = this.map.getZoom();
|
||||
const minZoom = layer.get('minZoom');
|
||||
const maxZoom = layer.get('maxZoom');
|
||||
if (zoom < minZoom || zoom > maxZoom) {
|
||||
layerNode.isActive = false;
|
||||
} else {
|
||||
layerNode.isActive = true;
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -2,12 +2,11 @@
|
|||
* @Author: ThinkGIS
|
||||
* @Date: 2018-06-08 11:19:06
|
||||
* @Last Modified by: mikey.zhaopeng
|
||||
* @Last Modified time: 2018-10-23 16:20:56
|
||||
* @Last Modified time: 2018-11-01 11:50:43
|
||||
*/
|
||||
const Base = require('./base');
|
||||
import Base from './base';
|
||||
const Controller = require('./controller/index');
|
||||
import { aProjectFlat } from '../geo/project';
|
||||
const MAXZOOM = 0;
|
||||
export default class Source extends Base {
|
||||
getDefaultCfg() {
|
||||
return {
|
||||
|
@ -83,14 +82,9 @@ export default class Source extends Base {
|
|||
});
|
||||
}
|
||||
_coorConvert(geo) {
|
||||
const maptype = this.get('mapType');
|
||||
if (maptype === 'AMAP') {
|
||||
const ll = aProjectFlat(geo);
|
||||
return [ ll.x, -ll.y, geo[2] || 0 ];
|
||||
}
|
||||
|
||||
// const ll = projectFlat(geo, Math.pow(2, MAXZOOM));
|
||||
// return [ ll[0], -ll[1], geo[2] || 0 ];
|
||||
const ll = aProjectFlat(geo);
|
||||
return [ ll.x, -ll.y, geo[2] || 0 ];
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ export { Scene } from 'three/src/scenes/Scene.js';
|
|||
export { WebGLRenderer } from 'three/src/renderers/WebGLRenderer.js';
|
||||
export { CanvasTexture } from 'three/src/textures/CanvasTexture.js';
|
||||
export { Object3D } from 'three/src/core/Object3D.js';
|
||||
export { Clock } from 'three/src/core/Clock';
|
||||
export { Points } from 'three/src/objects/Points.js';
|
||||
export { LineSegments } from 'three/src/objects/LineSegments.js';
|
||||
export { Mesh } from 'three/src/objects/Mesh.js';
|
||||
|
@ -39,3 +40,5 @@ export {
|
|||
Int8BufferAttribute,
|
||||
BufferAttribute
|
||||
} from 'three/src/core/BufferAttribute.js';
|
||||
|
||||
// export * from '../../build/Three.js';
|
||||
|
|
|
@ -15,4 +15,3 @@ export function aProjectFlat(lnglat) {
|
|||
y = scale * (c * y + d) - 106744817;
|
||||
return { x, y };
|
||||
}
|
||||
|
||||
|
|
|
@ -69,24 +69,12 @@ export default class BufferBase extends Base {
|
|||
const normals = new Float32Array(indexCount * 3);
|
||||
const colors = new Float32Array(indexCount * 4);
|
||||
const pickingIds = new Float32Array(indexCount);
|
||||
|
||||
// TODO:拾取
|
||||
// const pickingIds;
|
||||
// if (polygon.pickingId) {
|
||||
// // One component per vertex per face (1 x 3 = 3)
|
||||
// pickingIds = new Float32Array(polygon.facesCount * 3);
|
||||
// }
|
||||
|
||||
const pA = new THREE.Vector3();
|
||||
const pB = new THREE.Vector3();
|
||||
const pC = new THREE.Vector3();
|
||||
|
||||
const cb = new THREE.Vector3();
|
||||
const ab = new THREE.Vector3();
|
||||
|
||||
let index;
|
||||
|
||||
|
||||
let lastIndex = 0;
|
||||
indices.forEach((indice, pIndex) => {
|
||||
for (let i = 0; i < indice.length / 3; i++) {
|
||||
|
@ -96,24 +84,15 @@ export default class BufferBase extends Base {
|
|||
const ax = position[pIndex][index][0];
|
||||
const ay = position[pIndex][index][1];
|
||||
const az = position[pIndex][index][2];
|
||||
|
||||
|
||||
index = indice[i * 3 + 1];
|
||||
|
||||
const bx = position[pIndex][index][0];
|
||||
const by = position[pIndex][index][1];
|
||||
const bz = position[pIndex][index][2];
|
||||
|
||||
|
||||
index = indice[i * 3 + 2];
|
||||
|
||||
const cx = position[pIndex][index][0];
|
||||
const cy = position[pIndex][index][1];
|
||||
const cz = position[pIndex][index][2];
|
||||
|
||||
|
||||
// Flat face normals
|
||||
// From: http://threejs.org/examples/webgl_buffergeometry.html
|
||||
pA.set(ax, ay, az);
|
||||
pB.set(bx, by, bz);
|
||||
pC.set(cx, cy, cz);
|
||||
|
@ -181,6 +160,142 @@ export default class BufferBase extends Base {
|
|||
normals,
|
||||
colors,
|
||||
pickingIds,
|
||||
faceUv: new Float32Array(polygon.faceUv),
|
||||
sizes: new Float32Array(polygon.sizes)
|
||||
|
||||
};
|
||||
|
||||
return attributes;
|
||||
}
|
||||
_toPointShapeAttributes(polygon) {
|
||||
// Three components per vertex per face (3 x 3 = 9)
|
||||
const { style, indices, position, indexCount, shapes, sizes } = polygon;
|
||||
const vertices = new Float32Array(indexCount * 3);
|
||||
const shapePositions = new Float32Array(indexCount * 3);
|
||||
const a_size = new Float32Array(indexCount * 3);
|
||||
const normals = new Float32Array(indexCount * 3);
|
||||
const colors = new Float32Array(indexCount * 4);
|
||||
const pickingIds = new Float32Array(indexCount);
|
||||
const pA = new THREE.Vector3();
|
||||
const pB = new THREE.Vector3();
|
||||
const pC = new THREE.Vector3();
|
||||
|
||||
const cb = new THREE.Vector3();
|
||||
const ab = new THREE.Vector3();
|
||||
let lastIndex = 0;
|
||||
indices.forEach((indice, pIndex) => {
|
||||
for (let i = 0; i < indice.length / 3; i++) {
|
||||
let index = indice[i * 3];
|
||||
const color = style[pIndex].color;
|
||||
const coor1 = position[pIndex];
|
||||
const size = sizes[pIndex];
|
||||
const _pickingId = style[pIndex].id;
|
||||
const ax = shapes[pIndex][index][0];
|
||||
const ay = shapes[pIndex][index][1];
|
||||
const az = shapes[pIndex][index][2];
|
||||
index = indice[i * 3 + 1];
|
||||
const bx = shapes[pIndex][index][0];
|
||||
const by = shapes[pIndex][index][1];
|
||||
const bz = shapes[pIndex][index][2];
|
||||
index = indice[i * 3 + 2];
|
||||
const cx = shapes[pIndex][index][0];
|
||||
const cy = shapes[pIndex][index][1];
|
||||
const cz = shapes[pIndex][index][2];
|
||||
|
||||
pA.set(ax, ay, az);
|
||||
pB.set(bx, by, bz);
|
||||
pC.set(cx, cy, cz);
|
||||
|
||||
cb.subVectors(pC, pB);
|
||||
ab.subVectors(pA, pB);
|
||||
cb.cross(ab);
|
||||
|
||||
cb.normalize();
|
||||
|
||||
const nx = cb.x;
|
||||
const ny = cb.y;
|
||||
const nz = cb.z;
|
||||
|
||||
vertices[lastIndex * 9 + 0] = coor1[0];
|
||||
vertices[lastIndex * 9 + 1] = coor1[1];
|
||||
vertices[lastIndex * 9 + 2] = coor1[2];
|
||||
|
||||
shapePositions[lastIndex * 9 + 0] = ax;
|
||||
shapePositions[lastIndex * 9 + 1] = ay;
|
||||
shapePositions[lastIndex * 9 + 2] = az;
|
||||
|
||||
a_size[lastIndex * 9 + 0] = size[0];
|
||||
a_size[lastIndex * 9 + 1] = size[1];
|
||||
a_size[lastIndex * 9 + 2] = size[2];
|
||||
|
||||
normals[lastIndex * 9 + 0] = nx;
|
||||
normals[lastIndex * 9 + 1] = ny;
|
||||
normals[lastIndex * 9 + 2] = nz;
|
||||
|
||||
colors[lastIndex * 12 + 0] = color[0];
|
||||
colors[lastIndex * 12 + 1] = color[1];
|
||||
colors[lastIndex * 12 + 2] = color[2];
|
||||
colors[lastIndex * 12 + 3] = color[3];
|
||||
|
||||
|
||||
vertices[lastIndex * 9 + 3] = coor1[0];
|
||||
vertices[lastIndex * 9 + 4] = coor1[1];
|
||||
vertices[lastIndex * 9 + 5] = coor1[2];
|
||||
|
||||
shapePositions[lastIndex * 9 + 3] = bx;
|
||||
shapePositions[lastIndex * 9 + 4] = by;
|
||||
shapePositions[lastIndex * 9 + 5] = bz;
|
||||
|
||||
a_size[lastIndex * 9 + 3] = size[0];
|
||||
a_size[lastIndex * 9 + 4] = size[1];
|
||||
a_size[lastIndex * 9 + 5] = size[2];
|
||||
|
||||
normals[lastIndex * 9 + 3] = nx;
|
||||
normals[lastIndex * 9 + 4] = ny;
|
||||
normals[lastIndex * 9 + 5] = nz;
|
||||
|
||||
colors[lastIndex * 12 + 4] = color[0];
|
||||
colors[lastIndex * 12 + 5] = color[1];
|
||||
colors[lastIndex * 12 + 6] = color[2];
|
||||
colors[lastIndex * 12 + 7] = color[3];
|
||||
|
||||
vertices[lastIndex * 9 + 6] = coor1[0];
|
||||
vertices[lastIndex * 9 + 7] = coor1[1];
|
||||
vertices[lastIndex * 9 + 8] = coor1[2];
|
||||
|
||||
|
||||
a_size[lastIndex * 9 + 6] = size[0];
|
||||
a_size[lastIndex * 9 + 7] = size[1];
|
||||
a_size[lastIndex * 9 + 8] = size[2];
|
||||
|
||||
shapePositions[lastIndex * 9 + 6] = cx;
|
||||
shapePositions[lastIndex * 9 + 7] = cy;
|
||||
shapePositions[lastIndex * 9 + 8] = cz;
|
||||
|
||||
normals[lastIndex * 9 + 6] = nx;
|
||||
normals[lastIndex * 9 + 7] = ny;
|
||||
normals[lastIndex * 9 + 8] = nz;
|
||||
|
||||
colors[lastIndex * 12 + 8] = color[0];
|
||||
colors[lastIndex * 12 + 9] = color[1];
|
||||
colors[lastIndex * 12 + 10] = color[2];
|
||||
colors[lastIndex * 12 + 11] = color[3];
|
||||
|
||||
pickingIds[lastIndex * 3 + 0] = _pickingId;
|
||||
pickingIds[lastIndex * 3 + 1] = _pickingId;
|
||||
pickingIds[lastIndex * 3 + 2] = _pickingId;
|
||||
|
||||
lastIndex++;
|
||||
}
|
||||
});
|
||||
|
||||
const attributes = {
|
||||
vertices,
|
||||
normals,
|
||||
colors,
|
||||
pickingIds,
|
||||
shapePositions,
|
||||
a_size,
|
||||
faceUv: new Float32Array(polygon.faceUv)
|
||||
|
||||
};
|
||||
|
@ -188,7 +303,6 @@ export default class BufferBase extends Base {
|
|||
return attributes;
|
||||
}
|
||||
_toPolygonLineAttributes(polygonline) {
|
||||
console.log(polygonline);
|
||||
const { style, indices, position, indexCount } = polygonline;
|
||||
const vertices = new Float32Array(indexCount * 3);
|
||||
const colors = new Float32Array(indexCount * 4);
|
||||
|
@ -236,7 +350,7 @@ export default class BufferBase extends Base {
|
|||
colors[index * 4 + 2] = style[index].color[2];
|
||||
colors[index * 4 + 3] = style[index].color[3];
|
||||
pickingIds[index] = style[index].id;
|
||||
sizes[index] = style[index].size;
|
||||
sizes[index] = style[index].size * window.devicePixelRatio;
|
||||
if (style[index].shape) { shapes[index] = style[index].shape; }
|
||||
});
|
||||
const attributes = {
|
||||
|
@ -266,7 +380,8 @@ export default class BufferBase extends Base {
|
|||
context.fillRect(x, y, 2, 4);
|
||||
}
|
||||
}
|
||||
|
||||
context.fillStyle = '#105CB3';
|
||||
context.fillRect(0, 60, 32, 64);
|
||||
// build a bigger canvas and copy the small one in it
|
||||
// This is a trick to upscale the texture without filtering
|
||||
const canvas2 = document.createElement('canvas');
|
||||
|
|
|
@ -32,7 +32,7 @@ export default class ImageBuffer extends BufferBase {
|
|||
this.texture = texture;
|
||||
|
||||
}
|
||||
_getTexture(name, image) {
|
||||
_getTexture(image) {
|
||||
const texture = new THREE.Texture(image);
|
||||
texture.magFilter = THREE.LinearFilter;
|
||||
texture.minFilter = THREE.LinearFilter;
|
||||
|
|
|
@ -3,51 +3,120 @@ import { lineShape } from '../shape';
|
|||
|
||||
export default class LineBuffer extends BufferBase {
|
||||
geometryBuffer() {
|
||||
const self = this;
|
||||
const coordinates = self.get('coordinates');
|
||||
const properties = self.get('properties');
|
||||
const propertiesData = self.get('propertiesData');
|
||||
const coordinates = this.get('coordinates');
|
||||
const properties = this.get('properties');
|
||||
const shapeType = this.shapeType = this.get('shapeType');
|
||||
const positions = [];
|
||||
const positionsIndex = [];
|
||||
const instances = [];
|
||||
if (shapeType === 'line') {
|
||||
this.attributes = this._getMeshLineAttributes();
|
||||
return;
|
||||
} else if (shapeType === 'arc') {
|
||||
this.attributes = this._getArcLineAttributes();
|
||||
return;
|
||||
}
|
||||
coordinates.forEach((geo, index) => {
|
||||
const props = properties[index];
|
||||
const attrData = self._getShape(geo, props, index);
|
||||
const attrData = this._getShape(geo, props, index);
|
||||
positions.push(...attrData.positions);
|
||||
positionsIndex.push(...attrData.indexes);
|
||||
if (attrData.hasOwnProperty('instances')) {
|
||||
instances.push(...attrData.instances);
|
||||
}
|
||||
});
|
||||
self.bufferStruct.style = properties;
|
||||
self.bufferStruct.verts = positions;
|
||||
self.bufferStruct.indexs = positionsIndex;
|
||||
self.shape = properties[0].shape || 'default';
|
||||
this.bufferStruct.style = properties;
|
||||
this.bufferStruct.verts = positions;
|
||||
this.bufferStruct.indexs = positionsIndex;
|
||||
if (instances.length > 0) {
|
||||
self.bufferStruct.instances = instances;
|
||||
this.bufferStruct.instances = instances;
|
||||
}
|
||||
self.attributes = this._toAttributes(self.bufferStruct, propertiesData);
|
||||
this.attributes = this._toAttributes(this.bufferStruct);
|
||||
}
|
||||
|
||||
_getShape(geo, props, index) {
|
||||
if (!props.hasOwnProperty('shape')) {
|
||||
if (!this.shapeType) {
|
||||
return lineShape.defaultLine(geo, index);
|
||||
}
|
||||
const shape = props.shape;
|
||||
const shape = this.shapeType;
|
||||
if (shape === 'meshLine') {
|
||||
return lineShape[shape](geo, props, index);
|
||||
} else if (shape === 'tubeLine') {
|
||||
return lineShape[shape](geo, props, index);
|
||||
} else if (shape === 'arc') {
|
||||
return lineShape[shape](geo, index);
|
||||
return lineShape[shape](geo, props, index);
|
||||
}
|
||||
return lineShape.Line(geo, props, index);
|
||||
|
||||
}
|
||||
_toAttributes(bufferStruct, propertiesData) {
|
||||
_getArcLineAttributes() {
|
||||
const coordinates = this.get('coordinates');
|
||||
const properties = this.get('properties');
|
||||
const positions = [];
|
||||
const colors = [];
|
||||
const indexArray = [];
|
||||
const sizes = [];
|
||||
const instances = [];
|
||||
coordinates.forEach((geo, index) => {
|
||||
const props = properties[index];
|
||||
const positionCount = positions.length / 3;
|
||||
const attrData = this._getShape(geo, props, positionCount);
|
||||
positions.push(...attrData.positions);
|
||||
colors.push(...attrData.colors);
|
||||
indexArray.push(...attrData.indexArray);
|
||||
instances.push(...attrData.instances);
|
||||
sizes.push(...attrData.sizes);
|
||||
});
|
||||
return {
|
||||
positions,
|
||||
colors,
|
||||
indexArray,
|
||||
sizes,
|
||||
instances
|
||||
};
|
||||
}
|
||||
_getMeshLineAttributes() {
|
||||
const coordinates = this.get('coordinates');
|
||||
const properties = this.get('properties');
|
||||
const { lineType } = this.get('style');
|
||||
const positions = [];
|
||||
const pickingIds = [];
|
||||
const normal = [];
|
||||
const miter = [];
|
||||
const colors = [];
|
||||
const indexArray = [];
|
||||
const sizes = [];
|
||||
const attrDistance = [];
|
||||
coordinates.forEach((geo, index) => {
|
||||
const props = properties[index];
|
||||
const positionCount = positions.length / 3;
|
||||
const attr = lineShape.Line(geo, props, positionCount, (lineType !== 'soild'));
|
||||
positions.push(...attr.positions);
|
||||
normal.push(...attr.normal);
|
||||
miter.push(...attr.miter);
|
||||
colors.push(...attr.colors);
|
||||
indexArray.push(...attr.indexArray);
|
||||
sizes.push(...attr.sizes);
|
||||
attrDistance.push(...attr.attrDistance);
|
||||
pickingIds.push(...attr.pickingIds);
|
||||
});
|
||||
return {
|
||||
positions,
|
||||
normal,
|
||||
miter,
|
||||
colors,
|
||||
indexArray,
|
||||
pickingIds,
|
||||
sizes,
|
||||
attrDistance
|
||||
};
|
||||
}
|
||||
|
||||
_toAttributes(bufferStruct) {
|
||||
const vertCount = bufferStruct.verts.length;
|
||||
const vertices = new Float32Array(vertCount * 3);
|
||||
const inposs = new Float32Array(vertCount * 4);
|
||||
const colors = new Float32Array(vertCount * 4);
|
||||
const times = new Float32Array(vertCount);
|
||||
for (let i = 0; i < vertCount; i++) {
|
||||
const index = bufferStruct.indexs[i];
|
||||
const color = bufferStruct.style[index].color;
|
||||
|
@ -58,22 +127,18 @@ export default class LineBuffer extends BufferBase {
|
|||
colors[i * 4 + 1] = color[1];
|
||||
colors[i * 4 + 2] = color[2];
|
||||
colors[i * 4 + 3] = color[3];
|
||||
if (bufferStruct.instances) {
|
||||
if (bufferStruct.instances) { // 弧线
|
||||
inposs[i * 4] = bufferStruct.instances[i][0];
|
||||
inposs[i * 4 + 1] = bufferStruct.instances[i][1];
|
||||
inposs[i * 4 + 2] = bufferStruct.instances[i][2];
|
||||
inposs[i * 4 + 3] = bufferStruct.instances[i][3];
|
||||
}
|
||||
if (propertiesData) {
|
||||
const time = propertiesData[index].time;
|
||||
times[i] = time;
|
||||
}
|
||||
|
||||
}
|
||||
return {
|
||||
vertices,
|
||||
colors,
|
||||
inposs,
|
||||
times
|
||||
inposs
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,28 +1,21 @@
|
|||
import BufferBase from './bufferBase';
|
||||
import { regularShape } from '../shape/index';
|
||||
import Util from '../../util';
|
||||
import * as THREE from '../../core/three';
|
||||
const shapeObj = {
|
||||
circle: 30,
|
||||
square: 4,
|
||||
triangle: 3,
|
||||
hexagon: 6
|
||||
};
|
||||
|
||||
export default class PointBuffer extends BufferBase {
|
||||
|
||||
geometryBuffer() {
|
||||
const type = this.get('type');
|
||||
switch (type) {
|
||||
case 'image' : this._imageBuffer();
|
||||
break;
|
||||
case '2d': this._2dRegularBuffer();
|
||||
case '2d': this._3dRegularBuffer();
|
||||
break;
|
||||
case '3d': this._3dRegularBuffer();
|
||||
break;
|
||||
case 'Model':this._ModelBuffer();
|
||||
break;
|
||||
default:
|
||||
this._3dRegularBuffer();
|
||||
this._sdfRegularBuffer();
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +24,6 @@ export default class PointBuffer extends BufferBase {
|
|||
const properties = this.get('properties');
|
||||
const imagePos = this.get('imagePos');
|
||||
const uv = new Float32Array(properties.length * 2);
|
||||
|
||||
for (let i = 0; i < properties.length; i++) {
|
||||
const { x, y } = imagePos[properties[i].shape];
|
||||
uv[i * 2] = x;
|
||||
|
@ -44,56 +36,52 @@ export default class PointBuffer extends BufferBase {
|
|||
this.attributes = this._toPointsAttributes(this.bufferStruct);
|
||||
this.attributes.uvs = uv;
|
||||
}
|
||||
_2dRegularBuffer() {
|
||||
_sdfRegularBuffer() {
|
||||
const coordinates = this.get('coordinates');
|
||||
const properties = this.get('properties');
|
||||
|
||||
const shapes = [];
|
||||
for (let i = 0; i < properties.length; i++) {
|
||||
const shape = shapeObj[properties[i].shape];
|
||||
properties[i].shape = shape;
|
||||
}
|
||||
this.bufferStruct.position = coordinates;
|
||||
properties.shapes = shapes;
|
||||
this.bufferStruct.style = properties;
|
||||
this.attributes = this._toPointsAttributes(this.bufferStruct);
|
||||
}
|
||||
_3dRegularBuffer() {
|
||||
const coordinates = this.get('coordinates');
|
||||
const properties = this.get('properties');
|
||||
const type = this.get('type');
|
||||
const positions = [];
|
||||
const shapes = [];
|
||||
const sizes = [];
|
||||
const uvs = [];
|
||||
const positionsIndex = [];
|
||||
let indexCount = 0;
|
||||
this.bufferStruct.style = properties;
|
||||
coordinates.forEach((geo, index) => {
|
||||
const m1 = new THREE.Matrix4();
|
||||
const { size, shape } = properties[index];
|
||||
const vert = regularShape[shape]('extrude');
|
||||
m1.setPosition(new THREE.Vector3(...geo));
|
||||
size[2] += Math.random() * 1000;
|
||||
m1.scale(new THREE.Vector3(...size));
|
||||
vert.positions = vert.positions.map(coor => {
|
||||
const vector = new THREE.Vector4(...coor, 1);
|
||||
vector.applyMatrix4(m1);
|
||||
return vector.toArray();
|
||||
});// 旋转矩阵
|
||||
positions.push(vert.positions);
|
||||
let { size, shape } = properties[index];
|
||||
let shapeType = 'extrude';
|
||||
|
||||
if (type === '2d' || (type === '3d' && size[2] === 0)) {
|
||||
shapeType = 'fill';
|
||||
Util.isArray(size) || (size = [ size, size, 0 ]);
|
||||
} else {
|
||||
Util.isArray(size) || (size = [ size, size, size ]);
|
||||
}
|
||||
if (regularShape[shape] == null) {
|
||||
uvs.push(0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0);
|
||||
shape = 'square';
|
||||
}
|
||||
const vert = regularShape[shape](shapeType);
|
||||
shapes.push(vert.positions);
|
||||
positions.push(geo);
|
||||
sizes.push(size);
|
||||
positionsIndex.push(vert.positionsIndex);
|
||||
indexCount += vert.positionsIndex.length;
|
||||
});
|
||||
this.bufferStruct.indices = positionsIndex;
|
||||
this.bufferStruct.position = positions;
|
||||
this.bufferStruct.indexCount = indexCount;
|
||||
this.attributes = this._toPolygonAttributes(this.bufferStruct);
|
||||
|
||||
this.bufferStruct.shapes = shapes;
|
||||
this.bufferStruct.sizes = sizes;
|
||||
this.bufferStruct.faceUv = uvs;
|
||||
this.attributes = this._toPointShapeAttributes(this.bufferStruct);
|
||||
}
|
||||
_ModelBuffer() {
|
||||
|
||||
}
|
||||
_textBuffer() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ export default class PolygonBuffer extends BufferBase {
|
|||
const shape = this.get('shape');
|
||||
const positions = [];
|
||||
const faceUv = [];
|
||||
const sizes = [];
|
||||
const positionsIndex = [];
|
||||
let indexCount = 0;
|
||||
this.bufferStruct.style = properties;
|
||||
|
@ -24,7 +25,23 @@ export default class PolygonBuffer extends BufferBase {
|
|||
});
|
||||
}
|
||||
positions.push(extrudeData.positions);
|
||||
faceUv.push(...extrudeData.faceUv);
|
||||
|
||||
if (shape !== 'line') {
|
||||
// faceUv.push(...extrudeData.faceUv);
|
||||
const count = extrudeData.faceUv.length / 2;
|
||||
for (let i = 0; i < count; i++) {
|
||||
// uv 系数生成等大小的窗户
|
||||
let x = extrudeData.faceUv[i * 2];
|
||||
let y = extrudeData.faceUv[i * 2 + 1];
|
||||
if (x !== -1) {
|
||||
x = x * 0.1;
|
||||
y = y * heightValue / 2000;
|
||||
}
|
||||
faceUv.push(x, y);
|
||||
sizes.push((1.0 - extrudeData.faceUv[i * 2 + 1]) * heightValue);
|
||||
}
|
||||
|
||||
}
|
||||
indexCount += extrudeData.positionsIndex.length;
|
||||
positionsIndex.push(extrudeData.positionsIndex);
|
||||
});
|
||||
|
@ -33,6 +50,7 @@ export default class PolygonBuffer extends BufferBase {
|
|||
this.bufferStruct.indexCount = indexCount;
|
||||
this.bufferStruct.style = properties;
|
||||
this.bufferStruct.faceUv = faceUv;
|
||||
this.bufferStruct.sizes = sizes;
|
||||
if (shape !== 'line') {
|
||||
this.attributes = this._toPolygonAttributes(this.bufferStruct);
|
||||
this.faceTexture = this._generateTexture();
|
||||
|
|
|
@ -1,107 +0,0 @@
|
|||
import BufferBase from './bufferBase';
|
||||
import * as THREE from '../../core/three';
|
||||
import { colorScales } from '../../attr/colorscales';
|
||||
export class RainBuffer extends BufferBase {
|
||||
geometryBuffer() {
|
||||
const defaultRampColors = {
|
||||
0.0: '#3288bd',
|
||||
0.1: '#66c2a5',
|
||||
0.2: '#abdda4',
|
||||
0.3: '#e6f598',
|
||||
0.4: '#fee08b',
|
||||
0.5: '#fdae61',
|
||||
0.6: '#f46d43',
|
||||
1.0: '#d53e4f'
|
||||
};
|
||||
|
||||
const coordinates = this.get('coordinates');
|
||||
const particleImage1 = this.get('particleImage1');
|
||||
const particleImage0 = this.get('particleImage0');
|
||||
const backgroundImage = this.get('backgroundImage');
|
||||
const extent = this.get('extent');
|
||||
const imgPos = [ ...extent[0],
|
||||
extent[1][0], extent[0][1], 0,
|
||||
...extent[1],
|
||||
...extent[0],
|
||||
...extent[1],
|
||||
extent[0][0], extent[1][1], 0
|
||||
];
|
||||
const imgPosUv = [ 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0 ];
|
||||
const image = this.get('image');
|
||||
this.bufferStruct.particleStateTexture0 = this._getTexture(particleImage0, THREE.NearestFilter);
|
||||
this.bufferStruct.particleStateTexture1 = this._getTexture(particleImage1, THREE.NearestFilter);
|
||||
this.bufferStruct.backgroundTexture = this._getTexture(backgroundImage, THREE.NearestFilter);
|
||||
const texture = this._getTexture(image, THREE.NearestFilter);
|
||||
const colorImageData = this.getColorRamp('wind');
|
||||
const colorTexture = this._getTexture(colorImageData, THREE.LinearFilter);
|
||||
this.bufferStruct.position = coordinates;
|
||||
this.bufferStruct.imgPos = imgPos;
|
||||
this.bufferStruct.imgPosUv = imgPosUv;
|
||||
this.bufferStruct.u_wind = texture;// 风速 风向
|
||||
this.bufferStruct.colorTexture = colorTexture; // 颜色表‘=
|
||||
const attributes = {
|
||||
vertices: new Float32Array(imgPos),
|
||||
uvs: new Float32Array(imgPosUv)
|
||||
};
|
||||
this.attributes = attributes;
|
||||
|
||||
}
|
||||
// //生成色带纹理
|
||||
// getColorRamp(colors) {
|
||||
// const canvas = document.createElement('canvas');
|
||||
// const ctx = canvas.getContext('2d');
|
||||
|
||||
// canvas.width = 256;
|
||||
// canvas.height = 1;
|
||||
|
||||
// const gradient = ctx.createLinearGradient(0, 0, 256, 0);
|
||||
// for (const stop in colors) {
|
||||
// gradient.addColorStop(+stop, colors[stop]);
|
||||
// }
|
||||
|
||||
// ctx.fillStyle = gradient;
|
||||
// ctx.fillRect(0, 0, 256, 1);
|
||||
// const data = new Uint8ClampedArray(ctx.getImageData(0, 0, 256, 1).data);
|
||||
// return new ImageData(data, 16, 16);
|
||||
// }
|
||||
getColorRamp(name) {
|
||||
let colorscale = name;
|
||||
const canvas = document.createElement('canvas');
|
||||
const ctx = canvas.getContext('2d');
|
||||
|
||||
canvas.width = 256;
|
||||
canvas.height = 1;
|
||||
const gradient = ctx.createLinearGradient(0, 0, 256, 0);
|
||||
let data = null;
|
||||
if (typeof (colorscale) === 'string') {
|
||||
colorscale = colorScales[name];
|
||||
}
|
||||
if (Object.prototype.toString.call(colorscale) === '[object Object]') {
|
||||
const min = colorscale.positions[0];
|
||||
const max = colorscale.positions[colorscale.positions.length - 1];
|
||||
|
||||
for (let i = 0; i < colorscale.colors.length; ++i) {
|
||||
const value = (colorscale.positions[i] - min) / (max - min);
|
||||
gradient.addColorStop(value, colorscale.colors[i]);
|
||||
}
|
||||
ctx.fillStyle = gradient;
|
||||
ctx.fillRect(0, 0, 256, 1);
|
||||
data = new Uint8ClampedArray(ctx.getImageData(0, 0, 256, 1).data);
|
||||
}
|
||||
if (Object.prototype.toString.call(colorscale) === '[object Uint8Array]') {
|
||||
data = ctx.createImageData(256, 1);
|
||||
}
|
||||
|
||||
return new ImageData(data, 16, 16);
|
||||
|
||||
}
|
||||
// 生成纹理
|
||||
_getTexture(image, filter) {
|
||||
const texture = new THREE.Texture(image);
|
||||
texture.magFilter = filter;
|
||||
texture.minFilter = filter;
|
||||
texture.needsUpdate = true;
|
||||
return texture;
|
||||
}
|
||||
|
||||
}
|
|
@ -18,9 +18,8 @@ export class RasterBuffer extends BufferBase {
|
|||
const size = this.get('size');
|
||||
const texture = new THREE.DataTexture(new Float32Array(raster.data), raster.width, raster.height, THREE.LuminanceFormat, THREE.FloatType);
|
||||
texture.generateMipmaps = true;
|
||||
// texture.minFilter = THREE.NearestFilter;
|
||||
texture.needsUpdate = true;
|
||||
const colors = this.get('rampColors') || defaultRampColors;
|
||||
const colors = this.get('rampColors');
|
||||
const colorImageData = this.getColorRamp(colors);
|
||||
const colorTexture = this._getTexture(colorImageData);
|
||||
this.bufferStruct.position = positions;
|
||||
|
@ -29,7 +28,7 @@ export class RasterBuffer extends BufferBase {
|
|||
this.bufferStruct.u_extent = [ coordinates[0][0], coordinates[0][1], coordinates[1][0], coordinates[1][1] ];
|
||||
|
||||
this.bufferStruct.u_colorTexture = colorTexture; // 颜色表‘=
|
||||
const triangles = this._buildTriangles(raster, size);
|
||||
const triangles = this._buildTriangles(raster, size, this.bufferStruct.u_extent);
|
||||
const attributes = {
|
||||
vertices: new Float32Array(triangles.vertices),
|
||||
uvs: new Float32Array(triangles.uvs),
|
||||
|
@ -79,39 +78,35 @@ export class RasterBuffer extends BufferBase {
|
|||
texture1.needsUpdate = true;
|
||||
return texture1;
|
||||
}
|
||||
_buildTriangles(raster, size = 1) {
|
||||
_buildTriangles(raster, size = 1, extent) {
|
||||
// const extent = [ 73.482190241, 3.82501784112, 135.106618732, 57.6300459963 ]
|
||||
const { width, height } = raster;
|
||||
const halfSize = size / 2;
|
||||
const indices = [];
|
||||
const vertices = [];
|
||||
const normals = [];
|
||||
const uvs = [];
|
||||
|
||||
const gridX = Math.floor(width / size);
|
||||
const gridY = Math.floor(height / size);
|
||||
const gridX1 = gridX + 1;
|
||||
const gridY1 = gridY + 1;
|
||||
const stepX = (extent[2] - extent[0]) / gridX1;
|
||||
const stepY = (extent[3] - extent[1]) / gridY1;
|
||||
for (let i = 0; i < gridY1; i++) {
|
||||
const y = i * size - halfSize;
|
||||
const y = i * size;
|
||||
for (let j = 0; j < gridX1; j++) {
|
||||
const x = j * size - halfSize;
|
||||
vertices.push(x / gridX, -y / gridY, 0);
|
||||
const x = j * size;
|
||||
vertices.push(extent[0] + x * stepX, (height - y) * stepY + extent[1], 0);
|
||||
uvs.push(j / gridX);
|
||||
uvs.push(i / gridY);
|
||||
uvs.push(i / gridY);
|
||||
}
|
||||
}
|
||||
|
||||
for (let iy = 0; iy < gridY; iy++) {
|
||||
|
||||
for (let ix = 0; ix < gridX; ix++) {
|
||||
|
||||
const a = ix + gridX1 * iy;
|
||||
const b = ix + gridX1 * (iy + 1);
|
||||
const c = (ix + 1) + gridX1 * (iy + 1);
|
||||
const d = (ix + 1) + gridX1 * iy;
|
||||
indices.push(a, b, d);
|
||||
indices.push(b, c, d);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import BufferBase from './bufferBase';
|
||||
import { Texture2D } from '../../core/three';
|
||||
import { TextureFilter, TextureWrapMode } from '@ali/r3-base';
|
||||
import { getJSON, getImage } from '../../util/ajax';
|
||||
import * as THREE from '../../core/three';
|
||||
import Global from '../../global';
|
||||
const Space = 1;
|
||||
export default class TextBuffer extends BufferBase {
|
||||
|
@ -14,13 +13,11 @@ export default class TextBuffer extends BufferBase {
|
|||
};
|
||||
const coordinates = this.get('coordinates');
|
||||
const properties = this.get('properties');
|
||||
const style = this.get('style');
|
||||
const { size = 24 } = style;
|
||||
const { textOffset = [ 0, 0 ] } = this.get('style');
|
||||
const chars = [];
|
||||
const positions = [];
|
||||
const uvs = [];
|
||||
properties.forEach(element => {
|
||||
const text = element.shape;
|
||||
let text = element.shape || '';
|
||||
text = text.toString();
|
||||
for (let j = 0; j < text.length; j++) {
|
||||
const code = text.charCodeAt(j);
|
||||
if (chars.indexOf(code) === -1) {
|
||||
|
@ -28,38 +25,41 @@ export default class TextBuffer extends BufferBase {
|
|||
}
|
||||
}
|
||||
});
|
||||
this._loadTextInfo(chars);
|
||||
this.on('SourceLoaded', () => {
|
||||
let indexCount = 0;
|
||||
const textureElements = [];
|
||||
const colors = [];
|
||||
const originPoints = [];
|
||||
const textSizes = [];
|
||||
const textOffsets = [];
|
||||
properties.forEach((element, index) => {
|
||||
const text = element.shape;
|
||||
|
||||
const size = element.size;
|
||||
const pos = coordinates[index];
|
||||
const dimensions = this._measureText(text, size);
|
||||
// const pen = { x: pos[0] - dimensions.advance / 2, y: pos[1] };
|
||||
const pen = { x: pos[0], y: pos[1] };
|
||||
const vertexElements = [];
|
||||
const textureElements = [];
|
||||
const pen = { x: textOffset[0], y: textOffset[1] };
|
||||
let text = element.shape || '';
|
||||
text = text.toString();
|
||||
for (let i = 0; i < text.length; i++) {
|
||||
const chr = text.charCodeAt(i);
|
||||
const offset = dimensions.advance / text.length * i;
|
||||
this._drawGlyph(chr, pen, size, vertexElements, textureElements, offset);
|
||||
}
|
||||
|
||||
uvs.push(textureElements);
|
||||
indexCount += vertexElements.length;
|
||||
positions.push(vertexElements);
|
||||
const color = element.color;
|
||||
this._drawGlyph(pos, chr, pen, size, colors, textureElements, originPoints, textSizes, textOffsets, color);
|
||||
}
|
||||
});
|
||||
this.bufferStruct.uv = uvs;
|
||||
this.bufferStruct.position = positions;
|
||||
this.bufferStruct.style = properties;
|
||||
this.bufferStruct.indexCount = indexCount;
|
||||
this.attributes = {
|
||||
originPoints,
|
||||
textSizes,
|
||||
textOffsets,
|
||||
colors,
|
||||
textureElements
|
||||
};
|
||||
this.emit('completed');
|
||||
});
|
||||
this._loadTextInfo(chars);
|
||||
|
||||
}
|
||||
|
||||
_loadTextInfo(chars) {
|
||||
|
||||
getJSON({
|
||||
url: `${Global.sdfHomeUrl}/getsdfdata?chars=${chars.join('|')}`
|
||||
}, (e, info) => {
|
||||
|
@ -75,19 +75,32 @@ export default class TextBuffer extends BufferBase {
|
|||
this.emit('SourceLoaded');
|
||||
});
|
||||
}
|
||||
_drawGlyph(chr, pen, size, vertexElements, textureElements, offset) {
|
||||
/**
|
||||
* 计算每个标注词语的位置
|
||||
* @param {*} pos 文字三维空间坐标
|
||||
* @param {*} chr 字符
|
||||
* @param {*} pen 字符在词语的偏移量
|
||||
* @param {*} size 字体大小
|
||||
* @param {*} colors 颜色
|
||||
* @param {*} textureElements 纹理坐标
|
||||
* @param {*} originPoints 初始位置数据
|
||||
* @param {*} textSizes 文字大小数组
|
||||
* @param {*} textOffsets 字体偏移量数据
|
||||
* @param {*} color 文字颜色
|
||||
*/
|
||||
_drawGlyph(pos, chr, pen, size, colors, textureElements, originPoints, textSizes, textOffsets, color) {
|
||||
const metrics = this.metrics;
|
||||
const metric = metrics.chars[chr];
|
||||
if (!metric) return;
|
||||
|
||||
const scale = size / metrics.size;
|
||||
|
||||
const factor = 1;
|
||||
|
||||
let width = metric[0];
|
||||
let height = metric[1];
|
||||
|
||||
const horiBearingX = metric[2];
|
||||
const horiBearingY = metric[3];
|
||||
|
||||
const horiAdvance = metric[4];
|
||||
const posX = metric[5];
|
||||
const posY = metric[6];
|
||||
|
@ -98,36 +111,67 @@ export default class TextBuffer extends BufferBase {
|
|||
width += buffer * 2;
|
||||
height += buffer * 2;
|
||||
|
||||
// Add a quad (= two triangles) per glyph.
|
||||
const w1 = (horiBearingX - buffer) * scale + offset;
|
||||
const w2 = (horiBearingX - buffer + width) * scale + offset;
|
||||
const h1 = -horiBearingY * scale;
|
||||
const h2 = (height - horiBearingY) * scale;
|
||||
vertexElements.push(
|
||||
[ (factor * (pen.x + w1)), (factor * (pen.y + h1)), w1, h1 ],
|
||||
[ (factor * (pen.x + w2)), (factor * (pen.y + h1)), w2, h1 ],
|
||||
[ (factor * (pen.x + w1)), (factor * (pen.y + h2)), w1, h2 ],
|
||||
// Add a quad (= two triangles) per glyph.
|
||||
const originX = (horiBearingX - buffer + width / 2) * scale;
|
||||
const originY = -(height / 2 - horiBearingY) * scale;
|
||||
// const originY = (height / 2 - horiBearingY) * scale;
|
||||
// const originY = 0;
|
||||
const offsetWidth = width / 2 * scale / (1.0 - horiBearingX * 1.5 / horiAdvance);
|
||||
const offsetHeight = (horiAdvance / 2) * scale;
|
||||
|
||||
[ (factor * (pen.x + w2)), (factor * (pen.y + h1)), w2, h1 ],
|
||||
[ (factor * (pen.x + w1)), (factor * (pen.y + h2)), w1, h2 ],
|
||||
[ (factor * (pen.x + w2)), (factor * (pen.y + h2)), w2, h2 ]
|
||||
);
|
||||
const offsetX = pen.x;
|
||||
const offsetY = pen.y;
|
||||
originPoints.push(
|
||||
pos[0] + originX, pos[1] + originY, 0,
|
||||
pos[0] + originX, pos[1] + originY, 0,
|
||||
pos[0] + originX, pos[1] + originY, 0,
|
||||
pos[0] + originX, pos[1] + originY, 0,
|
||||
pos[0] + originX, pos[1] + originY, 0,
|
||||
pos[0] + originX, pos[1] + originY, 0,
|
||||
);
|
||||
|
||||
textSizes.push(
|
||||
offsetWidth, offsetHeight,
|
||||
-offsetWidth, offsetHeight,
|
||||
-offsetWidth, -offsetHeight,
|
||||
offsetWidth, offsetHeight,
|
||||
-offsetWidth, -offsetHeight,
|
||||
offsetWidth, -offsetHeight,
|
||||
);
|
||||
textOffsets.push(
|
||||
offsetX, offsetY,
|
||||
offsetX, offsetY,
|
||||
offsetX, offsetY,
|
||||
offsetX, offsetY,
|
||||
offsetX, offsetY,
|
||||
offsetX, offsetY,
|
||||
);
|
||||
|
||||
colors.push(
|
||||
...color,
|
||||
...color,
|
||||
...color,
|
||||
...color,
|
||||
...color,
|
||||
...color,
|
||||
);
|
||||
textureElements.push(
|
||||
[ posX, posY + height ],
|
||||
[ posX + width, posY + height ],
|
||||
[ posX, posY ],
|
||||
|
||||
[ posX + width, posY + height ],
|
||||
[ posX, posY ],
|
||||
[ posX + width, posY ]
|
||||
);
|
||||
posX + width, posY,
|
||||
posX, posY,
|
||||
posX, posY + height,
|
||||
|
||||
posX + width, posY,
|
||||
posX, posY + height,
|
||||
posX + width, posY + height
|
||||
);
|
||||
}
|
||||
|
||||
pen.x = pen.x + (horiAdvance + Space) * scale;
|
||||
|
||||
}
|
||||
|
||||
|
||||
_measureText(text, size) {
|
||||
const dimensions = {
|
||||
advance: 0
|
||||
|
@ -145,13 +189,10 @@ export default class TextBuffer extends BufferBase {
|
|||
}
|
||||
_creatTexture(image) {
|
||||
this.bufferStruct.textSize = [ image.width, image.height ];
|
||||
const texture = new Texture2D('textTexure', image, {
|
||||
magFilter: TextureFilter.LINEAR,
|
||||
minFilter: TextureFilter.LINEAR,
|
||||
wrapS: TextureWrapMode.CLAMP_TO_EDGE,
|
||||
wrapT: TextureWrapMode.CLAMP_TO_EDGE
|
||||
});
|
||||
const texture = new THREE.Texture(image);
|
||||
texture.minFilter = THREE.LinearFilter;
|
||||
texture.magFilter = THREE.LinearFilter;
|
||||
texture.needsUpdate = true;
|
||||
return texture;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,78 +0,0 @@
|
|||
import Base from '../../core/base';
|
||||
import TinySDF from '@mapbox/tiny-sdf';
|
||||
import { Texture } from '../../core/three';
|
||||
export default class textBuffer extends Base {
|
||||
constructor(cfg) {
|
||||
super(cfg);
|
||||
this.canvas = document.createElement('canvas');
|
||||
this.ctx = this.canvas.getContext('2d');
|
||||
this.fontSize = 24;
|
||||
this.fontWeight = 400;
|
||||
this.sdfs = {};
|
||||
this.bufferStruct = {};
|
||||
this.chars = this.makeChars();
|
||||
this.updateSDF();
|
||||
this.geometryBuffer();
|
||||
}
|
||||
|
||||
geometryBuffer() {
|
||||
const coordinates = this.get('coordinates');
|
||||
const properties = this.get('properties');
|
||||
const uvs = [];
|
||||
const texture = new Texture2D('charts', this.canvas);
|
||||
this.bufferStruct.style = properties;
|
||||
// this.bufferStruct.utexture = this.canvas;
|
||||
this.bufferStruct.utexture = texture;
|
||||
const positions = [];
|
||||
const textIndex = [];
|
||||
const index = 0;
|
||||
coordinates.forEach((coor, index) => {
|
||||
positions.push([[ coor[0], coor[1] ], [ coor[0], coor[1] ]]);
|
||||
textIndex.push([ 0, 1 ]);
|
||||
index++;
|
||||
const posX = this.sdfs[this.chars[index]].x; // pos in sprite x
|
||||
const posY = this.sdfs[this.chars[index]].y; // pos in sprite y
|
||||
uvs.push([[ posX / 2048, posY / 2048 ], [ posX / 2048, posY / 2048 ]]);
|
||||
});
|
||||
this.bufferStruct.position = positions;
|
||||
this.bufferStruct.uv = uvs;
|
||||
this.bufferStruct.textIndex = textIndex;
|
||||
this.bufferStruct.indexCount = this.bufferStruct.position.length * 2;
|
||||
}
|
||||
makeChars() {
|
||||
const properties = this.get('properties');
|
||||
const chars = [];
|
||||
properties.forEach(item => {
|
||||
const text = item.shape;
|
||||
text.forEach(char => {
|
||||
chars.push(char);
|
||||
});
|
||||
});
|
||||
return chars;
|
||||
}
|
||||
updateSDF() {
|
||||
this.canvas.width = 2048;
|
||||
this.canvas.height = 2048;
|
||||
const buffer = this.fontSize / 8;
|
||||
const radius = this.fontSize / 3;
|
||||
const sdf = new TinySDF(this.fontSize, buffer, radius, null, null, this.fontWeight);
|
||||
for (let y = 0, i = 0; y + sdf.size <= this.canvas.height && i < this.chars.length; y += sdf.size) {
|
||||
for (let x = 0; x + sdf.size <= this.canvas.width && i < this.chars.length; x += sdf.size) {
|
||||
this.ctx.putImageData(this.makeRGBAImageData(sdf.draw(this.chars[i]), sdf.size), x, y);
|
||||
this.sdfs[this.chars[i]] = { x, y };
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
makeRGBAImageData(alphaChannel, size) {
|
||||
const imageData = this.ctx.createImageData(size, size);
|
||||
const data = imageData.data;
|
||||
for (let i = 0; i < alphaChannel.length; i++) {
|
||||
data[4 * i + 0] = alphaChannel[i];
|
||||
data[4 * i + 1] = alphaChannel[i];
|
||||
data[4 * i + 2] = alphaChannel[i];
|
||||
data[4 * i + 3] = 255;
|
||||
}
|
||||
return imageData;
|
||||
}
|
||||
}
|
|
@ -1,118 +0,0 @@
|
|||
import { BufferGeometry, Float32BufferAttribute } from '../../core/three';
|
||||
/**
|
||||
* 基础几何体
|
||||
*/
|
||||
export default class BaseBufferGeometry extends BufferGeometry {
|
||||
|
||||
// indices, position, uv, normal
|
||||
constructor(opts) {
|
||||
super(opts.name);
|
||||
// 几何体顶点位置数据
|
||||
this._opts = opts;
|
||||
this._position = opts.position;
|
||||
|
||||
// 三角形顶点序号数据
|
||||
this._indices = opts.indices;
|
||||
|
||||
// this._colors = opts.colors;
|
||||
|
||||
this._style = opts.style;
|
||||
|
||||
|
||||
// 法线数据
|
||||
this._normals = opts.normals;
|
||||
|
||||
this._uv = opts.uv;
|
||||
|
||||
|
||||
this._activeIds = null;
|
||||
this._textIndex = opts.textIndex;
|
||||
this._indexCount = opts.indexCount;
|
||||
if (opts.DrawMode) {
|
||||
this.mode = DrawMode[opts.DrawMode];
|
||||
}
|
||||
if (this._indexCount > 65536) {
|
||||
this.primitive.indexType = DataType.UNSIGNED_INT;
|
||||
}
|
||||
this.initialize();
|
||||
}
|
||||
/**
|
||||
* 更新active操作
|
||||
* @param {*} featureStyleId 需要更新的要素Id
|
||||
* @param {*} style 更新的要素样式
|
||||
*/
|
||||
updateStyle(featureStyleId, style) {
|
||||
if (this._activeIds) {
|
||||
this.resetStyle();
|
||||
}
|
||||
this._activeIds = featureStyleId;
|
||||
let dataIndex = 0;
|
||||
const id = featureStyleId[0];
|
||||
if (!this._indices) {
|
||||
const color = style.color;
|
||||
this.setVertexValues(id, {
|
||||
COLOR: color
|
||||
});
|
||||
return;
|
||||
}
|
||||
for (let i = 0; i < id; i++) {
|
||||
dataIndex += this._indices[i].length;
|
||||
}
|
||||
featureStyleId.forEach(index => {
|
||||
|
||||
const indices = this._indices[index];
|
||||
const color = style.color;
|
||||
indices.forEach(() => {
|
||||
this.setVertexValues(dataIndex++, {
|
||||
COLOR: color
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
/**
|
||||
* 用于过滤数据
|
||||
* @param {*} filterData 数据过滤标识符
|
||||
*/
|
||||
updateFilter(filterData) {
|
||||
let dataIndex = 0;
|
||||
|
||||
this._indices.forEach((indices, i) => {
|
||||
const color = [ ...this._style[i].color ];
|
||||
if (filterData[i].hasOwnProperty('filter') && filterData[i].filter === false) {
|
||||
color[3] = 0;
|
||||
}
|
||||
|
||||
indices.forEach(() => {
|
||||
this.setVertexValues(dataIndex++, {
|
||||
COLOR: color
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 重置高亮要素
|
||||
*/
|
||||
resetStyle() {
|
||||
let dataIndex = 0;
|
||||
const id = this._activeIds[0];
|
||||
if (!this._indices) {
|
||||
const color = this._style[id].color;
|
||||
this.setVertexValues(id, {
|
||||
COLOR: color
|
||||
});
|
||||
return;
|
||||
}
|
||||
for (let i = 0; i < id; i++) {
|
||||
dataIndex += this._indices[i].length;
|
||||
}
|
||||
this._activeIds.forEach(index => {
|
||||
const indices = this._indices[index];
|
||||
indices.forEach(() => {
|
||||
this.setVertexValues(dataIndex++, {
|
||||
COLOR: this._style[index].color
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
import { DataType } from '@ali/r3-base';
|
||||
import BaseBufferGeometry from './baseBufferGeometry';
|
||||
/**
|
||||
* 创建Polygon几何体
|
||||
*/
|
||||
export default class ImageGeometry extends BaseBufferGeometry {
|
||||
|
||||
constructor(opts) {
|
||||
opts.DrawMode = 'TRIANGLES';
|
||||
super(opts);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 构造多边形数据
|
||||
* @private
|
||||
*/
|
||||
initialize() {
|
||||
super.initialize([
|
||||
{ semantic: 'POSITION', size: 3, type: DataType.FLOAT, normalized: false },
|
||||
{ semantic: 'TEXCOORD_0', size: 2, type: DataType.FLOAT, normalized: false }
|
||||
], this._position.length);
|
||||
|
||||
this._position.forEach((vert, j) => {
|
||||
this.setVertexValues(j, {
|
||||
POSITION: vert,
|
||||
TEXCOORD_0: this._uv[j]
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
export { default as MeshlineGeometry } from './line';
|
||||
export { default as PointGeometry } from './point';
|
||||
export { default as PolygonLine } from './polygon-line';
|
||||
export { default as PolygonGeometry } from './polygon';
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
import { DataType, DrawMode } from '@ali/r3-base';
|
||||
import { BufferGeometry } from '@ali/r3-geometry';
|
||||
|
||||
export class meshLineGeometry extends BufferGeometry {
|
||||
constructor(opts) {
|
||||
super();
|
||||
this._verts = opts.verts;
|
||||
this._style = opts.style;
|
||||
this._indexs = opts.indexs;
|
||||
this._initialize();
|
||||
}
|
||||
|
||||
_initialize() {
|
||||
const self = this;
|
||||
super.initialize([
|
||||
{ semantic: 'POSITION', size: 3, type: DataType.FLOAT, normalized: false },
|
||||
{ semantic: 'COLOR', size: 4, type: DataType.FLOAT, normalized: false }
|
||||
], self._verts.length);
|
||||
|
||||
self.mode = DrawMode.TRIANGLES;
|
||||
for (let i = 0; i < self._verts.length; i++) {
|
||||
const index = self._indexs[i];
|
||||
const color = this._style[index].color;
|
||||
const values = {
|
||||
POSITION: self._verts[i],
|
||||
COLOR: color
|
||||
};
|
||||
self.setVertexValues(i, values);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export class arcGeometry extends BufferGeometry {
|
||||
constructor(opts) {
|
||||
super();
|
||||
// 顶点位置数据
|
||||
this._verts = opts.verts;
|
||||
this._style = opts.style;
|
||||
this._indexs = opts.indexs;
|
||||
this._instances = opts.instances;
|
||||
this._initialize();
|
||||
}
|
||||
|
||||
_initialize() {
|
||||
const self = this;
|
||||
super.initialize([
|
||||
{ semantic: 'POSITION', size: 3, type: DataType.FLOAT, normalized: false },
|
||||
{ semantic: 'COLOR', size: 4, type: DataType.FLOAT, normalized: false },
|
||||
{ semantic: 'INSPOS', size: 4, type: DataType.FLOAT, normalized: false }
|
||||
], self._verts.length);
|
||||
|
||||
self.mode = DrawMode.LINES;
|
||||
for (let i = 0; i < self._verts.length; i++) {
|
||||
const index = this._indexs[i];
|
||||
const color = this._style[index].color;
|
||||
const values = {
|
||||
POSITION: self._verts[i],
|
||||
COLOR: color,
|
||||
INSPOS: self._instances[i]
|
||||
};
|
||||
self.setVertexValues(i, values);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,55 +0,0 @@
|
|||
import { DataType, BufferUsage } from '@ali/r3-base';
|
||||
import BaseBufferGeometry from './baseBufferGeometry';
|
||||
|
||||
/**
|
||||
* 创建点图层几何体
|
||||
*/
|
||||
export default class PointGeometry extends BaseBufferGeometry {
|
||||
|
||||
constructor(opts) {
|
||||
opts.DrawMode = 'POINTS';
|
||||
super(opts);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造多边形数据
|
||||
* @private
|
||||
*/
|
||||
initialize() {
|
||||
const attributesObj = {
|
||||
size: { semantic: 'SIZE', size: 1, type: DataType.FLOAT, normalized: false },
|
||||
id: { semantic: 'IDCOLOR', size: 4, type: DataType.FLOAT, normalized: false },
|
||||
uv: { semantic: 'TEXCOORD_0', size: 2, type: DataType.FLOAT, normalized: false },
|
||||
color: { semantic: 'COLOR', size: 4, type: DataType.FLOAT, normalized: false },
|
||||
shape: { semantic: 'SHAPE', size: 1, type: DataType.FLOAT, normalized: false }
|
||||
};
|
||||
|
||||
const keys = Object.keys(this._style[0]);
|
||||
const attributes = [{ semantic: 'POSITION', size: 3, type: DataType.FLOAT, normalized: false }];
|
||||
if (this._uv) attributes.push(attributesObj.uv);
|
||||
keys.forEach(key => { attributes.push(attributesObj[key]); });
|
||||
super.initialize(attributes, this._position.length, BufferUsage.DYNAMIC_DRAW);
|
||||
this._position.forEach((vert, i) => {
|
||||
const color = this._style[i].color;
|
||||
const attrData = {
|
||||
POSITION: vert,
|
||||
COLOR: color,
|
||||
SIZE: [ this._style[i].size ],
|
||||
IDCOLOR: this._style[i].id,
|
||||
SHAPE: [ this._style[i].shape ]
|
||||
};
|
||||
if (keys.indexOf('shape') !== -1) attrData.SHAPE = [ this._style[i].shape ];
|
||||
if (this._uv) attrData.TEXCOORD_0 = this._uv[i];
|
||||
this.setVertexValues(i, attrData);
|
||||
|
||||
});
|
||||
}
|
||||
updateSize(data) {
|
||||
const pointCount = this._position.length;
|
||||
for (let i = 0; i < pointCount; i++) {
|
||||
this.setVertexValues(i, {
|
||||
SIZE: [ data[i] ]
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,56 +0,0 @@
|
|||
import { DataType, DrawMode } from '@ali/r3-base';
|
||||
import { IndexBufferGeometry } from '@ali/r3-geometry';
|
||||
|
||||
// 创建立方体
|
||||
export default class PolygonLine extends IndexBufferGeometry {
|
||||
constructor(opts) {
|
||||
super();
|
||||
this._positions = opts.verts;
|
||||
this._positionsIndexs = opts.indexs;
|
||||
this._vertsCount = opts.vertsCount;
|
||||
this._style = opts.style;
|
||||
//
|
||||
if (this._positionsIndexs.length > 65536) {
|
||||
this.primitive.indexType = DataType.UNSIGNED_INT;
|
||||
}
|
||||
this.initialize();
|
||||
}
|
||||
initialize() {
|
||||
super.initialize([
|
||||
{ semantic: 'POSITION', size: 3, type: DataType.FLOAT, normalized: false },
|
||||
{ semantic: 'COLOR', size: 4, type: DataType.FLOAT, normalized: false }
|
||||
], this._vertsCount, this._positionsIndexs);
|
||||
this.mode = DrawMode.LINES;
|
||||
const featureCount = this._positions.length;
|
||||
let indexCount = 0;
|
||||
for (let i = 0; i < featureCount; i++) {
|
||||
const pos = this._positions[i];
|
||||
for (let j = 0; j < pos.length; j++) {
|
||||
this.setVertexValues(indexCount, {
|
||||
POSITION: pos[j],
|
||||
COLOR: this._style[i].color
|
||||
});
|
||||
indexCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
updateFilter(filterData) {
|
||||
this._activeIds = null; // 清空选中元素
|
||||
const featureCount = this._positions.length;
|
||||
let indexCount = 0;
|
||||
for (let i = 0; i < featureCount; i++) {
|
||||
const pos = this._positions[i];
|
||||
const color = [ ...this._style[i].color ];
|
||||
if (filterData[i].hasOwnProperty('filter') && filterData[i].filter === false) {
|
||||
color[3] = 0;
|
||||
}
|
||||
for (let j = 0; j < pos.length; j++) {
|
||||
this.setVertexValues(indexCount, {
|
||||
COLOR: color
|
||||
});
|
||||
indexCount++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,128 +0,0 @@
|
|||
import { DataType, DrawMode } from '@ali/r3-base';
|
||||
import { BufferGeometry } from '@ali/r3-geometry';
|
||||
/**
|
||||
* 创建Polygon几何体
|
||||
*/
|
||||
export default class PolygonGeometry extends BufferGeometry {
|
||||
|
||||
constructor(opts) {
|
||||
super(opts.name);
|
||||
|
||||
// 几何体顶点位置数据
|
||||
this._verts = opts.position;
|
||||
|
||||
// 三角形顶点序号数据
|
||||
this._indexs = opts.indices;
|
||||
|
||||
|
||||
this._style = opts.style;
|
||||
|
||||
|
||||
// 法线数据
|
||||
this._normals = opts.normals;
|
||||
|
||||
this._indexCount = opts.indexCount;
|
||||
this._activeIds = null;
|
||||
|
||||
this.initialize();
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造多边形数据
|
||||
* @private
|
||||
*/
|
||||
initialize() {
|
||||
super.initialize([
|
||||
{ semantic: 'POSITION', size: 3, type: DataType.FLOAT, normalized: false },
|
||||
{ semantic: 'NORMAL', size: 3, type: DataType.FLOAT, normalized: true },
|
||||
{ semantic: 'COLOR', size: 4, type: DataType.FLOAT, normalized: false },
|
||||
{ semantic: 'IDCOLOR', size: 4, type: DataType.FLOAT, normalized: false }
|
||||
], this._indexCount);
|
||||
this.mode = DrawMode.TRIANGLES;
|
||||
if (this._indexCount > 65536) {
|
||||
this.primitive.indexType = DataType.UNSIGNED_INT;
|
||||
}
|
||||
// camera.renderHardware
|
||||
let dataIndex = 0;
|
||||
this._indexs.forEach((vertIndexs, i) => {
|
||||
const color = [ ...this._style[i].color ];
|
||||
if (this._style[i].hasOwnProperty('filter') && !this._style[i].filter) {
|
||||
color[3] = 0;
|
||||
}
|
||||
vertIndexs.forEach((index, j) => {
|
||||
const vert = this._verts[i][index];
|
||||
const normalIndex = Math.floor(j / 3);
|
||||
this.setVertexValues(dataIndex++, {
|
||||
POSITION: vert,
|
||||
COLOR: color,
|
||||
IDCOLOR: this._style[i].id,
|
||||
NORMAL: this._normals[i][normalIndex]
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 更新active操作
|
||||
* @param {*} featureStyleId 需要更新的要素Id
|
||||
* @param {*} style 更新的要素样式
|
||||
*/
|
||||
updateStyle(featureStyleId, style) {
|
||||
if (this._activeIds) {
|
||||
this.resetStyle();
|
||||
}
|
||||
this._activeIds = featureStyleId;
|
||||
let dataIndex = 0;
|
||||
const id = featureStyleId[0];
|
||||
for (let i = 0; i < id; i++) {
|
||||
dataIndex += this._indexs[i].length;
|
||||
}
|
||||
featureStyleId.forEach(index => {
|
||||
const vertindex = this._indexs[index];
|
||||
const color = style.color;
|
||||
vertindex.forEach(() => {
|
||||
this.setVertexValues(dataIndex++, {
|
||||
COLOR: color
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
/**
|
||||
* 用于过滤数据
|
||||
* @param {*} filterData 数据过滤标识符
|
||||
*/
|
||||
updateFilter(filterData) {
|
||||
this._activeIds = null; // 清空选中元素
|
||||
let dataIndex = 0;
|
||||
this._indexs.forEach((vertIndexs, i) => {
|
||||
const color = [ ...this._style[i].color ];
|
||||
if (filterData[i].hasOwnProperty('filter') && filterData[i].filter === false) {
|
||||
color[3] = 0;
|
||||
}
|
||||
|
||||
vertIndexs.forEach(() => {
|
||||
this.setVertexValues(dataIndex++, {
|
||||
COLOR: color
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 重置高亮要素
|
||||
*/
|
||||
resetStyle() {
|
||||
let dataIndex = 0;
|
||||
const id = this._activeIds[0];
|
||||
for (let i = 0; i < id; i++) {
|
||||
dataIndex += this._indexs[i].length;
|
||||
}
|
||||
this._activeIds.forEach(index => {
|
||||
const vertindex = this._indexs[index];
|
||||
vertindex.forEach(() => {
|
||||
this.setVertexValues(dataIndex++, {
|
||||
COLOR: this._style[index].color
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
import { DataType } from '@ali/r3-base';
|
||||
import BaseBufferGeometry from './baseBufferGeometry';
|
||||
|
||||
/**
|
||||
* 创建点图层几何体
|
||||
*/
|
||||
export default class RainGeometry extends BaseBufferGeometry {
|
||||
|
||||
constructor(opts) {
|
||||
opts.DrawMode = 'POINTS';
|
||||
super(opts);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造多边形数据
|
||||
* @private
|
||||
*/
|
||||
initialize() {
|
||||
super.initialize([
|
||||
{ semantic: 'POSITION', size: 3, type: DataType.FLOAT, normalized: false },
|
||||
{ semantic: 'TEXCOORD_0', size: 2, type: DataType.FLOAT, normalized: false }
|
||||
], this._position.length);
|
||||
|
||||
this._position.forEach((vert, j) => {
|
||||
this.setVertexValues(j, {
|
||||
POSITION: vert,
|
||||
TEXCOORD_0: this._uv[j]
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
import { DataType, DrawMode } from '@ali/r3-base';
|
||||
import BaseBufferGeometry from './baseBufferGeometry';
|
||||
/**
|
||||
* 创建Polygon几何体
|
||||
*/
|
||||
export default class TextGeometry extends BaseBufferGeometry {
|
||||
|
||||
constructor(opts) {
|
||||
opts.DrawMode = opts.drawMode || 'TRIANGLES';
|
||||
|
||||
super(opts);
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造多边形数据
|
||||
* @private
|
||||
*/
|
||||
initialize() {
|
||||
super.initialize([
|
||||
{ semantic: 'POSITION', size: 4, type: DataType.FLOAT, normalized: false },
|
||||
{ semantic: 'COLOR', size: 4, type: DataType.FLOAT, normalized: false },
|
||||
{ semantic: 'TEXCOORD_0', size: 2, type: DataType.FLOAT, normalized: false },
|
||||
{ semantic: 'SIZE', size: 1, type: DataType.FLOAT, normalized: false }
|
||||
], this._indexCount);
|
||||
let dataIndex = 0;
|
||||
this._position.forEach((pos, i) => {
|
||||
const color = this._style[i].color;
|
||||
const uv = this._uv[i];
|
||||
pos.forEach((p, j) => {
|
||||
this.setVertexValues(dataIndex++, {
|
||||
POSITION: p,
|
||||
COLOR: color,
|
||||
SIZE: [ this._style[i].size ],
|
||||
TEXCOORD_0: uv[j]
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
|
@ -22,9 +22,7 @@ export default function extrudePolygon(points, extrude) {
|
|||
|
||||
const triangles = earcut(flattengeo.vertices, flattengeo.holes, flattengeo.dimensions);
|
||||
cells = triangles;
|
||||
triangles.forEach(() => {
|
||||
faceUv.push(-1, -1);
|
||||
});
|
||||
|
||||
const pointCount = flattengeo.vertices.length / 3;
|
||||
const { vertices } = flattengeo;
|
||||
extrude ? full() : flat();
|
||||
|
@ -32,11 +30,16 @@ export default function extrudePolygon(points, extrude) {
|
|||
|
||||
function flat() {
|
||||
for (let i = 0; i < pointCount; i++) {
|
||||
|
||||
positions.push([ vertices[ i * 3 ], vertices[i * 3 + 1 ], 0 ]);
|
||||
}
|
||||
}
|
||||
function full() {
|
||||
// 顶部纹理
|
||||
triangles.forEach(() => {
|
||||
faceUv.push(-1, -1);
|
||||
});
|
||||
// 顶部坐标
|
||||
|
||||
for (let i = 0; i < pointCount; i++) {
|
||||
positions.push([ vertices[ i * 3 ], vertices[i * 3 + 1 ], 1 ]);
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import * as THREE from '../../core/three';
|
||||
import image_frag from '../shader/image_frag.glsl';
|
||||
import image_vert from '../shader/image_vert.glsl';
|
||||
import Material from './material';
|
||||
export default function ImageMaterial(options) {
|
||||
const material = new THREE.ShaderMaterial({
|
||||
const material = new Material({
|
||||
uniforms: {
|
||||
u_opacity: { value: options.u_opacity },
|
||||
u_texture: { value: options.u_texture }
|
||||
|
@ -11,8 +11,5 @@ export default function ImageMaterial(options) {
|
|||
fragmentShader: image_frag,
|
||||
transparent: true
|
||||
});
|
||||
// material.roughness = 1;
|
||||
// material.metalness = 0.1;
|
||||
// material.envMapIntensity = 3;
|
||||
return material;
|
||||
}
|
||||
|
|
|
@ -1,13 +1,21 @@
|
|||
import * as THREE from '../../core/three';
|
||||
import Material from './material';
|
||||
import line_frag from '../shader/line_frag.glsl';
|
||||
import line_vert from '../shader/line_vert.glsl';
|
||||
import arcline_frag from '../shader/arcline_frag.glsl';
|
||||
import arcline_vert from '../shader/arcline_vert.glsl';
|
||||
import meshline_vert from '../shader/meshline_vert.glsl';
|
||||
import meshline_frag from '../shader/meshline_frag.glsl';
|
||||
import dashline_frag from '../shader/dashline_frag.glsl';
|
||||
import dashline_vert from '../shader/dashline_vert.glsl';
|
||||
|
||||
|
||||
export function LineMaterial(options) {
|
||||
const material = new THREE.ShaderMaterial({
|
||||
const material = new Material({
|
||||
uniforms: {
|
||||
u_opacity: { value: options.u_opacity || 1.0 },
|
||||
currentTime: { value: options.u_time || 2500 }
|
||||
u_time: { value: options.u_time || 0 },
|
||||
u_zoom: { value: options.u_zoom || 10 }
|
||||
},
|
||||
vertexShader: line_vert,
|
||||
fragmentShader: line_frag,
|
||||
|
@ -17,13 +25,46 @@ export function LineMaterial(options) {
|
|||
return material;
|
||||
}
|
||||
export function ArcLineMaterial(options) {
|
||||
const material = new THREE.ShaderMaterial({
|
||||
const material = new Material({
|
||||
uniforms: {
|
||||
u_opacity: { value: options.u_opacity || 1.0 },
|
||||
segmentNumber: { value: 50 }
|
||||
segmentNumber: { value: 49 },
|
||||
u_time: { value: 0 },
|
||||
u_zoom: { value: options.u_zoom || 10 }
|
||||
},
|
||||
vertexShader: arcline_vert,
|
||||
fragmentShader: arcline_frag,
|
||||
transparent: true,
|
||||
blending: THREE.AdditiveBlending
|
||||
});
|
||||
return material;
|
||||
}
|
||||
|
||||
export function MeshLineMaterial(options) {
|
||||
const material = new Material({
|
||||
uniforms: {
|
||||
u_opacity: { value: options.u_opacity || 1.0 },
|
||||
u_time: { value: options.u_time || 0 },
|
||||
u_zoom: { value: options.u_zoom }
|
||||
},
|
||||
vertexShader: meshline_vert,
|
||||
fragmentShader: meshline_frag,
|
||||
transparent: true
|
||||
});
|
||||
return material;
|
||||
}
|
||||
export function DashLineMaterial(options) {
|
||||
const material = new Material({
|
||||
uniforms: {
|
||||
u_opacity: { value: options.u_opacity || 1.0 },
|
||||
u_time: { value: options.u_time || 0 },
|
||||
u_zoom: { value: options.u_zoom },
|
||||
u_dashSteps: { value: options.u_dashSteps || 12 },
|
||||
u_dashSmooth: { value: options.u_dashSmooth || 0.01 },
|
||||
u_dashDistance: { value: options.u_dashDistance || 0.2 }
|
||||
},
|
||||
vertexShader: dashline_vert,
|
||||
fragmentShader: dashline_frag,
|
||||
transparent: true
|
||||
});
|
||||
return material;
|
||||
|
|
|
@ -1,11 +1,29 @@
|
|||
|
||||
import * as THREE from '../../core/three';
|
||||
export default class Material extends THREE.ShaderMaterial {
|
||||
constructor(opts) {
|
||||
super(opts);
|
||||
}
|
||||
setValue(name, value) {
|
||||
setUniformsValue(name, value) {
|
||||
if (!this.uniforms[name]) { return; }
|
||||
this.uniforms[name].value = value;
|
||||
this.uniforms.needsUpdate = true;
|
||||
}
|
||||
setDefinesvalue(name, value) {
|
||||
this.defines[name] = value;
|
||||
this.needsUpdate = true;
|
||||
}
|
||||
setUniform(option) {
|
||||
const uniforms = {};
|
||||
for (const key in option) {
|
||||
if (key.substr(0, 2) === 'u_') {
|
||||
uniforms[key] = { value: option[key] };
|
||||
}
|
||||
}
|
||||
return uniforms;
|
||||
}
|
||||
upDateUninform(option) {
|
||||
for (const key in option) {
|
||||
if (key.substr(0, 2) === 'u_') {
|
||||
this.setUniformsValue(key, option[key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,22 +1,37 @@
|
|||
import * as THREE from '../../core/three';
|
||||
import Material from './material';
|
||||
import point_frag from '../shader/point_frag.glsl';
|
||||
import point_vert from '../shader/point_vert.glsl';
|
||||
export default function PointMaterial(options) {
|
||||
const material = new THREE.ShaderMaterial({
|
||||
uniforms: {
|
||||
u_opacity: { value: options.u_opacity },
|
||||
u_stroke: { value: options.u_stroke },
|
||||
u_strokeWidth: { value: options.u_strokeWidth },
|
||||
u_texture: { value: options.u_texture }
|
||||
},
|
||||
vertexShader: point_vert,
|
||||
fragmentShader: point_frag,
|
||||
blending: THREE.NormalBlending,
|
||||
transparent: true,
|
||||
defines: {
|
||||
SHAPE: true,
|
||||
TEXCOORD_0: !!options.u_texture
|
||||
|
||||
export default class PointMaterial extends Material {
|
||||
getDefaultParameters() {
|
||||
return {
|
||||
uniforms: {
|
||||
u_opacity: { value: 1 },
|
||||
u_stroke: { value: [ 1.0, 1.0, 1.0, 1.0 ] },
|
||||
u_strokeWidth: { value: 1 }
|
||||
},
|
||||
defines: {
|
||||
SHAPE: false,
|
||||
TEXCOORD_0: false
|
||||
}
|
||||
};
|
||||
}
|
||||
constructor(_uniforms, _defines, parameters) {
|
||||
super(parameters);
|
||||
const { uniforms, defines } = this.getDefaultParameters();
|
||||
|
||||
this.uniforms = Object.assign(uniforms, this.setUniform(_uniforms));
|
||||
this.defines = Object.assign(defines, _defines);
|
||||
this.type = 'PointMaterial';
|
||||
this.vertexShader = point_vert;
|
||||
this.fragmentShader = point_frag;
|
||||
this.transparent = true;
|
||||
if (!_uniforms.shape) { this.blending = THREE.AdditiveBlending; }
|
||||
if (_uniforms.u_texture) {
|
||||
this.defines.TEXCOORD_0 = true;
|
||||
}
|
||||
});
|
||||
return material;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1,11 +1,16 @@
|
|||
import * as THREE from '../../core/three';
|
||||
import polygon_frag from '../shader/polygon_frag.glsl';
|
||||
import polygon_vert from '../shader/polygon_vert.glsl';
|
||||
import Material from './material';
|
||||
export default function PolygonMaterial(options) {
|
||||
const material = new THREE.ShaderMaterial({
|
||||
const material = new Material({
|
||||
uniforms: {
|
||||
u_opacity: { value: options.u_opacity },
|
||||
u_texture: { value: options.u_texture }
|
||||
u_opacity: { value: options.u_opacity || 1.0 },
|
||||
u_texture: { value: options.u_texture },
|
||||
u_time: { value: options.u_time || 0 },
|
||||
u_zoom: { value: options.u_zoom || 0 },
|
||||
u_baseColor: { value: options.u_baseColor || [ 1.0, 0, 0, 1.0 ] },
|
||||
u_brightColor: { value: options.u_brightColor || [ 1.0, 0, 0, 1.0 ] },
|
||||
u_windowColor: { value: options.u_windowColor || [ 1.0, 0, 0, 1.0 ] }
|
||||
},
|
||||
vertexShader: polygon_vert,
|
||||
fragmentShader: polygon_frag,
|
||||
|
@ -14,8 +19,5 @@ export default function PolygonMaterial(options) {
|
|||
TEXCOORD_0: !!options.u_texture
|
||||
}
|
||||
});
|
||||
material.roughness = 1;
|
||||
material.metalness = 0.1;
|
||||
material.envMapIntensity = 3;
|
||||
return material;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import Material from './material';
|
||||
import * as THREE from '../../core/three';
|
||||
import raster_frag from '../shader/raster_frag.glsl';
|
||||
import raster_vert from '../shader/raster_vert.glsl';
|
||||
export default function ImageMaterial(options) {
|
||||
|
|