Leaflet【五】Marker点闪烁效果

控制点的透明度

在创建marker的构造当中会传递一个配置对象,这个里面就可以配置对应的透明度opacity,那么只需要去修改这个透明度的值就好了。通过定时器去一直改值即可。

const changeOpacity = (entity) => {
  let i = 1;
  let int = setInterval(() => {
    if (!entity._map) clearInterval(int);
    if (i < -1) {
      i = 1;
    }
    i = i - 0.08;
    if (i < 0) entity.setOpacity(i * -1);
    else entity.setOpacity(i);
  }, 60);
};

还可以对这段代码进行调整一下,改成用动画帧去渲染,那么也就是:

const changeOpacity = (entity) => {
  let timer = null;
  let i = 1;

  function updateAnimation() {
    if (!entity._map) return cancelAnimationFrame(timer);
    if (i < -1) {
      i = 1;
    }
    i = i - 0.01;
    if (i < 0) entity.setOpacity(i * -1);
    else entity.setOpacity(i);
    timer = requestAnimationFrame(updateAnimation);
  }

  updateAnimation();
};

本质上是一样的,只要去改变透明度即可。最后创建一个点调用这个方法来进行测试一下

const marker2 = L.marker([22.5, 110], {}).addTo(map);
changeOpacity(marker2);
// 添加平面设置透明度,这个是下面那个,先一起把代码贴上来
// const polygon = L.polygon([
//  [22, 111],
//  [20, 115],
//  [24, 118],
//  [25, 113]
// ]).addTo(map);
// changePlaneOpacity(polygon);

在这里插入图片描述

拓展:控制平面的透明度

在控制平面的时候和点是不一样的,平面都继承至Path对象,这个里面需要通过setStyle去设置对应的属性,所以这里进行细微的调整一下。举一反三我们同样可以通过这种方式去改变其他属性值。

function changePlaneOpacity(entity) {
  let timer = null;
  let i = 1;
  let j = 0.2; // 注意要和线的透明度同步修改,保持开始和结束时间一致
  function updateAnimation() {
    if (i < -1) {
      i = 1;
    }
    i = i - 0.01;
    if (j < -0.2) {
      j = 0.2;
    }
    j = j - 0.002; //注意要和线的透明度同步修改,保持开始和结束时间一致
    if (i < 0) entity.setStyle({opacity: i * -1, fillOpacity: j * -1});
    else entity.setStyle({opacity: i, fillOpacity: j});
    if (!entity._map) return cancelAnimationFrame(timer);
    timer = requestAnimationFrame(updateAnimation);
  }

  updateAnimation();
}

leaflet-pulse-icon插件

简单使用插件,本质上就是构建出一个icon然后将这个icon作为marker标记的图标属性进行渲染

// 安装插件
// npm i @ansur/leaflet-pulse-icon
// 导入插件,同时需要把css一起导入进来
import '@ansur/leaflet-pulse-icon';
import '@ansur/leaflet-pulse-icon/dist/L.Icon.Pulse.css';
// 指定了点的大小以及外围圈的颜色
const pulsingIcon = L.icon.pulse({iconSize:[20,20],color:'red'});
const marker = L.marker([50,15],{icon: pulsingIcon}).addTo(map);

L.icon.pulse 配置说明

取值说明
iconSizeArray宽高
color颜色值外围颜色,默认红色
fillColor颜色值点的填充颜色,默认红色
heartbeat数字一圈渲染完成需要时间,单位为秒,默认为1

渲染n个随机点

// 得到随机颜色
const getRandomColor = () => {
  const r = Math.floor(Math.random() * 255);
  const g = Math.floor(Math.random() * 255);
  const b = Math.floor(Math.random() * 255);
  return `rgb(${r},${g},${b})`;
};

// 得到min和max之间的随机整数
const getRandomInt = (min, max) => {
  min = Math.ceil(min);
  max = Math.floor(max);
  return Math.floor(Math.random() * (max - min + 1)) + min;
};
const addPulseMarker = () => {
  for (let i = 0; i < 100; i++) {
    const size = getRandomInt(5, 10);
    const color = getRandomColor();
    const lat = 15 + Math.random() * 10;
    const lng = 110 + Math.random() * 10;
    const pulsingIcon = L.icon.pulse({
      iconSize: [size, size],
      color,
      fillColor: color,
      heartbeat: 1
    });
    const marker = L.marker([lat, lng], {icon: pulsingIcon}).addTo(map);
    marker.bindPopup(`<b>我的位置:${lng.toFixed(2)}, ${lat.toFixed(2)}</b><br>我的尺寸${size}.`);
  }
};

在这里插入图片描述

leaflet-pulse-icon插件源码透析

这个插件主要的就是前面引入的js和css文件。位置就在node_modules/@ansur/leaflet-pulse-icon/src

L.Icon.Pulse.js

  • 使用的时候会使用L.icon.pulse在这里就是直接new了一个L.Icon.Pulse,然后传递的options配置就直接放到这里面,通过setOptions赋值
  • 之后就是根据配置把对应的Dom元素给组装出来
  • 最后将这个挂载到marker上也就完成了渲染
(function(window) {

    L.Icon.Pulse = L.DivIcon.extend({

        options: {
            className: '',
            iconSize: [12,12],
            fillColor: 'red',
            color: 'red',
            animate: true,
            heartbeat: 1,
        },

        initialize: function (options) {
            L.setOptions(this,options);

            // css
            
            var uniqueClassName = 'lpi-'+ new Date().getTime()+'-'+Math.round(Math.random()*100000);

            var before = ['background-color: '+this.options.fillColor];
            var after = [

                'box-shadow: 0 0 6px 2px '+this.options.color,

                'animation: pulsate ' + this.options.heartbeat + 's ease-out',
                'animation-iteration-count: infinite',
                'animation-delay: '+ (this.options.heartbeat + .1) + 's',
            ];

            if (!this.options.animate){
                after.push('animation: none');
                after.push('box-shadow:none');
            }

            var css = [
                '.'+uniqueClassName+'{'+before.join(';')+';}',
                '.'+uniqueClassName+':after{'+after.join(';')+';}',
            ].join('');
 
            var el = document.createElement('style');
            if (el.styleSheet){
                el.styleSheet.cssText = css;
            } else {
                el.appendChild(document.createTextNode(css));
            }

            document.getElementsByTagName('head')[0].appendChild(el);

            // apply css class

            this.options.className = this.options.className+' leaflet-pulsing-icon '+uniqueClassName;

            // initialize icon
            
            L.DivIcon.prototype.initialize.call(this, options);
        
        }
    });

    L.icon.pulse = function (options) {
        return new L.Icon.Pulse(options);
    };


    L.Marker.Pulse = L.Marker.extend({
        initialize: function (latlng,options) {
            options.icon = L.icon.pulse(options);
            L.Marker.prototype.initialize.call(this, latlng, options);
        }
    });

    L.marker.pulse = function (latlng,options) {
        return new L.Marker.Pulse(latlng,options);
    };

})(window);

L.Icon.Pulse.css

这个本质上也就是根据动画去改变外围圆的大小(scale)和透明度(opacity)

.leaflet-pulsing-icon {
    border-radius: 100%;
    box-shadow: 1px 1px 8px 0 rgba(0,0,0,0.75);
}

.leaflet-pulsing-icon:after {
    content: "";
    border-radius: 100%;
    height: 300%;
    width: 300%;
    position: absolute;
    margin: -100% 0 0 -100%;

}

@keyframes pulsate {
    0% {
        transform: scale(0.1, 0.1);
        opacity: 0;
        -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
        filter: alpha(opacity=0);
    }
    50% {
        opacity: 1;
        -ms-filter: none;
        filter: none;
    }
    100% {
        transform: scale(1.2, 1.2);
        opacity: 0;
        -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
        filter: alpha(opacity=0);
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/751996.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

谷歌发布两款新Gemma 2大语言模型;阿里云开源Qwen2-72B模型荣登榜首

&#x1f989; AI新闻 &#x1f680; 谷歌发布两款新Gemma 2大语言模型 摘要&#xff1a;谷歌发布Gemma 2大语言模型&#xff0c;包括90亿和270亿参数两种版本。Gemma 2在推理性能、效率和安全性上较第一代有显著提升。27B模型的性能媲美更大规模的主流模型&#xff0c;且部署…

【C++题解】1721. 输出个位为5或者个位为8数

问题&#xff1a;1721. 输出个位为5或者个位为8数 类型&#xff1a;简单循环 题目描述&#xff1a; 请从小到大输出 1∼n 中所有个位为 5 或者个位为8 的所有的整数&#xff0c;每行 1 个。 比如&#xff0c;假设 n20&#xff0c;那么满足条件的数输出如下&#xff1a; 5 8 1…

尊重·理解·协同:论团队合作中的认知提升与信誉建设

零、背景 为什么写博客&#xff1f; 给自己灌输大道理—唠叨哲学 定期总结&#xff1a;反思这段时间内的生活、学习或工作中的得失&#xff0c;提炼出具有普适性的经验和教训。 紧跟热点新闻来有点流量 独特视角&#xff1a;尽量优先进行——人云亦云&#xff0c;先学某一…

MQTT遗嘱信息(2)

接前一篇文章&#xff1a;MQTT遗嘱信息&#xff08;1&#xff09; 本文内容参考&#xff1a; 什么是MQTT遗嘱消息&#xff1f;如何配置和处理遗嘱消息&#xff1f;_mqtt last will-CSDN博客 MQTT 协议学习&#xff1a;Retained&#xff08;保留消息&#xff09; 与 LWT&#x…

Stream Lua Nginx Module 插件一键安装

文章目录 一、场景说明二、脚本职责三、参数说明四、操作示例五、注意事项 一、场景说明 本自动化脚本旨在为提高研发、测试、运维快速部署应用环境而编写。 脚本遵循拿来即用的原则快速完成 CentOS 系统各应用环境部署工作。 统一研发、测试、生产环境的部署模式、部署结构、…

Linux容器篇-Docker容器的使用

文章目录 前言一、Docker的安装主机环境准备关闭防火墙关闭selinux时间同步关闭 swap配置操作系统yum源配置国内Docker-ce镜像源注意 二、安装docker-ce三、配置镜像加速器阿里云镜像加速器生成 四、Docker的使用Docker 客户端获取镜像启动容器查看所有的容器&#xff1a;启动已…

内外网共享文件最优方案,了解一下

基于安全性、合规性、数据防泄漏等原因&#xff0c;为了保护核心数据&#xff0c;企业一般会做内外网隔离&#xff0c;隔离后仍存在数据交换共享的需求。数字化时代&#xff0c;数据的流通与共享成为企业和团队之间日常运营的关键环节。内外网共享文件是指在内网和外网之间共享…

【知识学习】阐述Unity3D中动画渲染的概念及使用方法示例

Unity3D中的卡通渲染&#xff08;Cartoon Rendering&#xff09;是一种渲染技术&#xff0c;它模仿传统手绘动画或漫画的视觉效果。这种渲染风格通常具有鲜明的颜色、清晰的轮廓线和简化的光影效果&#xff0c;常用于制作动画、游戏和其他视觉媒体。 卡通渲染的基本概念 轮廓…

绩效管理过程中,定性指标的设计评价怎么做?

导读&#xff1a;企业在设计具体的定性考核标准时&#xff0c;可以运用一些量化的方式&#xff0c;使得最终的考核更具针对性和操作性&#xff0c;但是定性指标不可能完全量化分析&#xff0c;管理者不能过度追求量化原则&#xff0c;设计一些无效的指标。 绩效管理过程中&…

03逻辑门电路

分立门电路&#xff1a; 集成门电路&#xff1a; TTL门电路 MOS门电路&#xff1a;NMOS门电路、PMOS门电路、CMOS门电路 BICMOS门电路&#xff1a;CMOS的高输入阻抗和TTL的高放大倍数的结合 向更低功耗、更高速度发展 MOS管的Rdson在可变电阻区的阻值也一般会小于1000欧姆 …

django学习入门系列之第三点《伪类简单了解》

文章目录 hover&#xff08;伪类&#xff09;after&#xff08;伪类&#xff09;往期回顾 hover&#xff08;伪类&#xff09; 伪类指的是用冒号加的 hover样式指的是&#xff0c;当用户光标移动到设定区域后&#xff0c;所执行的用法 如&#xff1a; <!DOCTYPE html>…

并发编程工具集——Lock和Condition(上)(十二)

简述&#xff1a;Java SDK 并发包通过 Lock 和 Condition 两个接口来实现管程&#xff0c;其中 Lock 用于解决互斥问题&#xff0c;Condition 用于解决同步问题。 再造管程的理由和期望 理由&#xff1a;synchronized 没有办法解决“破坏不可抢占条件方案”。 原因是synchroniz…

Java NIO Buffer概念

针对每一种基本类型的 Buffer &#xff0c;NIO 又根据 Buffer 背后的数据存储内存不同分为了&#xff1a;HeapBuffer&#xff0c;DirectBuffer&#xff0c;MappedBuffer。 HeapBuffer 顾名思义它背后的存储内存是在 JVM 堆中分配&#xff0c;在堆中分配一个数组用来存放 Buffe…

springboot基于web模式的师资管理系统的设计与实现-计算机毕业设计源码040928

摘 要 随着互联网趋势的到来&#xff0c;各行各业都在考虑利用互联网将自己推广出去&#xff0c;最好方式就是建立自己的互联网系统&#xff0c;并对其进行维护和管理。在现实运用中&#xff0c;应用软件的工作规则和开发步骤&#xff0c;采用Java技术建设师资管理系统 。 本设…

全球视角下的AI安全挑战:面向未来的准备

云安全联盟大中华区即将推出人工智能安全认证专家&#xff08;Certified Artificial Intelligence Security Professional&#xff0c;CAISP&#xff09;培训及认证计划&#xff0c;将在Q3全面上线。 在全球科技创新的洪流中&#xff0c;人工智能&#xff08;AI&#xff09;无…

vue3.0(十五)状态管理vuex和pinia

文章目录 状态管理vuex1. 什么情况下应该使用 Vuex2. vuex的安装3. vuex的五大属性4. vuex的五大属性在组件中的应用5. 数据持久化 pinia1.Pinia 对比 Vuex2.安装及引入3.三大属性4.三大属性在组件中的运用总结 状态管理 状态管理是指对Vue.js应用中的数据进行统一管理的一种机…

【.Net】Web项目部署腾讯云

文章目录 总述前置准备docker-compose部署普通部署 参考 总述 前置准备 云服务添加端口 另有linux本身防火墙请参考&#xff1a; 【Linux】防火墙命令 需安装.Net SDK和Asp .Net Runtime 注意&#xff1a; 1、sdk也要不只是runtime 2、是Asp .Net Runtime不是.Net Runtime …

擎耀解码汽车大灯照明系统电动调节步进电机位置反馈的解决方案

在现代汽车设计中&#xff0c;智能照明系统扮演着至关重要的角色。其中&#xff0c;汽车大灯的电动调节功能不仅提高了夜间行车的安全性&#xff0c;还增强了车辆的科技感和便利性。然而&#xff0c;要实现精准的大灯角度调节&#xff0c;步进电机的位置反馈机制尤为关键。擎耀…

SpringBoot脚手架MySpringBootAPI(PgSQL+Druid+MyBatisPlus+Lombok)

MySpringBootAPI SpringBoot脚手架&#xff0c;基于SpringBootDruidPgSQLMyBatisPlusFastJSONLombok&#xff0c;其他的请自行添加和配置。 Author powered by Moshow郑锴(大狼狗) , https://zhengkai.blog.csdn.net 如何运行 1.首先确保你是JDK17&#xff0c;推荐微软的MSJDK…

《Windows API每日一练》6.4 程序测试

前面我们讨论了鼠标的一些基础知识&#xff0c;本节我们将通过一些实例来讲解鼠标消息的不同处理方式。 本节必须掌握的知识点&#xff1a; 第36练&#xff1a;鼠标击中测试1 第37练&#xff1a;鼠标击中测试2—增加键盘接口 第38练&#xff1a;鼠标击中测试3—子窗口 第39练&…