本文适合对vue,arcgis4.x,threejs,ES6较熟悉的人群食用。

效果图:

数据可视化【原创】vue+arcgis+threejs 实现立体光圈闪烁效果-LMLPHP

 素材:

数据可视化【原创】vue+arcgis+threejs 实现立体光圈闪烁效果-LMLPHP

主要思路:

先用arcgis externalRenderers封装了一个ExternalRendererLayer,在里面把arcgis和threejs的context关联,然后再写个子类继承它,这部分类容在上一个帖子里面有讲过。

子类FlashLayer继承它,并在里面封装了一个excute方法用来执行闪烁,参数包括point和height。先构建一个管道CatmullRomCurve3,在构建环RingGeometry,然后在updateModels里面去更新管道的scale.z,更新环的半径和透明度。

excute方法:

 1 excute(point, height) {
 2         // let pointList = [
 3         //     [114.31456780904838, 30.55355011036358, 0],
 4         //     [114.31456780904838, 30.55355011036358, 2000]
 5         // ];
 6         let pointList = [
 7             [
 8                 point.longitude,
 9                 point.latitude,
10                 0
11             ],
12             [
13                 point.longitude,
14                 point.latitude,
15                 height
16             ]
17         ]
18 
19         let linePoints = [];
20         //确定几何体位置
21         pointList.forEach((item) => {
22             var renderLinePoints = this.lngLatToXY(this.view, [item[0], item[1], item[2]]);
23             linePoints.push(new THREE.Vector3(renderLinePoints.vector3List.x, renderLinePoints
24                 .vector3List.y, renderLinePoints.vector3List.z));
25         })
26 
27         const lineImg = require('../../../../public/static/img/line.png')
28         let lineTexture = new THREE.TextureLoader().load(lineImg)
29         lineTexture.wrapS = lineTexture.wrapT = THREE.RepeatWrapping; //每个都重复
30         lineTexture.repeat.set(1, 1)
31         lineTexture.needsUpdate = true
32 
33         let lineMaterial = new THREE.MeshBasicMaterial({
34             map: lineTexture,
35             side: THREE.DoubleSide,
36             transparent: true,
37             opacity: 1
38         })
39 
40         // CatmullRomCurve3创建一条平滑的三维样条曲线
41         let curve = new THREE.CatmullRomCurve3(linePoints) // 曲线路径
42 
43         // 创建管道
44         let tubeGeometry = new THREE.TubeGeometry(curve, 1, 16)
45 
46         let mesh = new THREE.Mesh(tubeGeometry, lineMaterial);
47         mesh.name = 'FlashLayer_Line';
48         mesh.scale.z = 0;
49         mesh.layers.set(0);
50         this.group.add(mesh);
51 
52         //光圈
53         const ringUserData = {
54             width: 300,
55             innerRadius: 0,
56             opacity: 1,
57             opacityFlag: false,
58             per: 10,
59             innerMax: 800,
60             times: 0,
61             line: mesh
62         };
63         const ringGeometry = new THREE.RingGeometry(ringUserData.innerRadius, ringUserData.innerRadius +
64             ringUserData.width, 32);
65         const ringMaterial = new THREE.MeshPhongMaterial({
66             color: COLOR_RING,
67             emissive: COLOR_RING,
68             side: THREE.DoubleSide,
69             flatShading: true,
70             wireframe: false,
71             transparent: true,
72             opacity: ringUserData.opacity
73         });
74         const ringMesh = new THREE.Mesh(ringGeometry, ringMaterial);
75         const ringPoint = linePoints[1];
76         console.log(ringPoint);
77         ringMesh.position.set(ringPoint.x, ringPoint.y, ringPoint.z / 2 + (Math.random() * ringPoint.z / 4 | 0) );
78         ringMesh.name = 'FlashLayer_Ring';
79         ringMesh.userData = ringUserData;
80         ringMesh.layers.set(0);
81 
82         this.group.add(ringMesh);
83     }
09-05 23:48