From 888ead7eb48d2f4bd82c9d71bf1552769b4309fb Mon Sep 17 00:00:00 2001 From: YiQianYao <42212176+2912401452@users.noreply.github.com> Date: Thu, 10 Mar 2022 14:11:19 +0800 Subject: [PATCH] Shihui (#998) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 完善 fillimage 的销毁 * feat: 完善 lineLayer 顶点构建时候对边界条件的兼容、增加台风案例 * feat: 增加台风案例 * docs: 完善官网 fillimage 的 demo --- examples/point/image/demo/fillimage.js | 277 ++++++++++++++++--- examples/point/image/demo/meta.json | 4 +- packages/layers/src/core/triangulation.ts | 4 +- packages/layers/src/point/models/fillmage.ts | 4 +- stories/Object/components/taifeng.tsx | 275 ++++++++++++++++++ stories/Object/map.stories.tsx | 4 +- 6 files changed, 516 insertions(+), 52 deletions(-) create mode 100644 stories/Object/components/taifeng.tsx diff --git a/examples/point/image/demo/fillimage.js b/examples/point/image/demo/fillimage.js index 6797422a7f..9ddd9dae02 100644 --- a/examples/point/image/demo/fillimage.js +++ b/examples/point/image/demo/fillimage.js @@ -1,58 +1,243 @@ -import { Scene, PointLayer } from '@antv/l7'; +import { Scene, PointLayer, LineLayer } from '@antv/l7'; import { GaodeMap } from '@antv/l7-maps'; +import { animate, linear } from 'popmotion'; + +const path = [ + { + lng: 168.3984375, + lat: -4.565473550710278, + img: 'img' + }, + { + lng: 165.05859375, + lat: -5.7908968128719565, + img: 'img' + }, + { + lng: 160.3125, + lat: -5.7908968128719565, + img: 'img' + }, + { + lng: 157.32421875, + lat: -3.688855143147035, + img: 'img' + }, + { + lng: 153.80859375, + lat: -2.284550660236957, + img: 'img' + }, + { + lng: 148.88671874999997, + lat: -2.108898659243126, + img: 'img' + }, + { + lng: 145.1953125, + lat: -0.7031073524364783, + img: 'img' + }, + { + lng: 140.44921875, + lat: 0, + img: 'img' + }, + { + lng: 135, + lat: 1.4061088354351594, + img: 'img' + }, + { + lng: 131.8359375, + lat: 2.986927393334876, + img: 'img' + }, + { + lng: 130.078125, + lat: 5.965753671065536, + img: 'img' + }, + { + lng: 128.49609375, + lat: 9.102096738726456, + img: 'img' + }, + { + lng: 127.265625, + lat: 12.211180191503997, + img: 'img' + }, + { + lng: 125.859375, + lat: 15.453680224345835, + img: 'img' + }, + { + lng: 123.92578125, + lat: 18.312810846425442, + img: 'img' + }, + { + lng: 121.11328124999999, + lat: 19.80805412808859, + img: 'img' + }, + { + lng: 117.94921874999999, + lat: 20.96143961409684, + img: 'img' + }, + { + lng: 115.31249999999999, + lat: 22.917922936146045, + img: 'img' + } +]; + +let imageLayer; +let imageData = { + lng: 168.3984375, + lat: -4.565473550710278, + img: 'img' +}; +let lineLayer; +let lineData = []; +let timer2; +let pathCount = 0; +let rotation = 0; const scene = new Scene({ id: 'map', map: new GaodeMap({ pitch: 0, - style: 'light', - center: [ 121.434765, 31.256735 ], - zoom: 14.83 + center: [ 120, 10 ], + zoom: 2 }) }); -scene.on('loaded', () => { - fetch( - 'https://gw.alipayobjects.com/os/basement_prod/893d1d5f-11d9-45f3-8322-ee9140d288ae.json' - ) - .then(res => res.json()) - .then(data => { - scene.addImage( - '00', - 'https://gw.alipayobjects.com/zos/basement_prod/604b5e7f-309e-40db-b95b-4fac746c5153.svg' - ); - scene.addImage( - '01', - 'https://gw.alipayobjects.com/zos/basement_prod/30580bc9-506f-4438-8c1a-744e082054ec.svg' - ); - scene.addImage( - '02', - 'https://gw.alipayobjects.com/zos/basement_prod/7aa1f460-9f9f-499f-afdf-13424aa26bbf.svg' - ); - const imageLayer = new PointLayer({ layerType: 'fillImage' }) - .source(data, { - parser: { - type: 'json', - x: 'longitude', - y: 'latitude' - } - }) - .shape('name', [ '00', '01', '02' ]) - .active({ - color: '#0ff', - mix: 0.5 - }) - .size(45); - scene.addLayer(imageLayer); - let r = 0; - rotate(); - function rotate() { - r += 0.2; - imageLayer.style({ - rotation: r - }); - scene.render(); - requestAnimationFrame(rotate); +scene.addImage( + 'img', + 'https://gw.alipayobjects.com/mdn/rms_816329/afts/img/A*rd3kTp1VFxIAAAAAAAAAAAAAARQnAQ' +); + +scene.on('loaded', () => { + imageLayer = new PointLayer({ layerType: 'fillImage', zIndex: 2 }) + .source([ imageData ], { + parser: { + type: 'json', + x: 'lng', + y: 'lat' } + }) + .shape('img', img => img) + .size(60) + .active({ + color: '#f00', + mix: 0.5 + }) + .style({ + opacity: 0.8, + rotation }); + + scene.addLayer(imageLayer); + + const data = [ + { + id: '1', + coord: lineData + } + ]; + lineLayer = new LineLayer() + .source(data, { + parser: { + type: 'json', + coordinates: 'coord' + } + }) + .shape('line') + .size(2) + .color('#f00') + .style({ + opacity: 0.8, + targetColor: '#0DCCFF', + sourceColor: 'rbga(255,255,255, 0)' + }); + + scene.addLayer(lineLayer); + + const rotate = () => { + rotation -= 2; + imageLayer.style({ + rotation + }); + scene.render(); + requestAnimationFrame(rotate); + }; + rotate(); + + updateLocation(); }); + +function updateLocation() { + clearTimeout(timer2); + + if (pathCount < path.length) { + timer2 = setTimeout(() => { + const data = path[pathCount]; + + const t = animate({ + from: { + lng: imageData.lng, + lat: imageData.lat + }, + to: { + lng: data.lng, + lat: data.lat + }, + ease: linear, + duration: 500, + onUpdate: o => { + if (pathCount > 1) { + imageData.lng = o.lng; + imageData.lat = o.lat; + imageLayer.setData([ imageData ]); + + lineData.push([ o.lng, o.lat ]); + lineLayer.setData([ + { + id: '1', + coord: lineData + } + ]); + } + }, + onComplete: () => { + t.stop(); + if (pathCount === path.length - 1) { + lineData = []; + lineLayer.setData([ + { + id: '1', + coord: lineData + } + ]); + } + } + }); + + pathCount++; + updateLocation(); + }, 500); + } else { + lineData = []; + imageData = { + lng: 168.3984375, + lat: -4.565473550710278, + img: 'img' + }; + pathCount = 0; + updateLocation(); + } +} diff --git a/examples/point/image/demo/meta.json b/examples/point/image/demo/meta.json index 0109a7343e..3262183d60 100644 --- a/examples/point/image/demo/meta.json +++ b/examples/point/image/demo/meta.json @@ -11,8 +11,8 @@ }, { "filename": "fillimage.js", - "title": "贴地符号图", - "screenshot": "https://gw.alipayobjects.com/mdn/rms_816329/afts/img/A*1kBZTaains4AAAAAAAAAAAAAARQnAQ" + "title": "台风路径模拟", + "screenshot": "https://gw.alipayobjects.com/mdn/rms_816329/afts/img/A*yJLsS44dI14AAAAAAAAAAAAAARQnAQ" }, { "filename": "locate.js", diff --git a/packages/layers/src/core/triangulation.ts b/packages/layers/src/core/triangulation.ts index 7d5916c2f3..d8c93b211d 100644 --- a/packages/layers/src/core/triangulation.ts +++ b/packages/layers/src/core/triangulation.ts @@ -126,7 +126,7 @@ export function LineTriangulation(feature: IEncodeFeature) { } else { // 处理非高德2.0的几何体构建 let path = coordinates as number[][][] | number[][]; - if (!Array.isArray(path[0][0])) { + if (path[0] && !Array.isArray(path[0][0])) { path = [coordinates] as number[][][]; } path.forEach((item: any) => { @@ -171,7 +171,7 @@ export function SimpleLineTriangulation(feature: IEncodeFeature) { } else { // 处理非高德2.0的几何体构建 let path = coordinates as number[][][] | number[][]; - if (!Array.isArray(path[0][0])) { + if (path[0] && !Array.isArray(path[0][0])) { path = [coordinates] as number[][][]; } path.forEach((item: any) => { diff --git a/packages/layers/src/point/models/fillmage.ts b/packages/layers/src/point/models/fillmage.ts index 7237de3b36..3609ee9004 100644 --- a/packages/layers/src/point/models/fillmage.ts +++ b/packages/layers/src/point/models/fillmage.ts @@ -211,7 +211,7 @@ export default class FillImageModel extends BaseModel { const { frag, vert, type } = this.getShaders(); return [ this.layer.buildLayerModel({ - moduleName: 'pointfill-' + type, + moduleName: 'pointfill_' + type, vertexShader: vert, fragmentShader: frag, triangulation: PointFillTriangulation, @@ -231,6 +231,8 @@ export default class FillImageModel extends BaseModel { } public clearModels() { + this.iconService.off('imageUpdate', this.updateTexture); + this.texture.destroy(); this.dataTexture?.destroy(); } diff --git a/stories/Object/components/taifeng.tsx b/stories/Object/components/taifeng.tsx new file mode 100644 index 0000000000..990f2ac2fa --- /dev/null +++ b/stories/Object/components/taifeng.tsx @@ -0,0 +1,275 @@ +// @ts-ignore +import { PointLayer, Scene, ILayer, LineLayer } from '@antv/l7'; +import { GaodeMap } from '@antv/l7-maps'; +import * as React from 'react'; +import { animate, easeInOut, linear } from 'popmotion'; + +const path = [ + { + lng: 168.3984375, + lat: -4.565473550710278, + img: 'img', + }, + { + lng: 165.05859375, + lat: -5.7908968128719565, + img: 'img', + }, + { + lng: 160.3125, + lat: -5.7908968128719565, + img: 'img', + }, + { + lng: 157.32421875, + lat: -3.688855143147035, + img: 'img', + }, + { + lng: 153.80859375, + lat: -2.284550660236957, + img: 'img', + }, + { + lng: 148.88671874999997, + lat: -2.108898659243126, + img: 'img', + }, + { + lng: 145.1953125, + lat: -0.7031073524364783, + img: 'img', + }, + { + lng: 140.44921875, + lat: 0, + img: 'img', + }, + { + lng: 135, + lat: 1.4061088354351594, + img: 'img', + }, + { + lng: 131.8359375, + lat: 2.986927393334876, + img: 'img', + }, + { + lng: 130.078125, + lat: 5.965753671065536, + img: 'img', + }, + { + lng: 128.49609375, + lat: 9.102096738726456, + img: 'img', + }, + { + lng: 127.265625, + lat: 12.211180191503997, + img: 'img', + }, + { + lng: 125.859375, + lat: 15.453680224345835, + img: 'img', + }, + { + lng: 123.92578125, + lat: 18.312810846425442, + img: 'img', + }, + { + lng: 121.11328124999999, + lat: 19.80805412808859, + img: 'img', + }, + { + lng: 117.94921874999999, + lat: 20.96143961409684, + img: 'img', + }, + { + lng: 115.31249999999999, + lat: 22.917922936146045, + img: 'img', + }, +]; +export default class Amap2demo_polygon extends React.Component { + private scene: Scene; + private imageLayer: ILayer; + private imageData: { + lng: number; + lat: number; + img: string; + }; + private lineLayer: ILayer; + private lineData: any[] = []; + private timer: any; + private timer2: any; + private pathCount: any = 0; + private rotation: any = 0; + + public componentWillUnmount() { + cancelAnimationFrame(this.timer); + clearTimeout(this.timer2); + this.scene.destroy(); + } + public async componentDidMount() { + const scene = new Scene({ + id: 'map', + map: new GaodeMap({ + pitch: 0, + center: [120, 10], + zoom: 2, + }), + }); + this.scene = scene; + + scene.addImage( + 'img', + 'https://gw.alipayobjects.com/mdn/rms_816329/afts/img/A*rd3kTp1VFxIAAAAAAAAAAAAAARQnAQ', + ); + this.imageData = { + lng: 168.3984375, + lat: -4.565473550710278, + img: 'img', + }; + scene.on('loaded', () => { + this.imageLayer = new PointLayer({ layerType: 'fillImage', zIndex: 2 }) + .source([this.imageData], { + parser: { + type: 'json', + x: 'lng', + y: 'lat', + }, + }) + .shape('img', (img) => img) + .size(60) + .active({ + color: '#f00', + mix: 0.5, + }) + .style({ + opacity: 0.8, + rotation: this.rotation, + }); + + scene.addLayer(this.imageLayer); + + const data = [ + { + id: '1', + coord: this.lineData, + }, + ]; + this.lineLayer = new LineLayer() + .source(data, { + parser: { + type: 'json', + coordinates: 'coord', + }, + }) + .shape('line') + .size(2) + .color('#f00') + .style({ + opacity: 0.8, + targetColor: '#0DCCFF', + sourceColor: 'rbga(255,255,255, 0)', + }); + + scene.addLayer(this.lineLayer); + + const rotate = () => { + this.rotation -= 2; + this.imageLayer.style({ + rotation: this.rotation, + }); + scene.render(); + this.timer = requestAnimationFrame(rotate); + }; + rotate(); + + this.updateLocation(); + }); + } + + updateLocation() { + clearTimeout(this.timer2); + + if (this.pathCount < path.length) { + this.timer2 = setTimeout(() => { + const data = path[this.pathCount]; + + let t = animate({ + from: { + lng: this.imageData.lng, + lat: this.imageData.lat, + }, + to: { + lng: data.lng, + lat: data.lat, + }, + ease: linear, + duration: 500, + onUpdate: (o) => { + if (this.pathCount > 1) { + this.imageData.lng = o.lng; + this.imageData.lat = o.lat; + this.imageLayer.setData([this.imageData]); + + this.lineData.push([o.lng, o.lat]); + this.lineLayer.setData([ + { + id: '1', + coord: this.lineData, + }, + ]); + } + }, + onComplete: () => { + t.stop(); + if (this.pathCount === path.length - 1) { + this.lineData = []; + this.lineLayer.setData([ + { + id: '1', + coord: this.lineData, + }, + ]); + } + }, + }); + + this.pathCount++; + this.updateLocation(); + }, 500); + } else { + this.lineData = []; + this.imageData = { + lng: 168.3984375, + lat: -4.565473550710278, + img: 'img', + }; + this.pathCount = 0; + this.updateLocation(); + } + } + + public render() { + return ( +
+ ); + } +} diff --git a/stories/Object/map.stories.tsx b/stories/Object/map.stories.tsx index 174512b932..10d84c86f9 100644 --- a/stories/Object/map.stories.tsx +++ b/stories/Object/map.stories.tsx @@ -1,6 +1,8 @@ import { storiesOf } from '@storybook/react'; import * as React from 'react'; import Water from './components/water'; +import Taifong from './components/taifeng' storiesOf('Object', module) - .add('water', () => ) \ No newline at end of file + .add('water', () => ) + .add('Taifong', () => ) \ No newline at end of file