时间不早了。不说废话了。先上效果
原理:
Mapbox的customLayer+ three.js的QuadraticBezierCurve3。把线进行分段,每次只显示一部分,动态更改显示的部分就可以做出移动的效果。不会的同学请看代码。欢迎私信骚扰。
let positions = [] ;
//传入参数
let height =1000
let anypoint = [[114.58,28.61],[114.58,28.58]]
var point1 = turf.point([114.58,28.61]);
var point2 = turf.point([114.58,28.58]);
var midpoint = turf.midpoint(point1, point2).geometry.coordinates;
anypoint.splice(1,0,midpoint)
for(let i = 0 ; i < anypoint.length ; i++){
if(i == 1){
positions.push(mapboxgl.MercatorCoordinate.fromLngLat(anypoint[i], height))
}else{
positions.push(mapboxgl.MercatorCoordinate.fromLngLat(anypoint[i], 0))
}
}
let p1 = new THREE.Vector3(positions[0].x,positions[0].y,positions[0].z)
let p2 = new THREE.Vector3(positions[1].x,positions[1].y,positions[1].z)
let p3 = new THREE.Vector3(positions[2].x,positions[2].y,positions[2].z)
var curve = new THREE.QuadraticBezierCurve3(p1, p2, p3);
const linepoints = curve.getPoints(60)
const highLightGeometry = new THREE.Geometry();
let i = 0 ;
let j = 20 ;
highLightGeometry.vertices = linepoints.slice(i,j); // 将分割后的前三个点赋值给顶点数据,后面只需改变这个顶点数组
highLightGeometry.verticesNeedUpdate = true; // 如果顶点队列中的数据被修改,该值需要被设置为 true
highLightGeometry.colors = [
new THREE.Color('#ffff00'),
new THREE.Color('#ffffff'),
new THREE.Color('#ffff00'),
];
// let geometry = new THREE.BufferGeometry()
// geometry.addAttribute('position',new THREE.BufferAttribute(new Float32Array(positions), 3))
let WallLayer = {
id:'FlyLine01',
type:'custom',
renderingMode:'2d',
onAdd:(map:any,gl:any)=>{
let camera = new THREE.Camera();
let scene = new THREE.Scene();
let renderer = new THREE.WebGLRenderer({
canvas: map.getCanvas(),
context: gl,
antialias: true
})
let light = new THREE.PointLight(0xfca4c5)
light.position.set(0, 250, 0)
scene.add(light)
// 创建材质
// geometry.option
const material = new THREE.LineBasicMaterial({
vertexColors: true,
linewidth: 20
});
var color1 = new THREE.Color( 0xFFFFFF ),color2 = new THREE.Color( 0x444444 ),color3 = new THREE.Color( 0xFF0000 ),color4 = new THREE.Color( 0x0000FF );
highLightGeometry.colors.push(color2,color1,color3,color3,color4,color2,color1,color3,color2,color4,color3,color2,color1,color1,color2,color3,color4,color4,color3,color1)
let mesh = new THREE.Line(highLightGeometry, material)
scene.add(mesh)
renderer.autoClear = false
this.camera = camera ;
this.scene = scene
this.renderer = renderer ;
this.matrtial = material;
this.mesh = mesh ;
this.map = map
},
render:(gl:any,matrix:any)=>{
var m = new THREE.Matrix4().fromArray(matrix);
this.camera.projectionMatrix = m
this.renderer.state.reset()
this.renderer.render(this.scene, this.camera)
this.map.triggerRepaint();
}
}
viewer.addLayer(WallLayer);
let temp = setInterval(()=>{
if(j >= linepoints.length){
i = 0 ;
j = 20 ;
this.mesh.geometry.vertices = linepoints.slice(i,j)
this.mesh.geometry.verticesNeedUpdate = true
}else{
i+=1;
j+=1;
this.mesh.geometry.vertices = linepoints.slice(i,j)
this.mesh.geometry.verticesNeedUpdate = true//需动态设置为true不然每次会被重置为false
}//动态修改顶点
},50)
小记:最近身体有点难受,就不详细写了,有时间我会慢慢把我实现的特效分享出来。有什么疑惑的地方大可以直接贴出
最后感谢几位博主的文章