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

This commit is contained in:
thinkinggis 2019-08-12 10:35:50 +08:00
parent 77caab4b51
commit 4bd1f27b47
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>/*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://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/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> <script src="../build/l7.js"></script>
<style> <style>
#map { position:absolute; top:0; bottom:0; width:100%; } #map { position:absolute; top:0; bottom:0; width:100%; }
@ -24,6 +23,8 @@
mapStyle: 'light', // 样式URL mapStyle: 'light', // 样式URL
center: [120.19382669582967, 30.258134], center: [120.19382669582967, 30.258134],
pitch: 0, pitch: 0,
minZoom:5,
maxZoom:15,
zoom: 12 zoom: 12
}); });
window.scene = scene; window.scene = scene;
@ -45,6 +46,14 @@
strokeWidth: 1, strokeWidth: 1,
opacity: 0.9 opacity: 0.9
}).render(); }).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) => { layer.on('click',(e) => {
const { lnglat, feature } = e; const { lnglat, feature } = e;
const popup = new L7.Popup() 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="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/jquery-3.2.1.min.js"></script>
<script src="./assets/dat.gui.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> <script>
var buildLayer =null; var buildLayer =null;
const scene = new L7.Scene({ const scene = new L7.Scene({
id: 'map', id: 'map',
mapStyle: 'dark', // 样式URL mapStyle: 'dark', // 样式URL
center: [120.173104, 30.244072], center: [
pitch: 66.50572, 120.15935897827148,
zoom: 15.79, 30.261736090037477
minZoom:10 ],
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', () => { scene.on('loaded', () => {
$.get('https://gw.alipayobjects.com/os/basement_prod/40ef2173-df66-4154-a8c0-785e93a5f18e.json', data => { $.get('https://gw.alipayobjects.com/os/basement_prod/40ef2173-df66-4154-a8c0-785e93a5f18e.json', data => {
scene.LineLayer({ scene.LineLayer({
@ -37,15 +115,17 @@ scene.on('loaded', () => {
}) })
.source(data) .source(data)
.size(1) .size(1)
.shape('line')
.color('#ff893a') .color('#ff893a')
.animate({ .animate({
enable:true, enable:true,
interval:0.2, interval:0.4,
duration:5, duration:1,
trailLength:0.2 trailLength:0.8
}) })
.render(); .render();
}); });
$.get('https://gw.alipayobjects.com/os/rmsportal/ggFwDClGjjvpSMBIrcEx.json', data => { $.get('https://gw.alipayobjects.com/os/rmsportal/ggFwDClGjjvpSMBIrcEx.json', data => {
buildLayer = scene.PolygonLayer({ buildLayer = scene.PolygonLayer({
zIndex: 2 zIndex: 2
@ -65,6 +145,7 @@ scene.on('loaded', () => {
}); });
}); });
</script> </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({ const scene = new L7.Scene({
id: 'map', id: 'map',
mapStyle: 'light', // 样式URL mapStyle: 'dark', // 样式URL
center: [104.838088,34.075889 ], center: [104.838088,34.075889 ],
pitch: 0, pitch: 0,
hash:false, hash:false,
@ -42,7 +42,7 @@ scene.on('loaded', () => {
attributeCtr.addTo(scene); attributeCtr.addTo(scene);
scene.addTileSource('test',{ 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', type:'vector',
minZoom: 0, minZoom: 0,
maxZoom:9 maxZoom:9
@ -54,8 +54,8 @@ scene.on('loaded', () => {
.source('test',{ .source('test',{
parser:{ parser:{
type: 'mvt', type: 'mvt',
sourceLayer:'boundaries_admin_3', sourceLayer:'CHN_Cities',
idField:'id' idField:'adcode'
} }
}) })
.shape('fill') .shape('fill')
@ -70,20 +70,21 @@ scene.on('loaded', () => {
const { lnglat, feature } = e; const { lnglat, feature } = e;
const popup = new L7.Popup() const popup = new L7.Popup()
.setLnglat([lnglat.lng, lnglat.lat]) .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, zIndex:10,
}) })
.source('test',{ .source('test',{
parser:{ parser:{
type: 'mvt', type: 'mvt',
sourceLayer:'boundaries_admin_3', sourceLayer:'CHN_L',
idField:'id' idField:'adcode'
} }
}) })
.shape('line') .shape('line')
.size(1) .size(2)
.active(false) .active(false)
.color('#fff') .color('#fff')
.style({ .style({
@ -91,6 +92,7 @@ scene.on('loaded', () => {
}) })
.render(); .render();
/**
const layer3 = scene.PointLayer({ const layer3 = scene.PointLayer({
zIndex:10, zIndex:10,
}) })
@ -109,13 +111,15 @@ scene.on('loaded', () => {
opacity:1.0 opacity:1.0
}) })
.render(); .render();
**/
const overlayers = { const overlayers = {
"行政区划": layer, "行政区划": layer,
"标注": layer3, "行政区边界": layer2,
}; };
const layerContr = new L7.Control.Layers({overlayers}).addTo(scene); const layerContr = new L7.Control.Layers({overlayers}).addTo(scene);
const popup = new L7.Popup({anchor:'left'}).setText('hello world') 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 ]) .setLnglat([104.838088,34.075889 ])
.setPopup(popup) .setPopup(popup)
.addTo(scene); .addTo(scene);

View File

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

View File

@ -42,12 +42,8 @@ export default class Marker extends Base {
} }
DOM.addClass(element, 'l7-marker'); DOM.addClass(element, 'l7-marker');
element.addEventListener('dragstart', e => {
e.preventDefault();
});
element.addEventListener('click', e => { element.addEventListener('click', e => {
e.preventDefault(); this._onMapClick(e);
this._onMapClick();
}); });
applyAnchorClass(element, this.get('anchor'), 'marker'); applyAnchorClass(element, this.get('anchor'), 'marker');
@ -61,7 +57,6 @@ export default class Marker extends Base {
this._scene.on('camerachange', this._update); this._scene.on('camerachange', this._update);
this.setDraggable(this.get('draggable')); this.setDraggable(this.get('draggable'));
this._update(); this._update();
// this._scene.on('click', this._onMapClick);
return this; return this;
} }
@ -142,5 +137,32 @@ export default class Marker extends Base {
this.get('element').style.left = pos.x + 'px'; this.get('element').style.left = pos.x + 'px';
this.get('element').style.top = pos.y + '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')) { if (this.get('closeOnClick')) {
this._scene.on('click', this._onClickClose); this._scene.on('click', this._onClickClose);
} }
this._scene.on('mapmove', this._update); this._scene.on('camerachange', this._update);
this._update(); this._update();
} }
setLnglat(lngLat) { setLnglat(lngLat) {
this.lngLat = lngLat; this.lngLat = lngLat;
if (this._scene) { if (this._scene) {
this._scene.on('mapmove', this._update); this._scene.on('camerachange', this._update);
} }
this._update(lngLat); this._update(lngLat);
return this; return this;
@ -123,7 +123,7 @@ export default class Popup extends Base {
delete this._container; delete this._container;
} }
if (this._scene) { if (this._scene) {
this._scene.off('mapmove', this._update); this._scene.off('camerachange', this._update);
this._scene.off('click', this._onClickClose); this._scene.off('click', this._onClickClose);
delete this._scene; delete this._scene;
} }

View File

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

View File

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

View File

@ -6,7 +6,8 @@ uniform float u_dash_ratio : 0.0;
uniform float u_blur : 0.9; uniform float u_blur : 0.9;
varying vec4 v_color; varying vec4 v_color;
#ifdef DASHLINE uniform float u_time : 0;
#if defined DASHLINE || defined ANIMATE
varying float v_distance_ratio; varying float v_distance_ratio;
#endif #endif
varying float v_dash_array; varying float v_dash_array;
@ -41,15 +42,15 @@ void main() {
#endif #endif
#ifdef DASHLINE #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 #else
gl_FragColor.a *= u_opacity; gl_FragColor.a *= u_opacity;
#endif #endif
#ifdef ANIMATE #ifdef ANIMATE
float alpha =1.0 - fract( mod(1.0- v_distance_ratio,u_interval)* (1.0/u_interval) + u_time / u_duration); 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; alpha = (alpha + u_trailLength -1.0) / u_trailLength;
v_time = clamp(alpha,0.,1.); alpha = smoothstep(0., 1., alpha);
gl_FragColor.a *= v_time; gl_FragColor.a *= alpha;
#endif #endif
// anti-alias // anti-alias
float blur = 1. - smoothstep(u_blur, 1., length(v_normal)); 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 vec4 v_color;
varying float v_dash_array; varying float v_dash_array;
varying vec2 v_normal; varying vec2 v_normal;
#ifdef DASHLINE #if defined DASHLINE || defined ANIMATE
varying float v_distance_ratio; varying float v_distance_ratio;
#endif #endif
@ -37,7 +37,7 @@ void main() {
v_color = a_color; v_color = a_color;
v_dash_array = a_dash_array; v_dash_array = a_dash_array;
float distance_ratio = a_distance / a_total_distance; float distance_ratio = a_distance / a_total_distance;
#ifdef DASHLINE #if defined DASHLINE || defined ANIMATE
v_distance_ratio = distance_ratio; v_distance_ratio = distance_ratio;
#endif #endif
#ifdef TEXTURE #ifdef TEXTURE
@ -57,12 +57,6 @@ void main() {
gl_Position = projectionMatrix * modelViewMatrix * vec4(position.xy + offset.xy, 0., 1.0); gl_Position = projectionMatrix * modelViewMatrix * vec4(position.xy + offset.xy, 0., 1.0);
// gl_Position.z -=0.8 * gl_Position.w; // 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 // picking
if(pickingId == u_activeId) { if(pickingId == u_activeId) {
v_color = u_activeColor; v_color = u_activeColor;

View File

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

View File

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

View File

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

View File

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

View File

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