作者: kele
最近了解了一些关于canvas的知识,我们都知道canvas能做出很复杂且炫酷的动画效果,那么如果将canvas动画应用到gis应用,将会擦除什么样的火花呢?我们一起来看下吧
一、实现思路
本篇文章将介绍图中数字流特效的实现思路,彩球动画效果可参考另一篇文章(链接: 跳转地址) 总所周知,我们可以在canvas上绘制各种东西,但是要让canvas展示在三维场景中,必须要依赖一个载体,我们可以在场景中用面对象作为载体,将动画效果当作纹理展示:
1.通过entity绘制一个面对象 2.将canvas以图片的形式作为材质赋予面对象 3.循环改变标签的像素值位置,并使用CallbackProperty函数监听变化实时渲染
二、关键代码
1.绘制面实体
先不给材质,因为后续会将canvas动画作为材质
var textGreen = viewer.entities.add({
polygon: {
hierarchy: Cesium.Cartesian3.fromDegreesArrayHeights([
116.383434881692,39.992315273588524, 40,
116.3833273079725,39.99232011844418, 40,
116.3833273079725,39.99232011844418, 1000,
116.383434881692,39.992315273588524, 1000,
]),
perPositionHeight: true,
},
});
2.编写canvas内容,并指定规则
将每个文本旋转,其位置按照像素值递减,实现文字自下而上的流动,每次变化都会返回新的canvas对象
function writeGreenTextOnCanvas() {
var cns = document.createElement('canvas');
var ctx = cns.getContext("2d");
cns.width = 30;
cns.height = 1600;
if (perY > -700) {
y = perY;
for (let i = 0; i < text.length; i++) {
const str = text.slice(i, i + 1).toString();
if (str.match(/[A-Za-z0-9]/) && (y > 0)) {
ctx.font = "50px 微软雅黑";
ctx.fillStyle = "rgb(0 255 127)";
ctx.save();
ctx.translate(x, y);
ctx.rotate(Math.PI / 180);
ctx.textBaseline = 'bottom';
ctx.fillText(str, 0, 0);
ctx.restore();
y += ctx.measureText(str).width + letterSpacing;
} else if (str.match(/[\u4E00-\u9FA5]/) && (y < 576)) {
} else {
ctx.font = "50px 微软雅黑";
ctx.fillStyle = "rgb(0 255 127)";
ctx.save();
ctx.translate(x, y+1500);
ctx.rotate(Math.PI / 180);
ctx.textBaseline = 'bottom';
ctx.fillText(str, 0, 0);
ctx.restore();
y += ctx.measureText(str).width + letterSpacing;
}
}
perY-= 2;
} else {
perY = 100
}
return cns
}
3.将canvas作为材质赋予实体面
使用Callback函数监听canvas对象,接收变换后的对象,作为imang材质赋予实体面,并将材质背景设置为透明
material: new Cesium.ImageMaterialProperty({
image: new Cesium.CallbackProperty(writeGreenTextOnCanvas, false),
transparent: true
}),
4.添加尾迹线
以上步骤即可实现数字流的动态显示效果,在此基础上还可以增添尾迹线材质,使效果更炫
polyline: {
positions: Cesium.Cartesian3.fromDegreesArrayHeights([
116.38512143191338,39.995666690542585, 20,
116.38512143191338,39.995666690542585, 1000
]),
width: 3,
material: new Cesium.PolylineTrailMaterialProperty({
color: Cesium.Color.fromCssColorString("rgb(255,255,255)"),
trailLength: 0.3,
period: 3
})
}
完整demo地址:
链接:https://pan.baidu.com/s/1WumYrYnuQm8clUaMOj9S4g 提取码:6655
|