Changemarker (#1039)

* fix: 修复 Marker GaodeMapV2 在移动端的事件失效

* fix: 修复 iconfont 偏移

* fix: 修复销毁场景时候 webgl 实例未被销毁的问题

* style: lint style
This commit is contained in:
YiQianYao 2022-04-02 16:23:54 +08:00 committed by GitHub
parent 61c082679a
commit 65b70c19dd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 95 additions and 301 deletions

View File

@ -7,4 +7,5 @@ export interface IPickingService {
box: [number, number, number, number],
cb: (...args: any[]) => void,
): Promise<any>;
destroy(): void;
}

View File

@ -174,6 +174,13 @@ export default class PickingService implements IPickingService {
// domContainer?.style.setProperty('cursor', 'move');
}
public destroy() {
this.pickingFBO.destroy();
// this.pickingFBO = null; 清除对 webgl 实例的引用
// @ts-ignore
this.pickingFBO = null;
}
// 获取容器的大小 - 兼容小程序环境
private getContainerSize(container: HTMLCanvasElement | HTMLElement) {
if (!!(container as HTMLCanvasElement).getContext) {

View File

@ -411,9 +411,14 @@ export default class Scene extends EventEmitter implements ISceneService {
}
this.emit('destroy');
this.pickingService.destroy();
this.layerService.destroy();
// this.rendererService.destroy();
setTimeout(() => {
this.$container?.removeChild(this.canvas);
// this.canvas = null 清除对 webgl 实例的引用
// @ts-ignore
this.canvas = null;
// Tip: 把这一部分销毁放到写下一个事件循环中执行,兼容 L7React 中 scene 和 layer 同时销毁的情况
this.rendererService.destroy();
});

View File

@ -226,7 +226,13 @@ function shapeIconFont(
if (glyph) {
positionedGlyphs.push({
glyph: iconfont,
x,
// x,
/**
* iconfont
* unicode &#xe6d4;
* icon icon
*/
x: glyph.advance / 2,
y: y + baselineOffset,
vertical: false, // TODO目前只支持水平方向
scale: 1,

View File

@ -282,6 +282,9 @@ export class Map extends Camera {
}
public remove() {
this.container.removeChild(this.canvasContainer);
// @ts-ignore
this.canvasContainer = null;
if (this.frame) {
this.frame.cancel();
this.frame = null;

View File

@ -157,7 +157,8 @@ export default class AMapService
'amap-maps',
)[0] as HTMLElement;
// TODO: amap2 的 amap-maps 新增 z-index=0; 样式,让 marker 中 zIndex 失效
amap.style.zIndex = 'auto';
// * 设置 amap.style.zIndex = 'auto'; 会导致 GaodeMapV2 在移动端的事件失效
// amap.style.zIndex = 'auto';
this.markerContainer = DOM.create('div', 'l7-marker-container2', amap);
// this.markerContainer = DOM.create(
// 'div',

View File

@ -367,9 +367,6 @@ export default class L7MapService implements IMapService<Map> {
}
public destroy() {
// TODO: 销毁地图可视化层的容器
this.$mapContainer?.parentNode?.removeChild(this.$mapContainer);
this.eventEmitter.removeAllListeners();
if (this.map) {
this.map.remove();

View File

@ -263,7 +263,13 @@ export default class ReglRendererService implements IRendererService {
}
public destroy = () => {
// this.canvas = null 清除对 webgl 实例的引用
// @ts-ignore
this.canvas = null;
// @see https://github.com/regl-project/regl/blob/gh-pages/API.md#clean-up
this.gl.destroy();
// @ts-ignore
this.gl = null;
};
}

View File

@ -10,273 +10,60 @@ export default class Amap2demo_iconfont extends React.Component {
}
public async componentDidMount() {
let fontFamily = 'iconfont';
let fontPath =
'//at.alicdn.com/t/font_2534097_ao9soua2obv.woff2?t=1622021146076';
const scene = new Scene({
id: 'map',
map: new GaodeMap({
center: [121, 30.5],
pitch: 0,
style: 'amap://styles/453e2f8e11603fc8f7548fe18959e9e9',
zoom: 9,
zooms: [8, 10],
// viewMode: '2D',
pitch: 20,
style: 'light',
center: [120, 20],
zoom: 3,
}),
});
this.scene = scene;
scene.addIconFonts([
['smallRain', '&#xe6f7;'],
['middleRain', '&#xe61c;'],
['hugeRain', '&#xe6a6;'],
['sun', '&#xe6da;'],
['cloud', '&#xe8da;'],
]);
const fontFamily = 'iconfont';
// 指定 iconfont 字体文件
const fontPath =
'//at.alicdn.com/t/font_2534097_fcae9o2mxbv.woff2?t=1622200439140';
// 全局添加资源
scene.addFontFace(fontFamily, fontPath);
// 全局添加 iconfont 字段的映射;
scene.addIconFont('icon1', '&#xe6d4;');
scene.on('loaded', () => {
let originData = [
{
lng: 120,
lat: 30,
iconType: 'sun',
iconColor: '#FFA500',
backgoundColor: '#00BFFF',
temperature: '28℃',
weather: '晴朗',
opacity: 0.5,
strokeWidth2: 1,
stroke: '#f00',
testTextOffset: [5, -55],
},
{
lng: 120.2,
lat: 30.5,
iconType: 'sun',
iconColor: '#FFA500',
backgoundColor: '#00BFFF',
temperature: '28℃',
weather: '晴朗',
opacity: 0.5,
strokeWidth2: 1,
stroke: '#f00',
testTextOffset: [5, -55],
},
{
lng: 121.5,
lat: 31.4,
iconType: 'cloud',
iconColor: '#F0F8FF',
backgoundColor: '#1E90FF',
temperature: '22℃',
weather: '多云',
opacity: 0.5,
strokeWidth2: 1,
stroke: '#f00',
testTextOffset: [5, -55],
},
{
lng: 120,
lat: 31,
iconType: 'cloud',
iconColor: '#F0F8FF',
backgoundColor: '#1E90FF',
temperature: '22℃',
weather: '多云',
opacity: 0.5,
strokeWidth2: 1,
stroke: '#f00',
testTextOffset: [5, -55],
},
{
lng: 120.6,
lat: 30.8,
iconType: 'cloud',
iconColor: '#F0F8FF',
backgoundColor: '#1E90FF',
temperature: '22℃',
weather: '多云',
opacity: 0.5,
strokeWidth2: 1,
stroke: '#f00',
testTextOffset: [5, -55],
},
{
lng: 120.5,
lat: 31.3,
iconType: 'cloud',
iconColor: '#F0F8FF',
backgoundColor: '#1E90FF',
temperature: '22℃',
weather: '多云',
opacity: 1,
strokeWidth2: 3,
stroke: '#ff0',
testTextOffset: [5, -55],
},
{
lng: 121.3,
lat: 30.2,
iconType: 'smallRain',
iconColor: '#6EA0FF',
backgoundColor: '#4678AA',
temperature: '22℃',
weather: '小雨',
opacity: 1,
strokeWidth2: 3,
stroke: '#ff0',
testTextOffset: [5, -55],
},
{
lng: 121,
lat: 30.5,
iconType: 'smallRain',
iconColor: '#6EA0FF',
backgoundColor: '#4678AA',
temperature: '22℃',
weather: '小雨',
opacity: 1,
strokeWidth2: 3,
stroke: '#ff0',
testTextOffset: [5, -55],
},
{
lng: 120.6,
lat: 30,
iconType: 'middleRain',
iconColor: '#6495ED',
backgoundColor: '#326EA0',
temperature: '24℃',
weather: '中雨',
opacity: 1,
strokeWidth2: 3,
stroke: '#ff0',
testTextOffset: [5, -55],
},
{
lng: 120.2,
lat: 29.7,
iconType: 'smallRain',
iconColor: '#6EA0FF',
backgoundColor: '#4678AA',
temperature: '22℃',
weather: '小雨',
opacity: 1,
strokeWidth2: 3,
stroke: '#ff0',
testTextOffset: [5, -55],
},
{
lng: 121.7,
lat: 29.8,
iconType: 'middleRain',
iconColor: '#6495ED',
backgoundColor: '#326EA0',
temperature: '24℃',
weather: '中雨',
opacity: 1,
strokeWidth2: 3,
stroke: '#ff0',
testTextOffset: [5, -55],
},
{
lng: 121.5,
lat: 30,
iconType: 'hugeRain',
iconColor: '#4678D2',
backgoundColor: '#285A8C',
temperature: '20℃',
weather: '大雨-',
opacity: 1,
strokeWidth2: 3,
stroke: '#ff0',
testTextOffset: [10, -55],
},
];
const layer = new PointLayer()
.source(originData, {
parser: {
type: 'json',
x: 'lng',
y: 'lat',
const imageLayer = new PointLayer()
.source(
[
{
j: 118.234433,
w: 35.007936,
icon: 'icon1',
value: 10,
name: 'AA',
type: 'dibiaoshui',
},
],
{
parser: {
type: 'json',
x: 'j',
y: 'w',
},
},
})
.shape('circle')
.color('backgoundColor')
.size(40);
scene.addLayer(layer);
const pointIconFontLayer = new PointLayer({})
.source(originData, {
parser: {
type: 'json',
x: 'lng',
y: 'lat',
},
})
.shape('iconType', 'text')
)
.color('#44ff00')
.shape('icon', 'text')
// .shape('circle')
// .size(30)
.size(30)
.color('iconColor')
.style({
textAnchor: 'center', // 文本相对锚点的位置 center|left|right|top|bottom|top-left
textOffset: [38, 10], // 文本相对锚点的偏移量 [水平, 垂直]
// textAnchor: 'center', // 文本相对锚点的位置 center|left|right|top|bottom|top-left
// textOffset: [ 40, 0 ], // 文本相对锚点的偏移量 [水平, 垂直]
padding: [0, 0], // 文本包围盒 padding [水平,垂直],影响碰撞检测结果,避免相邻文本靠的太近
stroke: '#ffffff', // 描边颜色
fontFamily,
iconfont: true,
textAllowOverlap: true,
});
scene.addLayer(pointIconFontLayer);
const textLayer = new PointLayer({})
.source(originData, {
parser: {
type: 'json',
x: 'lng',
y: 'lat',
},
})
.shape('temperature', 'text')
.size(10)
.color('#ffffff')
.style({
textAnchor: 'center', // 文本相对锚点的位置 center|left|right|top|bottom|top-left
// textOffset: [5, -55], // 文本相对锚点的偏移量 [水平, 垂直]
textOffset: 'testTextOffset', // 文本相对锚点的偏移量 [水平, 垂直]
spacing: 2, // 字符间距
padding: [1, 1], // 文本包围盒 padding [水平,垂直],影响碰撞检测结果,避免相邻文本靠的太近
fontFamily: 'Times New Roman',
textAllowOverlap: true,
stroke: 'iconColor', // 描边颜色
strokeWidth: 'strokeWidth2', // 描边宽度
opacity: 'opacity',
});
scene.addLayer(textLayer);
const textLayer2 = new PointLayer({})
.source(originData, {
parser: {
type: 'json',
x: 'lng',
y: 'lat',
},
})
.shape('weather', 'text')
.size(14)
.color('#ffffff')
.style({
textAnchor: 'center', // 文本相对锚点的位置 center|left|right|top|bottom|top-left
textOffset: [5, -15], // 文本相对锚点的偏移量 [水平, 垂直]
spacing: 2, // 字符间距
padding: [1, 1], // 文本包围盒 padding [水平,垂直],影响碰撞检测结果,避免相邻文本靠的太近
stroke: '#ffffff', // 描边颜色
strokeWidth: 0.3, // 描边宽度
strokeOpacity: 1.0,
fontFamily: 'Times New Roman',
textAllowOverlap: true,
});
scene.addLayer(textLayer2);
scene.addLayer(imageLayer);
});
}

View File

@ -11,51 +11,32 @@ export default class Amap2demo extends React.Component {
}
public async componentDidMount() {
const scene = new Scene({
id: 'map',
map: new GaodeMap({
// center: [121.434765, 31.256735],
// zoom: 14.83,
pitch: 0,
style: 'light',
center: [122.5, 30],
zoom: 4,
}),
});
this.scene = scene;
const layer = new PointLayer()
.source(
[
{ lng: 120, lat: 30, c: '#ff0' },
{ lng: 125, lat: 30, c: '#0f0' },
],
{
parser: {
type: 'json',
x: 'lng',
y: 'lat',
},
},
)
.shape('circle')
.size(20)
.color('c');
scene.on('loaded', () => {
scene.addLayer(layer);
// layer.on('dataUpdate', (e) => {
// const le = layer.getLegendItems('color')
// console.log(le)
// })
layer.on('dataUpdate', (e) => {
const le = layer.getLegendItems('color');
console.log('scale', le);
function initScene() {
return new Promise((resolve, reject) => {
const scene = new Scene({
id: 'map',
map: new GaodeMapV2({
// center: [121.434765, 31.256735],
// zoom: 14.83,
pitch: 0,
style: 'light',
center: [122.5, 30],
zoom: 4,
}),
});
scene.on('loaded', () => {
setTimeout(() => {
resolve(scene);
}, 200);
});
});
layer.setData([{ lng: 121, lat: 30, c: '#000' }]);
// layer.color('#f00')
scene.render();
});
}
for (let i = 0; i < 20; i++) {
console.log('init ' + (i + 1));
let scene = await initScene();
scene.destroy();
}
}
public render() {