按配置数据绘制配置型地图marker的icon,自定义marker

一、需求

需要自定义配置数据的marker,其中图片内容要灵活可配置自动生成。此处项目用的百度地图。

效果图:

二、思路

用背景图+canvas绘制数字的方式生成icon的图片资源。

再将icon生成对应地图marker。

三、代码

canvasImg.js
<!--
* @description canvasImg.js 背景图+绘制内容生成图片资源
* @author xw
!-->

export function addFontWithBgImg(file, params, callback) {
    var ready = new FileReader()
    /* 开始读取指定的Blob对象或File对象中的内容. 当读取操作完成时,readyState属性的值会成为DONE,如果设置了onloadend事件处理程序,则调用之.同时,result属性中将包含一个data: URL格式的字符串以表示所读取文件的内容.*/
    ready.readAsDataURL(file) // 调用reader.readAsDataURL()方法,把图片转成base64
    ready.onload = function () {
        var re = this.result
        canvasDataURL(re, params, callback)
    }
}

/**
 * path 背景图资源路径
 * params:{ bgImgStyle: 'no-repeat', bgWidth: 35, bgHeight: 48, fontText: 1, fontWidth: 35, fontHeight: 35, font: 'bold 20px PingFangSC', bgc: '#0081FF', fontColor: '#fff' }
 * callback
 *      bgImgStyle = [
            "no-repeat", // 不平铺
            "repeat-x", // 横向平铺
            "repeat-y", // 纵向平铺
            "repeat" // 全画布平铺
        ];
 * */
export function canvasDataURL(path, params, callback) {
    const defaultOptions = {
        bgImgStyle: 'no-repeat',
        bgWidth: 45,
        bgHeight: 48,
        bgc: '#0081FF',
        fontText: 1, // 图片正中 大数字
        font: 'bold 20px PingFangSC',
        fontWidth: 34,
        fontHeight: 39,
        fontColor: '#0081FF',
        fontTwoText: 1, // 右上角 小数字
        fontTwo: 'bold 10px PingFangSC',
        fontTwoColor: '#fff',
        fontTwoPositionX: 35,
        fontTwoPositionY: 10,
    }
    const options = Object.assign(defaultOptions, params)
    const { bgImgStyle, bgWidth, bgHeight, fontText, fontWidth, fontHeight, font, bgc, fontColor, fontTwoText, fontTwo, fontTwoColor, fontTwoPositionX, fontTwoPositionY } = options
    // console.log('createNumberImg()-options', options)
    const img = new Image()
    img.src = path
    img.onload = function () {
        const canvas = document.createElement('canvas');
        // document.body.appendChild(canvas); //将画布添加到页面上
        // 设置画布大小
        canvas.width = bgWidth;
        canvas.height = bgHeight;
        // context 获取2D上下文
        const ctx = canvas.getContext('2d');
        // 清空画布内容
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        // ctx.fillStyle = ctx.createPattern(img, bgImgStyle);
        // ctx.fillRect(0, 0, canvas.width, canvas.height);
        // ctx.fill();
        ctx.drawImage(img, 0, 0, canvas.width, canvas.height)  //绘制背景图片

        // 背景色 部分,会覆盖背景图, 背景色做背景 和 背景图做背景 二选一
        // ctx.fillStyle = bgc
        // 背景画布设置完后,绘制第2层内容, 覆盖在背景上的 内容---ctxTwo--fillText
        // const ctxTwo = canvas.getContext('2d');
        ctx.font = font
        ctx.fillStyle = fontColor
        ctx.textAlign = 'center' // 水平居中 left center right ,positionX = fontWidth / 2
        const positionX = fontWidth / 2
        ctx.textBaseline = 'middle' // 垂直居中 top  middle bottom,  positionY = fontHeight / 2
        const positionY = fontHeight / 2
        ctx.fillText(String(fontText), positionX, positionY)

        ctx.font = fontTwo
        ctx.fillStyle = fontTwoColor
        ctx.fillText(String(fontTwoText), fontTwoPositionX, fontTwoPositionY)
        // 导出为图片数据URL
        const imageDataUrl = canvas.toDataURL('image/png', 1); // canvas.toDataURL('image/png', 1)
        // console.log("生成的图像资源链接:", imageDataUrl);
        callback(imageDataUrl)
    }

}


/**
 * 将以base64的图片url数据转换为Blob
 * @param urlData
 * 用url方式表示的base64图片数据
 */
export function convertBase64UrlToBlob(urlData) {
    const arr = urlData.split(',')
    const mime = arr[0].match(/:(.*?);/)[1]
    const bstr = atob(arr[1])
    let n = bstr.length
    const u8arr = new Uint8Array(n)
    while (n--) {
        u8arr[n] = bstr.charCodeAt(n)
    }
    return new Blob([u8arr], { type: mime })
}
具体使用
createIconImg() {
                // 图片资源 自己找几个bg 在项目里本地引用
                const iconNormal = require('@/assets/image/bg/normal.png');
                const iconDanger = require('@/assets/image/bg/danger.png'); 
                const iconInfo = require('@/assets/image/bg/info.png'); 
                const userImgMap = {
                    '0': iconInfo,
                    '1': iconNormal,
                    '2': iconNormal,
                    '3': iconDanger,
                }
                const fontColorMap = {
                    '0': '#666',
                    '1': '#0081FF',
                    '2': '#0081FF',
                    '3': 'red',
                }
const pointList = [
                    { lng: '113.939435', lat: '22.522226', completeStatus: '0', frequency: 1 },
                    { lng: '113.947254', lat: '22.524549', completeStatus: '1', frequency: 3 },
                    { lng: '113.945889',  lat: '22.520798', completeStatus: '2',  frequency: 4 },
                ]
                // 设置地图 marker ---此处用的百度地图--BMap--使用 canvasDataURL方法
                const markers = []
                if (BMap && pointList && pointList.length > 0) {
                    const mapRef = this.$refs.map
                    mapRef?.clearOverlays()
                    // 生成的icon图片bgWidth背景宽高 要和 canvas画布宽高保持一致
                    const bgWidth = 45
                    const bgHeight = 48
                    const iconSize = new BMap.Size(bgWidth, bgHeight)
                    const iconOptions = { offset: new BMap.Size(25, 50) }
                    pointList.forEach((em, idx) => {
                        const userImg = userImgMap[String(em.completeStatus) || '0']
                        const fontColor = fontColorMap[String(em.completeStatus) || '0']
                        const params = { bgWidth, bgHeight, fontText: String(idx+1), fontColor, fontTwoText: String(em.frequency)} 
                        // 生成图片资源
                        canvasDataURL(userImg, params, function (imgUrl) {
                            const siteMarker = this.createMarker(mapRef, imgUrl, iconSize, iconOptions, item, index)
                            markers.push(siteMarker)
                        })
                    })
                    setTimeout(() => { 
                        const centerPoint = new BMap.Point(Number(selectRow.pointList[0]?.lng), Number(selectRow.pointList[0]?.lat));
                        mapRef.centerAndZoom(centerPoint, 15)
                    }, 300)
                }
            },
            createMarker(mapRef, iconImg, item, index) {
                const siteIcon = new BMap.Icon(
                    iconImg,
                    iconSize,
                    iconOptions,
                )
                const sitePoint = new BMap.Point(Number(item.lng), Number(item.lat));
                const siteMarker = new BMap.Marker(sitePoint, {
                    icon: siteIcon
                })
                // siteMarker.lisaSiteInfo = item // lisaSiteInfo自定义字段 主要装item信息,在InfoWindow的innerHtml时使用
                // const newHtml = '<div class="">我是innerHtml</div>'
                // console.log('newHtml', newHtml)
                // const infoWindow = new BMap.InfoWindow({
                //     content: newHtml,
                //     InfoWindowOptions: {
                //         width: 400,
                //         height: 300,
                //         enableAutoPan: true,
                //     }
                // })
                siteMarker.on('click', function () {
                    alert("carText模拟触发了地图click事件!");
                    // console.log('mapRef', mapRef)
                    // mapRef.openInfoWindow(infoWindow, sitePoint); //开启信息窗口
                })
                mapRef.addOverlay(siteMarker)
                return siteMarker
            },

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

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

相关文章

[NISACTF 2022]sign-ezc++

IDA打开 int __cdecl main(int argc, const char **argv, const char **envp) {Human *v3; // rbxHuman *v4; // rbxchar v6[23]; // [rsp20h] [rbp-20h] BYREFchar v7; // [rsp37h] [rbp-9h] BYREFHuman *v8; // [rsp38h] [rbp-8h]_main(argc, argv, envp);std::allocator<…

明源云ERP系统接口管家 ApiUpdate.ashx 任意文件上传漏洞(QVD-2023-20382)

0x01 产品简介 明源云ERP系统接口管家是明源云ERP提供的一个功能,用于管理和处理系统与外部系统之间的接口集成。它充当了ERP系统与其他应用程序、第三方系统或服务之间的桥梁,负责数据的传输、交换和同步。通过接口管家,用户可以配置和管理不同接口的参数、调度和监控接口…

操作系统-线程的实现方式和多线程模型(用户级线程 内核级线程 多线程模型的情况)和线程的状态,转换,组织,控制

文章目录 线程的实现方式和多线程模型总览线程的实现方式用户级线程内核级线程多线程模型一对一多对一多对多 小结 线程的状态,转换,组织,控制总览 线程的状态与转换线程的组织与控制 线程的实现方式和多线程模型 总览 线程的实现方式 用户级线程 程序自己通过自己设计的线程…

PCIE 4.0 Equalizaiton(LTSSM 均衡流程)

1. 均衡 在Tx端有FFE&#xff08;Feed Forward Equalizer&#xff0c;前馈均衡器&#xff09;&#xff1b;在Rx端有&#xff1a;CTLE&#xff08;Continuous Time Linear Equalizer&#xff0c;连续时间线性均衡器&#xff09;和DFE&#xff08;Decision Feedback Equalizer&a…

SpringBoot项目配置SSL后,WebSocket连接失败的解决方案

SpringBoot项目配置SSL后&#xff0c;WebSocket连接应使用wss协议&#xff0c;而不是ws协议。在前端配置WebSocket时&#xff0c;URL以wss://开头。

【C++】C++ 入门 — 命名空间,输入输出,函数新特性

C 1 前言2 命名空间2.1 概念引入2.2 开始使用2.3 投入应用 3 输入与输出3.1 基础知识3.2 开始使用3.3 注意局限 4 函数新特性4.1 缺省参数4.1.1 开始使用4.1.2 注意事项 4.2 函数重载4.2.1 开始使用4.2.2 如何实现 Thanks♪(&#xff65;ω&#xff65;)&#xff89;谢谢阅读下…

day33_js

今日内容 0 复习昨日 1 JS概述 2 JS的引入方式 3 JS语法 3.1 变量 3.2 基本数据类型 3.3 引用类型 3.4 数组类型 3.5 日期类型 3.6 运算符(算术运算,逻辑,关系运算,三目运算) 3.7 分支 3.8 循环 3.9 函数(重点) 3 常见弹窗函数 alter,confirm,prompt 0 复习昨日 1 盒子模型 对d…

C语言与操作符相关的经典例题

目录 一道变态的面试题&#xff1a;不能创建临时变量&#xff08;第三个变量&#xff09;&#xff0c;实现两个数的交换。 编写代码实现&#xff1a;求一个整数存储在内存中的二进制中1的个数。 二进制位置0或者置1 如果以下的知识点不是很清楚的可以去看这篇文章&#xff1…

代码随想录算法训练营第十五天| 102. 二叉树的层序遍历、226.翻转二叉树、101. 对称二叉树

文章目录 1.二叉树的层序遍历2.翻转二叉树3.对称二叉树 1.二叉树的层序遍历 给你二叉树的根节点 root &#xff0c;返回其节点值的 层序遍历 。 &#xff08;即逐层地&#xff0c;从左到右访问所有节点&#xff09;。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null…

3. SQL 语言

重点&#xff1a; MySQL 的 三种安装方式&#xff1a;包安装&#xff0c;二进制安装&#xff0c;源码编译安装。 MySQL 的 基本使用 MySQL 多实例 DDLcreate alter drop DML insert update delete DQL select 3&#xff09;SQL 语言 3.1&#xff09;关系型数据库的常见…

[晓理紫]每日论文分享(有中文摘要,源码或项目地址)--强化学习、模仿学习、机器人、开放词汇

专属领域论文订阅 关注{晓理紫|小李子}&#xff0c;每日更新论文&#xff0c;如感兴趣&#xff0c;请转发给有需要的同学&#xff0c;谢谢支持 如果你感觉对你有所帮助&#xff0c;请关注我&#xff0c;每日准时为你推送最新论文。 分类: 大语言模型LLM视觉模型VLM扩散模型视觉…

JVM工作原理与实战(二十九):监控内存泄漏的工具

专栏导航 JVM工作原理与实战 RabbitMQ入门指南 从零开始了解大数据 目录 专栏导航 前言 一、解决内存溢出的步骤 二、发现问题 1.Top命令 2.VisualVM 3.Arthas 4.Prometheus Grafana 总结 前言 JVM作为Java程序的运行环境&#xff0c;其负责解释和执行字节码&#x…

PyInstaller 将 Python 程序生成可直接运行的程序

图标转换地址&#xff1a;https://convert.app/#google_vignette 官方文档&#xff1a;https://readthedocs.org/projects/pyinstaller/downloads/pdf/stable/#page20 安装pyinstaller pip install pyinstaller执行打包 pyinstaller -i ./resource/w.icns -w -F whv.py --a…

VsCode CMake调试QT QString等变量不显示具体值,调试中查看qt源码 (可视化调试配置Natvis)

遇到的问题 当我们在VsCode使用CMake来调试QT程序时&#xff0c;可能会出现变量是十六进制的地址&#xff0c;而看不到具体的值。例如&#xff1a; 如何解决 这时候需要手动设置一下natvis &#xff08;资源以上传&#xff0c;可以直接下载&#xff09; 在.vscode文件下找到…

Ribbon 体系架构解析

前面已经介绍了服务治理相关组件&#xff0c;接下来趁热打铁&#xff0c;快速通关Ribbon&#xff01;前面我们了解了负载均衡的含义&#xff0c;以及客户端和服务端负载均衡模型&#xff0c;接下来我们就来看下SpringCloud 下的客户端负载均衡组件Ribbon 的特点以及工作模型。 …

uniapp微信小程序-请求二次封装(直接可用)

一、请求封装优点 代码重用性&#xff1a;通过封装请求&#xff0c;你可以在整个项目中重用相同的请求逻辑。这样一来&#xff0c;如果 API 发生变化或者需要进行优化&#xff0c;你只需在一个地方修改代码&#xff0c;而不是在每个使用这个请求的地方都进行修改。 可维护性&a…

P8651 [蓝桥杯 2017 省 B] 日期问题

#include <iostream> #include <string> using namespace std;int first; int second; int third; int day[13]{0,31,0,31,30,31,30,31,31,30,31,30,31};//每月日期bool select (int i,int j,int k){if ((i%100 first) && (j second) && (k thi…

Spring Cloud + Vue前后端分离-第13章 网站开发

源代码在GitHub - 629y/course: Spring Cloud Vue前后端分离-在线课程 Spring Cloud Vue前后端分离-第13章 网站开发 13-1 网站模块的搭建 新建web模板 1.网站开发&#xff0c;增加web模块&#xff0c;使用命令&#xff1a;vue create web vue版本4.2.3 大家拿到一个v…

第七篇【传奇开心果短博文系列】Python的OpenCV库技术点案例示例:图像拼接和融合

传奇开心果短博文系列 系列短博文目录Python的OpenCV库技术点案例示例短博文系列 短博文目录一、前言二、OpenCV图像拼接融合介绍三、全景图像拼接示例代码和扩展四、图像融合示例代码和扩展五、归纳总结 系列短博文目录 Python的OpenCV库技术点案例示例短博文系列 短博文目录…

el-table 设置内容超出宽度后省略,并添加tooltip

el-table 设置内容超出宽度后省略&#xff0c;并添加tooltip 只需要在el-table-item 标签中添加属性 :show-overflow-tooltip"true" 例子 <template><div style"width:100%; display: flex; justify-content: center;"><el-table :data&…