微信小程序地图组件,根据行驶速度绘制彩虹线 附源码

微信小程序地图组件,根据行驶速度绘制彩虹线

彩虹线

可以自定义一段地图折线中的颜色值达到一条线段出现过个颜色的效果

小程序地图组件的踩红线参数

在这里插入图片描述

效果演示:

请添加图片描述

请添加图片描述

甚至

请添加图片描述

小程序代码片段

https://developers.weixin.qq.com/s/XwWhRhmW7UKc

测试数据 请添加图片描述

waySpeed 一个记录行驶速度的数组 与记录点列表的长度相同

wayPath 记录点 经纬度

基本原理

使用HSL 色彩空间中的色相数值达到变换颜色的效果

起始颜色 速度最慢 红色

请添加图片描述

结束颜色 速度最快 绿色

请添加图片描述

只改变H 色相值 使饱和度和亮度保持不变时 颜色值表现出的色彩不同,但亮度和饱和度相同

请添加图片描述
色相不同 但亮度 饱和度相同的三种颜色请添加图片描述

参考:

https://blog.csdn.net/qq_36984465/article/details/109715123

https://zhuanlan.zhihu.com/p/158524543

实现原理

  1. 计算速度的最大速度和最小速度的差值 得到速度区间
  2. 计算结束颜色减去起始颜色的差值
  3. 生成时计算当前速度在速度区间的占比 通过这个比值拿到应有的色相值进行取整
  4. 将这个色相与饱和度和亮度重新组成hsl颜色转为hex格式进行使用

代码片段

drawMap(){

        const mapContext = wx.createMapContext('map')
 

            // 拿到全部坐标点
        let allPoints = this.data.wayPath.map(({latitude,longitude})=>{
        
            return {
                latitude: latitude, // 纬度
                longitude:longitude // 经度
            }
        })
        // 最大速度和最小速度
        const minSpeed = parseFloat((Math.min(...this.data.waySpeed)).toFixed(2))
        const maxSpeed = parseFloat(Math.max(...this.data.waySpeed).toFixed(2))

        // 最小速度和最大速度的差值
        const diffSpeed = maxSpeed - minSpeed

        // 起始色相和终止色相
        const startColorHsb = rgbToHsb(hexToRgb(this.data.minSpeedColor))
        const endColorHsb = rgbToHsb(hexToRgb(this.data.maxSpeedColor))
        // 色相差值 色相范围区间 
        const diffHue = endColorHsb[0] - startColorHsb[0]

        // 最小色相
        const minHue = startColorHsb[0]
        
        // 生成整段路线的颜色列表
        const colorList = this.data.waySpeed.map((speed, index)=>{
            // 当前速度的占比
            const ratioSpeed = parseFloat(((speed - minSpeed) / (minSpeed + diffSpeed)).toFixed(2))
            // 当前色相
            const hue = minHue + Math.round(Math.round(diffHue / 32) * Math.round(ratioSpeed*32))
            // 颜色
            return rgbToHex(hsbToRgb(...[hue, startColorHsb[1], startColorHsb[2]]))
            
        })
    // 地图中的全部折线
    let polylines = []
    // 拆分每段的个数
    const splitCount = 31
    // 拆分整个数组
    for (let i = 0; i < allPoints.length; i += splitCount) {
        
        const pointL = allPoints.slice(i, i + splitCount)
        const nextP = allPoints[i + splitCount]
        
        const colorL = colorList.slice(i, i + splitCount)

        if(nextP){
            pointL.push(nextP)
            colorL.push(colorList[i + splitCount])
        }

        polylines.push({
            // wayPolyline是一个模板对象 用于提供公用属性
            ...this.data.wayPolyline,
            points: pointL,
            colorList: colorL
        });
    }
 

    // 绘制起点 终点
        let startMarker = {
            id: 10,
            latitude: allPoints[0].latitude,
            longitude: allPoints[0].longitude,
            title: '起',
            "aria-label": "起点",
            width: '32px',
            height: '32px',
            iconPath: '/assets/icon/png/start-marker-icon.png'
        }
        const endPoint = allPoints[allPoints.length - 1]
        let endMarker = {
            id: 20,
            latitude: endPoint.latitude,
            longitude: endPoint.longitude,
            title: '终',
            "aria-label": "终点",
            width: '32px',
            height: '32px',
            iconPath: '/assets/icon/png/end-marker-icon.png'
        }
        this.setData({
            polyline: polylines,
            markers: [startMarker,endMarker]
        })
        
        mapContext.includePoints({
            points: allPoints,
            padding: [90,30,30,30],
            success: ()=>{
 
            },
            fail: (err)=>{
                console.log("err",err)
            }
        })
    },

小程序中地图踩红线使用限制

  1. colorList 最长只能有32的长度 超过32 安卓手机直接闪退,开发工具显示正常 所以需要将路径按照31进行拆分 再加上下一段中的第一个 否则会出现不连续的情况

最终效果

请添加图片描述

欢迎 扫码体验骑行小程序 沿途A+ 更多好用功能正在努力开发中

请添加图片描述

颜色转换工具函数

function hexToRgb(hex){
    let sColor = hex.toLowerCase()
    let sColorChange = []
    for (let i=1; i<7; i+=2) {
        sColorChange.push(parseInt("0x"+sColor.slice(i, i+2)));    
    }

    return sColorChange
}

function rgbToHex(rgb){
    var aColor = rgb.replace(/(?:\(|\)|rgb|RGB)*/g, "").split(",");
    var strHex = "#";
    for (var i=0; i<aColor.length; i++) {
        var hex = Math.round(Number(aColor[i])).toString(16);
        if (hex.length < 2) {
            hex = '0' + hex;    
        }
        strHex += hex;
    }
    return strHex
}

function rgbToHsb(arr) {
    var h = 0, s = 0, v = 0;
    var r = arr[0], g = arr[1], b = arr[2];
    arr.sort(function (a, b) {
        return a - b;
    })
    var max = arr[2]
    var min = arr[0];
    v = max / 255;
    if (max === 0) {
        s = 0;
    } else {
        s = 1 - (min / max);
    }
    if (max === min) {
        h = 0;//事实上,max===min的时候,h无论为多少都无所谓
    } else if (max === r && g >= b) {
        h = 60 * ((g - b) / (max - min)) + 0;
    } else if (max === r && g < b) {
        h = 60 * ((g - b) / (max - min)) + 360
    } else if (max === g) {
        h = 60 * ((b - r) / (max - min)) + 120
    } else if (max === b) {
        h = 60 * ((r - g) / (max - min)) + 240
    }
    h = parseInt(h);
    s = parseInt(s * 100);
    v = parseInt(v * 100);
    return [h, s, v]
}
function hsbToRgb(h, s, v) {
    // var h = arr[0], s = arr[1], v = arr[2];
    s = s / 100;
    v = v / 100;
    var r = 0, g = 0, b = 0;
    var i = parseInt((h / 60) % 6);
    var f = h / 60 - i;
    var p = v * (1 - s);
    var q = v * (1 - f * s);
    var t = v * (1 - (1 - f) * s);
    switch (i) {
        case 0:
            r = v; g = t; b = p;
            break;
        case 1:
            r = q; g = v; b = p;
            break;
        case 2:
            r = p; g = v; b = t;
            break;
        case 3:
            r = p; g = q; b = v;
            break;
        case 4:
            r = t; g = p; b = v;
            break;
        case 5:
            r = v; g = p; b = q;
            break;
        default:
            break;
    }
    r = parseInt(r * 255.0)
    g = parseInt(g * 255.0)
    b = parseInt(b * 255.0)

    return `rgb(${r},${g},${b})`
}

function rangeMappingToColor(){

}

module.exports = {
    hexToRgb,
    rgbToHex,
    rgbToHsb,
    hsbToRgb,

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值