SuperMap iClient3D for WebGL Canvas(一)数字流特效

作者: 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'); //创建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),//回调canvas
    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

你可能感兴趣的:(三维GIS,3d,动画,javascript)