看到一个博客,给了我启发,万分感谢,参考的博客地址是:
https://www.cnblogs.com/HandyLi/p/11244889.html
html部分:
1 <div id="cesiumContainer"></div>
2 <canvas id="canvas-a" width="400px" height="400px"></canvas>
3 <canvas id="canvas-b" width="400px" height="400px"></canvas>
4 <canvas id="canvas-c" width="400px" height="400px"></canvas>
三个canvas也可以通过js代码创建。
js部分:
1 Cesium.Ion.defaultAccessToken = ‘your token';
2 var viewer = new Cesium.Viewer('cesiumContainer');
3 viewer._cesiumWidget._creditContainer.style.display = "none";
4 viewer.scene.debugShowFramesPerSecond = true;
5
6 //通过3个画布交替切换实现探测纹理动态
7 var changenum = 0;
8 var curCanvas = 'a';
9
10 function readyCanvas(convasid, radius) {
11 var canvas = document.getElementById(convasid);
12 let cwidth = 400;
13 let cheight = 400;
14 var ctx = canvas.getContext("2d");
15 ctx.clearRect(0, 0, cwidth, cheight);
16 ctx.fillStyle = 'rgba(255, 255, 255, 0)';
17 ctx.fillRect(0, 0, cwidth, cheight);
18
19 for (let ii = 0; radius <= 200; ii++) {
20 ctx.lineWidth = 5;
21 //开始一个新的绘制路径
22 ctx.beginPath();
23 //设置弧线的颜色
24 var trans = 1.0 - (radius / 255);
25 ctx.strokeStyle = "rgba(255, 0, 255, " + trans + ")";
26 var circle = {
27 x: 200, //圆心的x轴坐标值
28 y: 200, //圆心的y轴坐标值
29 r: radius //圆的半径
30 };
31 //以canvas中的坐标点(200,200)为圆心,绘制一个半径为50px的圆形
32 ctx.arc(circle.x, circle.y, circle.r, 0, Math.PI * 2, true);
33 //按照指定的路径绘制弧线
34 ctx.stroke();
35 radius += 20;
36 }
37 }
38 readyCanvas("canvas-a", 5);
39 readyCanvas("canvas-b", 10);
40 readyCanvas("canvas-c", 15);
41
42 function drawCanvasImage(time, result) {
43 changenum++;
44 var canvas = document.getElementById("canvas-" + curCanvas);
45 if (changenum >= 20) {
46 changenum = 0;
47 if (curCanvas === 'a')
48 curCanvas = 'b';
49 else if (curCanvas === 'b')
50 curCanvas = 'c';
51 else
52 curCanvas = 'a';
53 }
54 return canvas;
55 }
56 //初始位置
57 var lon = -118.760842;
58 var lat = 38.132073;
59 var planePosition = Cesium.Cartesian3.fromDegrees(lon, lat, 3000.0)
60 //改变圆锥体位置,循环画矩形
61 function changePosition() {
62 if (lon > -118.755842 && lat < 38.138073) {
63 lat += 0.00001;
64 } else if (lat > 38.138073 && lon > -118.760842) {
65 lon -= 0.00001;
66 } else if (lon <= -118.760842 && lat > 38.132074) {
67 lat -= 0.00001
68 } else {
69 lon += 0.00001;
70 }
71
72 planePosition = Cesium.Cartesian3.fromDegrees(lon, lat, 3000.0)
73 return planePosition
74 }
75 //根据圆锥中心点位置动态计算朝向、圆锥体长度
76 var geoD = new Cesium.EllipsoidGeodesic();
77 //顶点经纬度
78 var startPt = Cesium.Cartographic.fromDegrees(-118.760842, 38.132073, 0);
79
80 function changeOrientation() {
81 //计算经度方向的夹角
82 var endX = Cesium.Cartographic.fromDegrees(lon, 38.132073, 0);
83 geoD.setEndPoints(startPt, endX);
84 var innerS = geoD.surfaceDistance;
85 var angleX = Math.atan(innerS / halfLen);
86
87 //计算圆锥体长度
88 var end = Cesium.Cartographic.fromDegrees(lon, lat, 0);
89 geoD.setEndPoints(startPt, end);
90 innerS = geoD.surfaceDistance;
91 length = Math.sqrt(innerS * innerS + halfLen * halfLen);
92
93 //计算纬度方向的夹角
94 var endY = Cesium.Cartographic.fromDegrees(-118.760842, lat, 0);
95 geoD.setEndPoints(startPt, endY);
96 innerS = geoD.surfaceDistance;
97 var angleY = Math.asin(innerS / length);
98
99 //计算朝向
100 var hpr = new Cesium.HeadingPitchRoll(0.0, angleX, angleY);
101 var orientation = Cesium.Transforms.headingPitchRollQuaternion(planePosition, hpr);
102
103 return orientation
104 }
105 var halfLen = 1000.0
106 var length = 1000.0;
107
108 function changeLength() {
109 return 2 * length;
110 }
111 //创建圆锥实体
112 var cylinder = viewer.entities.add({
113 name: 'Red cone',
114 position: new Cesium.CallbackProperty(changePosition, false),
115 orientation: new Cesium.CallbackProperty(changeOrientation, false),
116 cylinder: {
117 length: new Cesium.CallbackProperty(changeLength, false),
118 topRadius: 0.0,
119 bottomRadius: 300.0,
120 //topSurface: false, //新增参数,控制顶部是否渲染
121 bottomSurface: false, //新增参数,控制底部是否渲染
122 material: new Cesium.ImageMaterialProperty({
123 image: new Cesium.CallbackProperty(drawCanvasImage, false),
124 transparent: true
125 })
126 }
127 });
128
129 //定位到圆锥体
130 var initialPosition = Cesium.Cartesian3.fromDegrees(-118.760842, 38.089073, 8000); //相机视角三要素:朝向(左右偏移),倾斜(上下偏移),翻滚角度(相机视锥体中轴线旋转角度)
131 var initialOrientation = new Cesium.HeadingPitchRoll.fromDegrees(1.27879878293835, -51.34390550872461, 0.0716951918898415);
132 viewer.scene.camera.setView({
133 destination: initialPosition,
134 orientation: initialOrientation,
135 endTransform: Cesium.Matrix4.IDENTITY
136 });
启发是:
在cesium的material中,image:可以用回调方式去传递
material: new Cesium.ImageMaterialProperty({
image: new Cesium.CallbackProperty(drawCanvasImage, false),
transparent: true
})
然后就是渲染到纹理了,传递其他canvas过去,可以当作纹理,这样就是渲染到纹理了。主要应该是回调函数Cesium.CallbackProperty起作用了,可以当作动画使用。
官方教程上也写着
ImageMaterialProperty--图片
图片纹理功能比较丰富,主要有下面属性:
- image 值可以是URL,Canvas,或者Video