perf(shader): 优化线动画效果

This commit is contained in:
thinkinggis 2019-08-12 10:35:50 +08:00
parent 39e870af09
commit 94b76304ef
16 changed files with 275 additions and 59 deletions

View File

@ -13,7 +13,6 @@
<script>/*Fixing iframe window.innerHeight 0 issue in Safari*/ document.body.clientHeight; </script>
<script src="https://webapi.amap.com/maps?v=1.4.8&key=15cd8a57710d40c9b7c0e3cc120f1200&plugin=Map3D"></script>
<script src="https://gw.alipayobjects.com/os/antv/assets/lib/jquery-3.2.1.min.js"></script>
<link rel=stylesheet type=text/css href='../build/l7.css'>
<script src="../build/l7.js"></script>
<style>
#map { position:absolute; top:0; bottom:0; width:100%; }
@ -24,6 +23,8 @@
mapStyle: 'light', // 样式URL
center: [120.19382669582967, 30.258134],
pitch: 0,
minZoom:5,
maxZoom:15,
zoom: 12
});
window.scene = scene;
@ -45,6 +46,14 @@
strokeWidth: 1,
opacity: 0.9
}).render();
const popup = new L7.Popup({anchor:'left'}).setText('hello world')
const marker = new L7.Marker({color:'blue'})
.setLnglat( [120.19382669582967, 30.258134])
.setPopup(popup)
.addTo(scene);
layer.on('click',(e) => {
const { lnglat, feature } = e;
const popup = new L7.Popup()

View File

@ -18,18 +18,96 @@
<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="https://gw.alipayobjects.com/os/antv/pkg/_antv.l7-1.2.0-beta.1/build/l7.js"></script>
<script src="../build/l7.js"></script>
<script>
var buildLayer =null;
const scene = new L7.Scene({
id: 'map',
mapStyle: 'dark', // 样式URL
center: [120.173104, 30.244072],
pitch: 66.50572,
zoom: 15.79,
minZoom:10
center: [
120.15935897827148,
30.261736090037477
],
pitch:0,
zoom: 5,
minZoom: 0,
maxZoom: 18
});
const lineData = {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "LineString",
"coordinates": [
[
117.02636718749999,
37.79676317682161
],
[
117.20214843749999,
37.23032838760387
],
[
117.31201171875001,
36.756490329505176
],
[
117.43286132812499,
36.38591277287651
],
[
117.586669921875,
35.871246850027966
],
[
117.76245117187499,
35.25459097465022
],
[
117.90527343750001,
34.732584206123626
],
[
117.99316406249999,
33.8339199536547
],
[
117.97119140625,
33.119150226768866
],
[
117.48779296875,
32.80574473290688
],
[
116.773681640625,
32.713355353177555
],
[
115.67504882812501,
32.704111144407406
],
[
114.510498046875,
32.85190345738802
],
[
113.818359375,
33.61461929233378
],
[
113.70849609375,
33.970697997361626
]
]
}
}
]
}
scene.on('loaded', () => {
$.get('https://gw.alipayobjects.com/os/basement_prod/40ef2173-df66-4154-a8c0-785e93a5f18e.json', data => {
scene.LineLayer({
@ -37,15 +115,17 @@ scene.on('loaded', () => {
})
.source(data)
.size(1)
.shape('line')
.color('#ff893a')
.animate({
enable:true,
interval:0.2,
duration:5,
trailLength:0.2
interval:0.4,
duration:1,
trailLength:0.8
})
.render();
});
$.get('https://gw.alipayobjects.com/os/rmsportal/ggFwDClGjjvpSMBIrcEx.json', data => {
buildLayer = scene.PolygonLayer({
zIndex: 2
@ -65,6 +145,7 @@ scene.on('loaded', () => {
});
});
</script>

96
demos/marker.html Normal file
View File

@ -0,0 +1,96 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="https://gw.alipayobjects.com/os/rmsportal/PqLCOJpqoOUfuPRacUzE.css" />
<title>气泡图</title>
<style> ::-webkit-scrollbar{display:none;}html,body{overflow:hidden;margin:0;}
#map { position:absolute; top:0; bottom:0; width:100%; }
</style>
</head>
<body>
<div id="map"></div>
<script>/*Fixing iframe window.innerHeight 0 issue in Safari*/ document.body.clientHeight; </script>
<script src="https://webapi.amap.com/maps?v=1.4.8&key=15cd8a57710d40c9b7c0e3cc120f1200&plugin=Map3D"></script>
<script src="https://gw.alipayobjects.com/os/antv/assets/lib/jquery-3.2.1.min.js"></script>
<script src="https://gw.alipayobjects.com/os/antv/pkg/_antv.g2-3.5.1/dist/g2.min.js"></script>
<script src="../build/l7.js"></script>
<style>
#map { position:absolute; top:0; bottom:0; width:100%; }
</style>
<script>
G2.Global.renderer = 'svg'
var scene = new L7.Scene({
id: 'map',
mapStyle: 'light', // 样式URL
center: [120.19382669582967, 30.258134],
pitch: 0,
minZoom:5,
maxZoom:15,
zoom: 3
});
window.scene = scene;
scene.on('loaded', function() {
$.getJSON('https://gw.alipayobjects.com/os/basement_prod/0b96cca4-7e83-449a-93d0-2a77053e74ab.json', function(data) {
console.log(data);
data.nodes.forEach(item=>{
const el = document.createElement('div');
const total = item.gdp.Agriculture + item.gdp.Industry + item.gdp.Service;
const size =Math.max(Math.min(parseInt(total / 20000), 150),40)
console.log(item.name, size);
var data = [{
item: 'Agriculture',
count: item.gdp.Agriculture,
percent: item.gdp.Agriculture / total
}, {
item: 'Industry',
count: item.gdp.Industry,
percent: item.gdp.Industry / total
}, {
item: 'Service',
count: item.gdp.Service,
percent: item.gdp.Service / total
}];
var chart = new G2.Chart({
container: el,
width:size,
height:size,
render:'svg',
padding:5,
});
chart.source(data, {
percent: {
formatter: function formatter(val) {
val = val * 100 + '%';
return val;
}
}
});
chart.coord('theta', {
radius: 1.0
});
chart.legend(false);
chart.tooltip(false);
chart.intervalStack().position('percent').color('item').style({
lineWidth: 1,
stroke: '#fff'
});
chart.render();
const popup = new L7.Popup({anchor:'left'}).setText(item.name);
const marker = new L7.Marker({color:'blue', element:el})
.setLnglat( item.coordinates)
.setPopup(popup)
.addTo(scene);
})
})
});
</script>
</body>
</html>

View File

@ -25,7 +25,7 @@
const scene = new L7.Scene({
id: 'map',
mapStyle: 'light', // 样式URL
mapStyle: 'dark', // 样式URL
center: [104.838088,34.075889 ],
pitch: 0,
hash:false,
@ -42,7 +42,7 @@ scene.on('loaded', () => {
attributeCtr.addTo(scene);
scene.addTileSource('test',{
url:'http://127.0.0.1:8080/{z}/{x}/{y}.pbf',
url:' https://mvt.amap.com/district/CHN2/{z}/{x}/{y}/4096?key=608d75903d29ad471362f8c58c550daf',
type:'vector',
minZoom: 0,
maxZoom:9
@ -54,8 +54,8 @@ scene.on('loaded', () => {
.source('test',{
parser:{
type: 'mvt',
sourceLayer:'boundaries_admin_3',
idField:'id'
sourceLayer:'CHN_Cities',
idField:'adcode'
}
})
.shape('fill')
@ -70,20 +70,21 @@ scene.on('loaded', () => {
const { lnglat, feature } = e;
const popup = new L7.Popup()
.setLnglat([lnglat.lng, lnglat.lat])
.setHTML(feature.properties.id).addTo(scene);
.setHTML(feature.properties.NAME_CHN.toString()).addTo(scene);
})
const layer2 = scene.PolygonLayer({
const layer2 = scene.LineLayer({
zIndex:10,
})
.source('test',{
parser:{
type: 'mvt',
sourceLayer:'boundaries_admin_3',
idField:'id'
sourceLayer:'CHN_L',
idField:'adcode'
}
})
.shape('line')
.size(1)
.size(2)
.active(false)
.color('#fff')
.style({
@ -91,6 +92,7 @@ scene.on('loaded', () => {
})
.render();
/**
const layer3 = scene.PointLayer({
zIndex:10,
})
@ -109,13 +111,15 @@ scene.on('loaded', () => {
opacity:1.0
})
.render();
**/
const overlayers = {
"行政区划": layer,
"标注": layer3,
"行政区边界": layer2,
};
const layerContr = new L7.Control.Layers({overlayers}).addTo(scene);
const popup = new L7.Popup({anchor:'left'}).setText('hello world')
const marker = new L7.Marker({color:'red'})
const marker = new L7.Marker({color:'blue'})
.setLnglat([104.838088,34.075889 ])
.setPopup(popup)
.addTo(scene);

View File

@ -12,8 +12,9 @@ export default class Zoom extends Control {
...cfg
});
bindAll([ '_updateDisabled', '_zoomIn', '_zoomOut' ], this);
this._disabled = false;
}
onAdd() {
onAdd(scene) {
const zoomName = 'l7-control-zoom';
const container = DOM.create('div', zoomName + ' l7-bar');
@ -21,14 +22,14 @@ export default class Zoom extends Control {
zoomName + '-in', container, this._zoomIn);
this._zoomOutButton = this._createButton(this.get('zoomOutText'), this.get('zoomOutTitle'),
zoomName + '-out', container, this._zoomOut);
scene.on('zoomend', this._updateDisabled);
scene.on('zoomchange', this._updateDisabled);
this._updateDisabled();
this._scene.on('zoomend', this._updateDisabled);
this._scene.on('zoomchange', this._updateDisabled);
return container;
}
onRemove() {
this._scene.off('zoomend', this._updateDisabled);
this._scene.off('zoomchange', this._updateDisabled);
onRemove(scene) {
scene.off('zoomend', this._updateDisabled);
scene.off('zoomchange', this._updateDisabled);
}
disable() {
this._disabled = true;
@ -63,11 +64,10 @@ export default class Zoom extends Control {
const className = 'l7-disabled';
DOM.removeClass(this._zoomInButton, className);
DOM.removeClass(this._zoomOutButton, className);
if (this._disabled || scene.getZoom() === scene.get('minZoom')) {
if (this._disabled || scene.getZoom() <= scene.get('minZoom')) {
DOM.addClass(this._zoomOutButton, className);
}
if (this._disabled || scene._zoom === scene.get('maxZoom')) {
if (this._disabled || scene.getZoom() >= scene.get('maxZoom')) {
DOM.addClass(this._zoomInButton, className);
}
}

View File

@ -42,12 +42,8 @@ export default class Marker extends Base {
}
DOM.addClass(element, 'l7-marker');
element.addEventListener('dragstart', e => {
e.preventDefault();
});
element.addEventListener('click', e => {
e.preventDefault();
this._onMapClick();
this._onMapClick(e);
});
applyAnchorClass(element, this.get('anchor'), 'marker');
@ -61,7 +57,6 @@ export default class Marker extends Base {
this._scene.on('camerachange', this._update);
this.setDraggable(this.get('draggable'));
this._update();
// this._scene.on('click', this._onMapClick);
return this;
}
@ -142,5 +137,32 @@ export default class Marker extends Base {
this.get('element').style.left = pos.x + 'px';
this.get('element').style.top = pos.y + 'px';
}
_bubbleUp() {
const eventsName = [
'mouseout',
'mouseover',
'mousemove',
'mousedown',
'mouseleave',
'mouseup',
'rightclick',
'click',
'dblclick',
'wheel'
];
const element = this.get('element');
eventsName.forEach(event => {
element.addEventListener(event, e => {
this._scene.emit(event, e);
});
});
}
_addDragHandler() {
}
_onUp() {
}
}

View File

@ -18,13 +18,13 @@ export default class Popup extends Base {
if (this.get('closeOnClick')) {
this._scene.on('click', this._onClickClose);
}
this._scene.on('mapmove', this._update);
this._scene.on('camerachange', this._update);
this._update();
}
setLnglat(lngLat) {
this.lngLat = lngLat;
if (this._scene) {
this._scene.on('mapmove', this._update);
this._scene.on('camerachange', this._update);
}
this._update(lngLat);
return this;
@ -123,7 +123,7 @@ export default class Popup extends Base {
delete this._container;
}
if (this._scene) {
this._scene.off('mapmove', this._update);
this._scene.off('camerachange', this._update);
this._scene.off('click', this._onClickClose);
delete this._scene;
}

View File

@ -20,7 +20,6 @@ export default class Scene extends Base {
super(cfg);
this._initMap();
this.crs = epsg3857;
this._initContoller();
// this._initAttribution(); // 暂时取消,后面作为组件去加载
this.addImage();
this.fontAtlasManager = new FontAtlasManager();
@ -68,6 +67,7 @@ export default class Scene extends Base {
interaction._onHashChange();
}
this.style = new Style(this, {});
this._initContoller();
this.emit('loaded');
this._engine.update();
});

View File

@ -5,6 +5,9 @@ export default class ArcLineBuffer extends BufferBase {
layerData.forEach((feature, index) => {
this._calculateArc(feature, index);
});
this.hasPattern = layerData.some(layer => {
return layer.pattern;
});
}
_initAttributes() {
super._initAttributes();

View File

@ -6,7 +6,8 @@ uniform float u_dash_ratio : 0.0;
uniform float u_blur : 0.9;
varying vec4 v_color;
#ifdef DASHLINE
uniform float u_time : 0;
#if defined DASHLINE || defined ANIMATE
varying float v_distance_ratio;
#endif
varying float v_dash_array;
@ -41,15 +42,15 @@ void main() {
#endif
#ifdef DASHLINE
gl_FragColor.a *= u_opacity * ceil(mod(v_distance_ratio + u_dash_offset, v_dash_array) - (v_dash_array * u_dash_ratio));
gl_FragColor.a *= u_opacity * ceil(mod(v_distance_ratio + u_dash_offset + u_time / 10., v_dash_array) - (v_dash_array * u_dash_ratio));
#else
gl_FragColor.a *= u_opacity;
#endif
#ifdef ANIMATE
float alpha =1.0 - fract( mod(1.0- v_distance_ratio,u_interval)* (1.0/u_interval) + u_time / u_duration);
alpha = (alpha + u_trailLength -1.0) / u_trailLength;
v_time = clamp(alpha,0.,1.);
gl_FragColor.a *= v_time;
alpha = smoothstep(0., 1., alpha);
gl_FragColor.a *= alpha;
#endif
// anti-alias
float blur = 1. - smoothstep(u_blur, 1., length(v_normal));

View File

@ -14,7 +14,7 @@ varying float v_time;
varying vec4 v_color;
varying float v_dash_array;
varying vec2 v_normal;
#ifdef DASHLINE
#if defined DASHLINE || defined ANIMATE
varying float v_distance_ratio;
#endif
@ -37,7 +37,7 @@ void main() {
v_color = a_color;
v_dash_array = a_dash_array;
float distance_ratio = a_distance / a_total_distance;
#ifdef DASHLINE
#if defined DASHLINE || defined ANIMATE
v_distance_ratio = distance_ratio;
#endif
#ifdef TEXTURE
@ -57,12 +57,6 @@ void main() {
gl_Position = projectionMatrix * modelViewMatrix * vec4(position.xy + offset.xy, 0., 1.0);
// gl_Position.z -=0.8 * gl_Position.w;
// #ifdef ANIMATE
// float alpha =1.0 - fract( mod(1.0- distance_ratio,u_interval)* (1.0/u_interval) + u_time / u_duration);
// alpha = (alpha + u_trailLength -1.0) / u_trailLength;
// v_time = clamp(alpha,0.,1.);
// #endif
// picking
if(pickingId == u_activeId) {
v_color = u_activeColor;

View File

@ -1,8 +1,13 @@
import Layer from '../core/layer';
import { getRender } from './render';
export default class LineLayer extends Layer {
constructor(scene, cfg) {
super(scene, cfg);
this.set('type', 'line');
}
shape(type) {
this.shapeType = type;
this.set('shape', type);
return this;
}
preRender() {

View File

@ -9,9 +9,9 @@ export default function DrawLine(layerData, layer, buffer) {
const activeOption = layer.get('activedOptions');
// const pattern = style.pattern;
// const texture = layer.scene.image.singleImages[pattern];
const hasPattern = layerData.some(layer => {
return layer.pattern;
});
// const hasPattern = layerData.some(layer => {
// return layer.pattern;
// });
if (!buffer) {
const geometryBuffer = getBuffer(layer.type, layer.shapeType);
buffer = new geometryBuffer({
@ -22,7 +22,7 @@ export default function DrawLine(layerData, layer, buffer) {
});
}
const { attributes, indexArray } = buffer;
const { attributes, indexArray, hasPattern } = buffer;
const geometry = new THREE.BufferGeometry();
@ -70,7 +70,7 @@ export default function DrawLine(layerData, layer, buffer) {
u_trailLength: trailLength
});
lineMaterial.setDefinesvalue('ANIMATE', true);
lineMaterial.setDefinesvalue('DASHLINE', true);
// lineMaterial.setDefinesvalue('DASHLINE', true);
}
return lineMesh;
}

View File

@ -33,7 +33,7 @@ export default class GaodeMap extends Base {
this.addOverLayer();
setTimeout(() => {
this.emit('mapLoad');
}, 100);
}, 10);
}
initMap() {

View File

@ -26,7 +26,7 @@ export default class MapBox extends Base {
this.addOverLayer();
setTimeout(() => {
this.emit('mapLoad');
}, 100);
}, 10);
}

View File

@ -40,7 +40,8 @@ export default class WorkerTile {
const geometryBuffer = getBuffer(style.type, style.shape);
const buffer = new geometryBuffer({
layerData: tileMapping.layerData,
shape: style.shape
shape: style.shape,
style
});
sourceLayerData[style.layerId] = {
buffer: {