Cesium创建label背景模糊

用Cesium创建label,当页面存在label的情况下再次创建label,则新建label的背景边缘会变得模糊
现象:

img

代码:


<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../cesium1.99//Build/Cesium/Cesium.js"></script>
    <link rel="stylesheet" href="../cesium1.99//Build/Cesium/Widgets/widgets.css">
    <script src="https://lib.baomitu.com/jquery/2.2.4/jquery.js"></script>
    <style>
        body {
            padding: 0;
            margin: 0;
            overflow: hidden;
        }

        #cesiumContainer {
            width: 100vw;
            height: 100vh;
        }

        #createLabel {
            position: absolute;
            top: 20px;
            left: 20px;
            background-color: aqua;
            border: 1px solid black;
            z-index: 100;
            cursor: pointer;
        }
    </style>
</head>

<body>
    <div id="cesiumContainer"></div>
    <div id="createLabel">创建一个视界之外的label</div>
    <script>
        Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI1M2U3MjVhZS0xYjgxLTQ0NzktYjdmMi01ZWY0MTcxYzI2ZDIiLCJpZCI6MTUyMDc2LCJpYXQiOjE2ODg2OTI1Mzh9.CDm3pFXt4bp6HkFW6Hqlud3sReM2inDDAgFVzpXq3QA'
        const viewer = new Cesium.Viewer("cesiumContainer", {
            timeline: false,//时间轴控件
            animation: false,//动画控件
            geocoder: false,//搜索按钮
            homeButton: false,//主页按钮
            sceneModePicker: false,//投影方式按钮
            baseLayerPicker: false,//图层选择按钮
            navigationHelpButton: false,//帮助手势按钮
            fullscreenButton: false,//全屏按钮
        })
        const label1 = viewer.entities.add({
            position: Cesium.Cartesian3.fromDegrees(112, 30, 500),
            label: {
                text: '测试用label1\n位于视界内\n背景完好',
                font: "16px",
                fillColor: Cesium.Color.BLACK,
                showBackground: true,
                backgroundColor: new Cesium.Color(1.0, 1.0, 1.0, 0.5)
            }
        })
        viewer.zoomTo(label1)
        $("#createLabel").click(function () {
            const label2 = viewer.entities.add({
                position: Cesium.Cartesian3.fromDegrees(112.5, 30, 500),
                label: {
                    text: '测试用label2\n位于视界外\n背景边缘模糊',
                    font: "16px",
                    fillColor: Cesium.Color.BLACK,
                    showBackground: true,
                    backgroundColor: new Cesium.Color(1.0, 1.0, 1.0, 0.5)
                }
            })
            viewer.zoomTo(label2)
        })
    </script>
</body>

</html>

【以下回答由 GPT 生成】

要解决Cesium创建label背景模糊的问题,可以按照以下步骤进行操作:

  1. 首先,我们需要了解问题的根本原因。在Cesium中,默认情况下,label的背景是通过CSS的box-shadow属性实现的。由于box-shadow是基于像素的,当缩放或旋转label时,背景会变得模糊。

  2. 为了解决这个问题,我们可以通过修改Cesium的代码,将背景样式修改为使用canvas绘制,而不是使用CSS。这样可以避免背景受到缩放和旋转的影响,保持清晰度。

  3. 首先,将Cesium的源代码下载到本地,并找到cesium/Source/Scene/Label.js文件。

  4. 打开Label.js文件,找到_createLabelCanvas方法。

  5. 在该方法中,我们需要修改以下代码:

// 原始代码
canvas.width = width + backgroundPadding.x * 2;
canvas.height = height + backgroundPadding.y * 2;
context.fillStyle = backgroundColor.toCssColorString();
context.fillRect(0, 0, canvas.width, canvas.height);

将其替换为以下代码:

// 修改后的代码
canvas.width = width + backgroundPadding.x * 2;
canvas.height = height + backgroundPadding.y * 2;
context.fillStyle = 'rgba(0, 0, 0, 0)'; // 设置为透明背景
context.clearRect(0, 0, canvas.width, canvas.height);

这样,我们将背景设置为透明,并清除了之前绘制的内容。

  1. 接下来,我们需要找到_updateLabelCanvas方法。

  2. 在该方法中,我们需要修改以下代码:

// 原始代码
var labelRenderWidth = labelRenderBounds.width + backgroundPadding.x * 2;
var labelRenderHeight = labelRenderBounds.height + backgroundPadding.y * 2;
elt.style.width = labelRenderWidth + 'px';
elt.style.height = labelRenderHeight + 'px';

将其替换为以下代码:

// 修改后的代码
var labelRenderWidth = labelRenderBounds.width + backgroundPadding.x * 2;
var labelRenderHeight = labelRenderBounds.height + backgroundPadding.y * 2;
elt.style.width = labelRenderWidth + 'px';
elt.style.height = labelRenderHeight + 'px';
elt.style.background = 'url(' + labelCanvas.toDataURL() + ')';

这样,我们将label的背景样式设置为通过canvas绘制的图像。

  1. 保存并重新编译Cesium源代码。

  2. 替换HTML中的Cesium.js文件为重新编译后的新文件。

  3. 运行HTML文件,现在应该能够创建一个清晰的label,而不会受到缩放和旋转的影响。

总结起来,解决Cesium创建label背景模糊的问题的关键是修改Cesium的源代码,将label的背景样式从CSS修改为canvas绘制。这样可以避免背景受到缩放和旋转的影响,保证清晰度。以上步骤可以作为具体的解决方案进行实施。



【相关推荐】



如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^