• 四十九、openlayers官网示例Immediate Rendering (Geographic)——在地图上绘制星空动画效果


    官网demo地址:

    Immediate Rendering (Geographic) 

    首先先创建1000个随机点,创建点对象。 

    1. const n = 1000;
    2. const geometries = new Array(n);
    3. for (let i = 0; i < n; ++i) {
    4. const lon = 360 * Math.random() - 180;
    5. const lat = 180 * Math.random() - 90;
    6. geometries[i] = new Point([lon, lat]);
    7. }

     因为创建的点坐标是地理坐标,而地图默认是3857投影展示,所以使用 useGeographic()让所有坐标都直接使用地理坐标系(EPSG:4326)

    1. import { useGeographic } from "ol/proj.js";
    2. useGeographic();

    等同于在view中设置projection为"EPSG:4326"

    1. view: new View({
    2. center: [0, 0],
    3. zoom: 2,
    4. projection: "EPSG:4326",
    5. }),

     然后利用postrender在地图上绘制动画效果,每次随机生成一个点,push进geometries数组中,同时将数组的第一个删除,使地图上的点动态的出现消失。

    1. layer.on("postrender", function (event) {
    2. const vectorContext = getVectorContext(event);
    3. for (let i = 0; i < n; ++i) {
    4. const importance = upAndDown(Math.pow((n - i) / n, 0.15));
    5. if (importance < 0.1) {
    6. continue;
    7. }
    8. style.getImage().setOpacity(importance);
    9. style.getImage().setScale(importance);
    10. vectorContext.setStyle(style);
    11. vectorContext.drawGeometry(geometries[i]);
    12. }
    13. const lon = 360 * Math.random() - 180;
    14. const lat = 180 * Math.random() - 90;
    15. geometries.push(new Point([lon, lat]));
    16. geometries.shift();
    17. map.render();
    18. });

    其中upAndDown 是openlayers提供的缓动函数,创建动画效果。定义了动画的进度和速度曲线,使得动画效果更加平滑和自然。调整点的透明度和缩放比例,从而实现点的渐显渐隐效果。

    const importance = upAndDown(Math.pow((n - i) / n, 0.15));

    计算了每个点的重要性,Math.pow((n - i) / n, 0.15) 计算了一个缩放值,upAndDown 函数应用了缓动效果,使得这个缩放值先增加后减少。 

    如果不喜欢点,也可以换成星星图形。

    1. const star = new RegularShape({
    2. radius: 10,
    3. radius2: 3,
    4. points: 5,
    5. angle: Math.PI,
    6. fill: new Fill({
    7. color: "rgba(255, 153, 0, 0.8)",
    8. }),
    9. });
    1. const style = new Style({
    2. // image: image,
    3. image: star,
    4. });

    完整代码:

    1. <template>
    2. <div class="box">
    3. <h1>Immediate Rendering (Geographic)</h1>
    4. <div id="map" class="map"></div>
    5. </div>
    6. </template>
    7. <script>
    8. import StadiaMaps from "ol/source/StadiaMaps.js";
    9. import TileLayer from "ol/layer/Tile.js";
    10. import { Circle, Fill, Style, Icon, RegularShape } from "ol/style.js";
    11. import { Map, View } from "ol/index.js";
    12. import { Point } from "ol/geom.js";
    13. import { getVectorContext } from "ol/render.js";
    14. import { upAndDown } from "ol/easing.js";
    15. import { useGeographic } from "ol/proj.js";
    16. export default {
    17. name: "",
    18. components: {},
    19. data() {
    20. return {
    21. map: null,
    22. };
    23. },
    24. computed: {},
    25. created() {},
    26. mounted() {
    27. useGeographic();
    28. const layer = new TileLayer({
    29. source: new StadiaMaps({
    30. layer: "stamen_toner",
    31. }),
    32. });
    33. const map = new Map({
    34. layers: [layer],
    35. target: "map",
    36. view: new View({
    37. center: [0, 0],
    38. zoom: 2,
    39. projection: "EPSG:4326",
    40. }),
    41. });
    42. const image = new Circle({
    43. radius: 8,
    44. fill: new Fill({ color: "rgba(255, 153, 0, 0.8)" }),
    45. });
    46. const star = new RegularShape({
    47. radius: 10,
    48. radius2: 3,
    49. points: 5,
    50. angle: Math.PI,
    51. fill: new Fill({
    52. color: "rgba(255, 153, 0, 0.8)",
    53. }),
    54. });
    55. const style = new Style({
    56. // image: image,
    57. image: star,
    58. });
    59. const n = 1000;
    60. const geometries = new Array(n);
    61. for (let i = 0; i < n; ++i) {
    62. const lon = 360 * Math.random() - 180;
    63. const lat = 180 * Math.random() - 90;
    64. geometries[i] = new Point([lon, lat]);
    65. }
    66. layer.on("postrender", function (event) {
    67. const vectorContext = getVectorContext(event);
    68. for (let i = 0; i < n; ++i) {
    69. const importance = upAndDown(Math.pow((n - i) / n, 0.15));
    70. if (importance < 0.1) {
    71. continue;
    72. }
    73. style.getImage().setOpacity(importance);
    74. style.getImage().setScale(importance);
    75. vectorContext.setStyle(style);
    76. vectorContext.drawGeometry(geometries[i]);
    77. }
    78. const lon = 360 * Math.random() - 180;
    79. const lat = 180 * Math.random() - 90;
    80. geometries.push(new Point([lon, lat]));
    81. geometries.shift();
    82. map.render();
    83. });
    84. },
    85. methods: {},
    86. };
    87. </script>
    88. <style lang="scss" scoped>
    89. #map {
    90. width: 100%;
    91. height: 500px;
    92. }
    93. .box {
    94. height: 100%;
    95. }
    96. #popup {
    97. width: 160px;
    98. height: 80px;
    99. border-radius: 10px;
    100. background: #fff;
    101. position: absolute;
    102. padding: 10px;
    103. box-sizing: border-box;
    104. }
    105. .triangle {
    106. position: absolute;
    107. left: 50%;
    108. transform: translateX(-50%);
    109. bottom: -20px;
    110. border-top: 10px solid #fff;
    111. border-bottom: 10px solid transparent;
    112. border-left: 10px solid transparent;
    113. border-right: 10px solid transparent;
    114. }
    115. </style>

  • 相关阅读:
    悄然兴起的“跑腿”,正在成为一个千亿市场
    Nature|高性能柔性纤维电池 (柔性智能织物/可穿戴电子/界面调控/柔性电池/柔性电子)
    数字化采购管理系统开发:精细化采购业务流程管理,赋能企业实现“阳光采购”
    去除 Zotero + Obsidian 复制粘贴参考文献表时的多余空行(ctrl+shift+C)
    线程池线程保活以及动态更新线程数
    Ubuntu20.04.6新系统没有wifi驱动(已解决)
    【leetcode】最小差值 I c++
    Java面试宝典(超级详细)
    解析/区分MOS管的三个引脚G、S、D(NMOS管和PMOS管)
    SAE-J1939-21 (超8字节)多包数据----CAN传输协议
  • 原文地址:https://blog.csdn.net/aaa_div/article/details/139798506