mirror of https://gitee.com/antv-l7/antv-l7
commit
4ecbc2ace1
|
@ -54,7 +54,7 @@ window.scene = scene;
|
|||
scene.on('loaded', () => {
|
||||
$.get('https://gw.alipayobjects.com/os/rmsportal/epnZEheZeDgsiSjSPcCv.json', data => {
|
||||
console.log(data);
|
||||
const circleLayer = scene.PointLayer({
|
||||
const circleLayer = = scene.PointLayer({
|
||||
zIndex: 0,
|
||||
})
|
||||
.source(data,{
|
||||
|
@ -76,7 +76,6 @@ scene.on('loaded', () => {
|
|||
})
|
||||
.source(circleLayer.layerSource)
|
||||
.shape('point_count', 'text')
|
||||
.active(true)
|
||||
.size('point_count', [ 10, 20, 24 ])
|
||||
.color('#FFF')
|
||||
.style({
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
<!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>hexagon demo</title>
|
||||
<style>
|
||||
body {margin: 0;}
|
||||
#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: [121.5558, 31.2481 ],
|
||||
pitch: 0,
|
||||
zoom: 11,
|
||||
hash:true,
|
||||
|
||||
});
|
||||
window.scene = scene;
|
||||
scene.on('loaded', () => {
|
||||
$.getJSON('https://gw.alipayobjects.com/os/basement_prod/7bb614db-bac0-48d7-93e7-9446392d3917.json', city => {
|
||||
const layer = scene.PolygonLayer()
|
||||
.source(city)
|
||||
.color('unit_price',['#b2182b','#ef8a62','#fddbc7','#d1e5f0','#67a9cf','#2166ac'].reverse())
|
||||
.shape('fill')
|
||||
.active(false)
|
||||
.style({
|
||||
opacity: 1
|
||||
})
|
||||
.render()
|
||||
const highlight = scene.LineLayer()
|
||||
.source(city)
|
||||
.color('#fff')
|
||||
.filter('unit_price', (price)=> { return price > 40000})
|
||||
.shape('line')
|
||||
.size(4)
|
||||
.render()
|
||||
|
||||
layer.on('click',(item)=>{
|
||||
const { feature } = item;
|
||||
highlight.filter('id',(id)=>{
|
||||
return feature.properties.id === id;
|
||||
}).render();
|
||||
})
|
||||
})
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
<!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="../build/l7.js"></script>
|
||||
<style>
|
||||
#map { position:absolute; top:0; bottom:0; width:100%; }
|
||||
</style>
|
||||
<script>
|
||||
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',()=>{
|
||||
$.getJSON('https://gw.alipayobjects.com/os/basement_prod/1d27c363-af3a-469e-ab5b-7a7e1ce4f311.json', city => {
|
||||
const labeldata = city.features.map(fe=>{
|
||||
return fe.properties
|
||||
})
|
||||
const layer = scene.PolygonLayer()
|
||||
.source(city)
|
||||
.color('unit_price',['#b2182b','#ef8a62','#fddbc7','#d1e5f0','#67a9cf','#2166ac'].reverse())
|
||||
.shape('fill')
|
||||
.active(true)
|
||||
.style({
|
||||
opacity: 1
|
||||
})
|
||||
.render()
|
||||
const layer2= scene.PolygonLayer()
|
||||
.source(city)
|
||||
.color('#fff')
|
||||
.shape('line')
|
||||
.style({
|
||||
opacity: 1
|
||||
})
|
||||
.render()
|
||||
layer.fitBounds();
|
||||
scene.PointLayer({
|
||||
zIndex: 5
|
||||
})
|
||||
.source(labeldata,{
|
||||
parser:{
|
||||
type:'json',
|
||||
x:'longitude',
|
||||
y:'latitude'
|
||||
}
|
||||
})
|
||||
.shape('name', 'text')
|
||||
.size(20)
|
||||
.color('#000')
|
||||
.style({
|
||||
// fontFamily: 'Monaco, monospace', // 字体
|
||||
fontWeight: 200,
|
||||
textAnchor: 'center', // 文本相对锚点的位置 center|left|right|top|bottom|top-left
|
||||
textOffset: [ 0, 0 ], // 文本相对锚点的偏移量 [水平, 垂直]
|
||||
spacing: 2, // 字符间距
|
||||
padding: [ 4, 4 ], // 文本包围盒 padding [水平,垂直],影响碰撞检测结果,避免相邻文本靠的太近
|
||||
strokeColor: '#fff', // 描边颜色
|
||||
strokeWidth: 4, // 描边宽度
|
||||
opacity: 1.0
|
||||
})
|
||||
.render();
|
||||
})
|
||||
})
|
||||
</script>
|
|
@ -38,18 +38,18 @@ const scene = new L7.Scene({
|
|||
// 高德数据服务 https://mvt.amap.com/district/CHN2/{z}/{x}/{y}/4096?key=608d75903d29ad471362f8c58c550daf
|
||||
scene.on('loaded', () => {
|
||||
|
||||
const attributeCtr = new L7.Control.Attribution();
|
||||
attributeCtr.addTo(scene);
|
||||
|
||||
scene.addTileSource('test',{
|
||||
url:' https://mvt.amap.com/district/CHN2/{z}/{x}/{y}/4096?key=608d75903d29ad471362f8c58c550daf',
|
||||
type:'vector',
|
||||
minZoom: 0,
|
||||
maxZoom:9
|
||||
|
||||
})
|
||||
|
||||
const layer = scene.PolygonLayer({
|
||||
zIndex:0,
|
||||
attribution:'高德地图'
|
||||
})
|
||||
.source('test',{
|
||||
parser:{
|
||||
|
@ -66,13 +66,20 @@ scene.on('loaded', () => {
|
|||
opacity:1.0
|
||||
})
|
||||
.render();
|
||||
let id =0;
|
||||
|
||||
layer.on('click',(e) => {
|
||||
const { lnglat, feature } = e;
|
||||
const popup = new L7.Popup()
|
||||
console.log(lnglat);
|
||||
const popup = new L7.Popup({
|
||||
id:id++
|
||||
})
|
||||
.setLnglat([lnglat.lng, lnglat.lat])
|
||||
.setHTML(feature.properties.NAME_CHN.toString()).addTo(scene);
|
||||
.setText(feature.properties.NAME_CHN.toString()).addTo(scene);
|
||||
})
|
||||
|
||||
scene.on('click',(e)=>{
|
||||
console.log(e);
|
||||
})
|
||||
const layer2 = scene.LineLayer({
|
||||
zIndex:10,
|
||||
})
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@antv/l7",
|
||||
"version": "1.3.0-beta.1",
|
||||
"version": "1.3.0-beta.4",
|
||||
"description": "Large-scale WebGL-powered Geospatial Data Visualization",
|
||||
"main": "build/L7.js",
|
||||
"browser": "build/L7-min.js",
|
||||
|
|
|
@ -345,12 +345,12 @@
|
|||
border-radius: 5px;
|
||||
}
|
||||
.l7-control-layers-toggle {
|
||||
background-image: url(../images/layers.png);
|
||||
background-image: url(../images/layers.svg);
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
}
|
||||
.l7-retina .l7-control-layers-toggle {
|
||||
background-image: url(../images/layers-2x.png);
|
||||
background-image: url(../images/layers.svg);
|
||||
background-size: 26px 26px;
|
||||
}
|
||||
.l7-touch .l7-control-layers-toggle {
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 1.2 KiB |
Binary file not shown.
Before Width: | Height: | Size: 696 B |
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1566292427369" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8341" width="32" height="32" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><style type="text/css"></style></defs><path d="M256 341.333333l256 128 256-128-256-128-256 128z m276.864-208.384l341.034667 173.909334c20.736 10.581333 28.202667 34.56 16.682666 53.632a41.386667 41.386667 0 0 1-16.64 15.317333l-341.077333 173.909333a46.336 46.336 0 0 1-41.728 0L150.101333 375.808c-20.736-10.581333-28.202667-34.56-16.682666-53.632a41.386667 41.386667 0 0 1 16.64-15.317333l341.077333-173.909334c12.970667-6.613333 28.757333-6.613333 41.728 0z m0 587.349334a45.653333 45.653333 0 0 1-41.728 0l-341.034667-176.938667c-20.736-10.752-28.202667-35.157333-16.682666-54.528a41.642667 41.642667 0 0 1 16.64-15.573333 34.901333 34.901333 0 0 1 32.213333 0l308.906667 160.213333c12.928 6.741333 28.714667 6.741333 41.685333 0l308.864-160.213333a34.901333 34.901333 0 0 1 32.170667 0c20.736 10.752 28.202667 35.157333 16.682666 54.528a41.642667 41.642667 0 0 1-16.64 15.573333l-341.077333 176.938667z m0 170.666666a45.653333 45.653333 0 0 1-41.728 0l-341.034667-176.938666c-20.736-10.752-28.202667-35.157333-16.682666-54.528a41.642667 41.642667 0 0 1 16.64-15.573334 34.901333 34.901333 0 0 1 32.213333 0l308.906667 160.213334c12.928 6.741333 28.714667 6.741333 41.685333 0l308.864-160.213334a34.901333 34.901333 0 0 1 32.170667 0c20.736 10.752 28.202667 35.157333 16.682666 54.528a41.642667 41.642667 0 0 1-16.64 15.573334l-341.077333 176.938666z" fill="#000000" p-id="8342"></path></svg>
|
After Width: | Height: | Size: 1.7 KiB |
|
@ -11,15 +11,18 @@ export default class Popup extends Base {
|
|||
anchor: 'bottom',
|
||||
...cfg
|
||||
});
|
||||
|
||||
bindAll([ '_update', '_onClickClose', 'remove' ], this);
|
||||
}
|
||||
addTo(scene) {
|
||||
this._scene = scene;
|
||||
if (this.get('closeOnClick')) {
|
||||
this._scene.on('click', this._onClickClose);
|
||||
}
|
||||
this._scene.on('camerachange', this._update);
|
||||
this._update();
|
||||
if (this.get('closeOnClick')) {
|
||||
setTimeout(() => { // TODO 事件冲突
|
||||
this._scene.on('click', this._onClickClose);
|
||||
}, 30);
|
||||
}
|
||||
}
|
||||
setLnglat(lngLat) {
|
||||
this.lngLat = lngLat;
|
||||
|
|
|
@ -18,15 +18,20 @@ export default class Mapping {
|
|||
|
||||
_init() {
|
||||
this._initControllers();
|
||||
this._initTileAttrs();
|
||||
this._initAttrs();
|
||||
this._mapping();
|
||||
}
|
||||
|
||||
update() {
|
||||
this.mesh.set('scales', {});
|
||||
this._initTileAttrs();
|
||||
this._initAttrs();
|
||||
this._updateMaping();
|
||||
}
|
||||
reMapping() {
|
||||
this.mesh.set('scales', {});
|
||||
this._initAttrs();
|
||||
this._mapping();
|
||||
}
|
||||
|
||||
_initControllers() {
|
||||
const scalesOption = this.layer.get('scaleOptions');
|
||||
|
@ -144,7 +149,7 @@ export default class Mapping {
|
|||
}
|
||||
|
||||
|
||||
_initTileAttrs() {
|
||||
_initAttrs() {
|
||||
const attrOptions = this.layer.get('attrOptions');
|
||||
for (const type in attrOptions) {
|
||||
if (attrOptions.hasOwnProperty(type)) {
|
||||
|
|
|
@ -20,7 +20,7 @@ class Picking {
|
|||
depthBuffer: true
|
||||
};
|
||||
|
||||
this._pickingTexture = new THREE.WebGLRenderTarget(this._width, this._height, parameters);
|
||||
this._pickingTexture = new THREE.WebGLRenderTarget(this._width / 10, this._height / 10, parameters);
|
||||
|
||||
this._nextId = 1;
|
||||
|
||||
|
|
|
@ -81,16 +81,15 @@ export default class Layer extends Base {
|
|||
/**
|
||||
* 将图层添加加到 Object
|
||||
* @param {*} object three 物体
|
||||
* @param {*} type mesh类型是区别是填充还是边线
|
||||
*/
|
||||
add(object, type = 'fill') {
|
||||
add(object) {
|
||||
// composer合图层绘制
|
||||
if (object.type === 'composer') {
|
||||
this._object3D = object;
|
||||
this.scene._engine.composerLayers.push(object);
|
||||
return;
|
||||
}
|
||||
type === 'fill' ? this.layerMesh = object : this.layerLineMesh = object;
|
||||
this.layerMesh = object;
|
||||
this._visibleWithZoom();
|
||||
object.onBeforeRender = () => { // 每次渲染前改变状态
|
||||
const zoom = this.scene.getZoom();
|
||||
|
@ -105,9 +104,8 @@ export default class Layer extends Base {
|
|||
this.afterRender();
|
||||
};
|
||||
this._object3D.add(object);
|
||||
if (type === 'fill') {
|
||||
this.get('pickingController').addPickMesh(object);
|
||||
}
|
||||
this.get('pickingController').addPickMesh(object);
|
||||
|
||||
}
|
||||
remove(object) {
|
||||
if (object.type === 'composer') {
|
||||
|
@ -279,6 +277,7 @@ export default class Layer extends Base {
|
|||
setData(data, cfg) {
|
||||
this.layerSource.setData(data, cfg);
|
||||
this.repaint();
|
||||
this.scene._engine.update();
|
||||
}
|
||||
_createScale(field) {
|
||||
// TODO scale更新
|
||||
|
@ -331,7 +330,7 @@ export default class Layer extends Base {
|
|||
this.scene.style.update(this._attrs);
|
||||
return this;
|
||||
}
|
||||
this.init();
|
||||
this._updateDraw();
|
||||
this.scene._engine.update();
|
||||
return this;
|
||||
}
|
||||
|
@ -345,7 +344,6 @@ export default class Layer extends Base {
|
|||
init() {
|
||||
this._initControllers();
|
||||
this._mapping();
|
||||
this._updateDraw();
|
||||
}
|
||||
_initInteraction() {
|
||||
if (this.get('allowActive')) {
|
||||
|
@ -379,6 +377,7 @@ export default class Layer extends Base {
|
|||
|
||||
setActive(id, color) {
|
||||
this._activeIds = id;
|
||||
if (!color) color = Global.activeColor;
|
||||
if (!Array.isArray(color)) {
|
||||
color = ColorUtil.color2RGBA(color);
|
||||
}
|
||||
|
@ -407,31 +406,35 @@ export default class Layer extends Base {
|
|||
const preStyle = this.get('preStyleOption');
|
||||
const nextStyle = this.get('styleOptions');
|
||||
if (preAttrs === undefined && preStyle === undefined) { // 首次渲染
|
||||
// this._mapping();
|
||||
// this._scaleByZoom();
|
||||
this._setPreOption();
|
||||
this.init();
|
||||
this._initInteraction();
|
||||
this._initMapEvent();
|
||||
if (this.layerData.length === 0) {
|
||||
return;
|
||||
}
|
||||
this.draw();
|
||||
return;
|
||||
}
|
||||
if (!Util.isEqual(preAttrs.color, nextAttrs.color)) {
|
||||
this._updateAttributes(this.layerMesh);
|
||||
}
|
||||
// 更新数据过滤 filter
|
||||
if (!Util.isEqual(preAttrs.filter, nextAttrs.filter)) {
|
||||
// 更新color;
|
||||
this.repaint();
|
||||
this._setPreOption();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Util.isEqual(preAttrs.color, nextAttrs.color)) {
|
||||
this._updateAttributes(this.layerMesh);
|
||||
}
|
||||
// 更新Size
|
||||
if (!Util.isEqual(preAttrs.size, nextAttrs.size)) {
|
||||
// 更新color;
|
||||
this._updateSize();
|
||||
this.repaint();
|
||||
}
|
||||
// 更新形状
|
||||
if (!Util.isEqual(preAttrs.shape, nextAttrs.shape)) {
|
||||
// 更新color;
|
||||
this._updateShape();
|
||||
this.repaint();
|
||||
}
|
||||
if (!Util.isEqual(preStyle, nextStyle)) {
|
||||
// 判断新增,修改,删除
|
||||
|
@ -442,7 +445,6 @@ export default class Layer extends Base {
|
|||
});
|
||||
this._updateStyle(newStyle);
|
||||
}
|
||||
this._setPreOption();
|
||||
}
|
||||
|
||||
_updateSize(zoom) {
|
||||
|
@ -525,6 +527,9 @@ export default class Layer extends Base {
|
|||
style
|
||||
};
|
||||
}
|
||||
_updateFilter() {
|
||||
this.get('mappingController').reMapping();
|
||||
}
|
||||
/**
|
||||
* 用于过滤数据
|
||||
* @param {*} object 更新颜色和数据过滤
|
||||
|
|
|
@ -3,7 +3,6 @@ import { LAYER_MAP } from '../layer';
|
|||
import Base from './base';
|
||||
import LoadImage from './image';
|
||||
import FontAtlasManager from './atlas/font-manager';
|
||||
// import { MapProvider } from '../map/AMap';
|
||||
import { getMap } from '../map/index';
|
||||
import Global from '../global';
|
||||
import { getInteraction } from '../interaction/index';
|
||||
|
@ -42,6 +41,9 @@ export default class Scene extends Base {
|
|||
if (this.get('scaleControl')) {
|
||||
new Control.Scale().addTo(this);
|
||||
}
|
||||
if (this.get('attributionControl')) {
|
||||
new Control.Attribution().addTo(this);
|
||||
}
|
||||
}
|
||||
// 为pickup场景添加 object 对象
|
||||
addPickMesh(object) {
|
||||
|
@ -145,9 +147,7 @@ export default class Scene extends Base {
|
|||
// 要素拾取
|
||||
if (e.target.nodeName !== 'CANVAS') return;
|
||||
e.pixel || (e.pixel = e.point);
|
||||
requestAnimationFrame(() => {
|
||||
this._engine._picking.pickdata(e);
|
||||
});
|
||||
this._engine._picking.pickdata(e);
|
||||
}, true);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -40,6 +40,7 @@ export default class Source extends Base {
|
|||
this._transforms = transform || [];
|
||||
this.set('data', data);
|
||||
this._init();
|
||||
this.emit('SourceUpdate');
|
||||
}
|
||||
// 数据更新
|
||||
updateTransfrom(cfg) {
|
||||
|
|
|
@ -6,7 +6,8 @@ export default function TextMaterial(_uniforms) {
|
|||
const { vs, fs, uniforms } = getModule('text');
|
||||
const material = new Material({
|
||||
defines: {
|
||||
DEVICE_PIXEL_RATIO: window.devicePixelRatio
|
||||
SDF_PX: '8.0',
|
||||
EDGE_GAMMA: 0.105 / window.devicePixelRatio
|
||||
},
|
||||
uniforms: wrapUniforms(merge(uniforms, _uniforms)),
|
||||
vertexShader: vs,
|
||||
|
|
|
@ -56,7 +56,6 @@ void main() {
|
|||
float segmentRatio = getSegmentRatio(segmentIndex);
|
||||
float indexDir = mix(-1.0, 1.0, step(segmentIndex, 0.0));
|
||||
float nextSegmentRatio = getSegmentRatio(segmentIndex + indexDir);
|
||||
v_distance_ratio = segmentIndex / segmentNumber;
|
||||
vec3 curr = getPos(source, target, segmentRatio);
|
||||
vec3 next = getPos(source, target, nextSegmentRatio);
|
||||
vec2 offset = getExtrusionOffset((next.xy - curr.xy) * indexDir, position.y);
|
||||
|
|
|
@ -42,14 +42,15 @@ void main() {
|
|||
#endif
|
||||
|
||||
#ifdef DASHLINE
|
||||
float time = u_time;
|
||||
float time = 0.;
|
||||
#ifdef ANIMATE
|
||||
time =0;
|
||||
time = u_time / 1000. ;
|
||||
#endif
|
||||
gl_FragColor.a *= u_opacity * ceil(mod(v_distance_ratio + u_dash_offset + time / 10., v_dash_array) - (v_dash_array * u_dash_ratio));
|
||||
gl_FragColor.a *= u_opacity * ceil(mod(v_distance_ratio + u_dash_offset + time, 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;
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
#define SDF_PX 8.0
|
||||
#define EDGE_GAMMA 0.105 / float(DEVICE_PIXEL_RATIO)
|
||||
|
||||
uniform sampler2D u_sdf_map;
|
||||
uniform float u_gamma_scale : 0.5;
|
||||
uniform float u_font_size : 24;
|
||||
|
@ -26,6 +23,6 @@ void main() {
|
|||
|
||||
highp float alpha = smoothstep(buff - gamma_scaled, buff + gamma_scaled, dist);
|
||||
|
||||
gl_FragColor = mix(v_color * u_font_opacity, u_halo_color, smoothstep(0., .5, 1. - dist)) * alpha;
|
||||
gl_FragColor = mix(v_color * u_font_opacity, u_halo_color, smoothstep(0., 0.5, 1. - dist)) * alpha;
|
||||
#pragma include "pick"
|
||||
}
|
|
@ -16,7 +16,8 @@ const Global = {
|
|||
pitch: 0,
|
||||
hash: false,
|
||||
zoomControl: true,
|
||||
scaleControl: true
|
||||
scaleControl: true,
|
||||
attributionControl: true
|
||||
},
|
||||
animate: true,
|
||||
height: 0,
|
||||
|
|
|
@ -4,6 +4,7 @@ import DrawFill from './polygon/drawFill';
|
|||
import DrawLine from './polygon/drawLine';
|
||||
import DrawAnimate from './polygon/drawAnimate';
|
||||
import Draw3DShape from './point/draw_3d_shape';
|
||||
import DrawText from './text/drawText';
|
||||
|
||||
registerRender('polygon', 'fill', DrawFill);
|
||||
registerRender('polygon', 'extrude', DrawFill);
|
||||
|
@ -23,7 +24,6 @@ registerRender('line', 'greatCircle', DrawArcLine);
|
|||
import DrawPointImage from './point/drawImage';
|
||||
import DrawPointNormal from './point/drawNormal';
|
||||
import DrawPointStroke from './point/drawStroke';
|
||||
import DrawPointText from './point/drawText';
|
||||
import DrawPointCircle from './point/drawCircle';
|
||||
import DrawHexagon from './heatmap/hexagon';
|
||||
|
||||
|
@ -31,11 +31,12 @@ import DrawHexagon from './heatmap/hexagon';
|
|||
registerRender('point', 'image', DrawPointImage);
|
||||
registerRender('point', 'normal', DrawPointNormal);
|
||||
registerRender('point', 'stroke', DrawPointStroke);
|
||||
registerRender('point', 'text', DrawPointText);
|
||||
registerRender('point', 'text', DrawText);
|
||||
registerRender('point', 'fill', DrawPointCircle);
|
||||
registerRender('point', 'shape', Draw3DShape);
|
||||
registerRender('point', 'extrude', Draw3DShape);
|
||||
|
||||
|
||||
// heatmap
|
||||
|
||||
import DrawGrid from './heatmap/gird';
|
||||
|
@ -55,8 +56,6 @@ registerRender('image', 'image', DrawImage);
|
|||
|
||||
// image
|
||||
|
||||
import DrawText from './text/drawText';
|
||||
|
||||
registerRender('text', 'text', DrawText);
|
||||
|
||||
export { getRender };
|
||||
|
|
|
@ -54,3 +54,4 @@ export default function DrawText(layerData, layer) {
|
|||
const mesh = new THREE.Mesh(geometry, material);
|
||||
return mesh;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,14 +2,52 @@ import * as THREE from '../../../core/three';
|
|||
import TextMaterial from '../../../geom/material/textMaterial';
|
||||
import TextBuffer from '../../../geom/buffer/point/text';
|
||||
import ColorUtil from '../../../attr/color-util';
|
||||
|
||||
export default function DrawText(layerData, layer, updateGeometry = false) {
|
||||
import CollisionIndex from '../../../util/collision-index';
|
||||
export default function DrawText(layerData, layer) {
|
||||
const style = layer.get('styleOptions');
|
||||
const activeOption = layer.get('activedOptions');
|
||||
const { strokeWidth, strokeColor, opacity,
|
||||
fontFamily, fontWeight, spacing, textAnchor, textOffset, padding } = style;
|
||||
const { strokeWidth, strokeColor, opacity } = style;
|
||||
|
||||
const { width, height } = layer.scene.getSize();
|
||||
const { geometry, texture, fontAtlas } = _updateGeometry(layerData, layer);
|
||||
layer.scene.on('camerachange', () => {
|
||||
const { geometry } = _updateGeometry(layerData, layer);
|
||||
layer.layerMesh.geometry = geometry;
|
||||
layer.layerMesh.geometry.needsUpdate = true;
|
||||
});
|
||||
|
||||
|
||||
const material = new TextMaterial({
|
||||
name: layer.layerId,
|
||||
u_sdf_map: texture,
|
||||
u_halo_color: ColorUtil.toRGB(strokeColor).map(e => e / 255),
|
||||
u_halo_width: strokeWidth,
|
||||
u_halo_blur: 0.5,
|
||||
u_font_opacity: opacity,
|
||||
u_sdf_map_size: [ fontAtlas.width, fontAtlas.height ],
|
||||
u_viewport_size: [ width, height ],
|
||||
u_activeColor: activeOption.fill
|
||||
});
|
||||
const mesh = new THREE.Mesh(geometry, material);
|
||||
|
||||
// 更新 viewport
|
||||
window.addEventListener('resize', () => {
|
||||
const { width, height } = layer.scene.getSize();
|
||||
material.uniforms.u_viewport_size.value = [ width, height ];
|
||||
material.uniforms.needsUpdate = true;
|
||||
}, false);
|
||||
|
||||
// 关闭视锥裁剪
|
||||
mesh.frustumCulled = false;
|
||||
return mesh;
|
||||
}
|
||||
|
||||
function _updateGeometry(layerData, layer) {
|
||||
const style = layer.get('styleOptions');
|
||||
const {
|
||||
fontFamily, fontWeight, spacing, textAnchor, textOffset, padding } = style;
|
||||
const { width, height } = layer.scene.getSize();
|
||||
const collisionIndex = new CollisionIndex(width, height);
|
||||
const { _camera: { projectionMatrix, matrixWorldInverse } } = layer.scene._engine;
|
||||
|
||||
// 计算 MVP 矩阵
|
||||
|
@ -39,7 +77,7 @@ export default function DrawText(layerData, layer, updateGeometry = false) {
|
|||
padding
|
||||
},
|
||||
layer.scene.fontAtlasManager,
|
||||
layer.collisionIndex,
|
||||
collisionIndex,
|
||||
mvpMatrix
|
||||
);
|
||||
|
||||
|
@ -69,34 +107,5 @@ export default function DrawText(layerData, layer, updateGeometry = false) {
|
|||
'a_size',
|
||||
new THREE.Float32BufferAttribute(textSizes, 1)
|
||||
);
|
||||
|
||||
// 只需要更新顶点数据
|
||||
if (updateGeometry) {
|
||||
return geometry;
|
||||
}
|
||||
|
||||
const material = new TextMaterial({
|
||||
name: layer.layerId,
|
||||
u_sdf_map: texture,
|
||||
u_halo_color: ColorUtil.toRGB(strokeColor).map(e => e / 255),
|
||||
u_halo_width: strokeWidth,
|
||||
u_halo_blur: 0.5,
|
||||
u_font_opacity: opacity,
|
||||
u_sdf_map_size: [ fontAtlas.width, fontAtlas.height ],
|
||||
u_viewport_size: [ width, height ],
|
||||
u_activeColor: activeOption.fill
|
||||
});
|
||||
const mesh = new THREE.Mesh(geometry, material);
|
||||
|
||||
// 更新 viewport
|
||||
window.addEventListener('resize', () => {
|
||||
const { width, height } = layer.scene.getSize();
|
||||
material.uniforms.u_viewport_size.value = [ width, height ];
|
||||
material.uniforms.needsUpdate = true;
|
||||
}, false);
|
||||
|
||||
// 关闭视锥裁剪
|
||||
mesh.frustumCulled = false;
|
||||
return mesh;
|
||||
return { geometry, texture, fontAtlas };
|
||||
}
|
||||
|
||||
|
|
|
@ -1,23 +1,9 @@
|
|||
import Layer from '../core/layer';
|
||||
import { getRender } from './render';
|
||||
import CollisionIndex from '../util/collision-index';
|
||||
export default class TextLayer extends Layer {
|
||||
shape(field, values) {
|
||||
super.shape(field, values);
|
||||
this.shape = 'text';
|
||||
|
||||
// 创建碰撞检测索引
|
||||
const { width, height } = this.scene.getSize();
|
||||
this.collisionIndex = new CollisionIndex(width, height);
|
||||
|
||||
// 相机变化,需要重新构建索引,由于文本可见性的改变,也需要重新组装顶点数据
|
||||
this.scene.on('camerachange', () => {
|
||||
this.collisionIndex = new CollisionIndex(width, height);
|
||||
|
||||
this.layerMesh.geometry = getRender(this.type, this.shape)(this.layerData, this, true);
|
||||
this.layerMesh.geometry.needsUpdate = true;
|
||||
});
|
||||
|
||||
return this;
|
||||
}
|
||||
draw() {
|
||||
|
|
Loading…
Reference in New Issue