uni-app label定位在marker中心位置并出现在上方 Bug反馈

uni-app label定位在marker中心位置并出现在上方 Bug反馈

开发环境 版本号 项目创建方式
Windows Windows 10 企业版 HBuilderX

产品分类:uniapp/App

PC开发环境操作系统:Windows

HBuilderX类型:正式

HBuilderX版本号:3.1.18

手机系统:Android

手机系统版本号:Android 10

手机厂商:华为

手机机型:华为p20

页面类型:nvue

打包方式:云端

项目创建方式:HBuilderX

App下载地址或H5网址: https://service.dcloud.net.cn/build/download/de6fb160-01a0-11ec-8178-f3baf54d1416

示例代码:

switch(type) {  
    case 1:  
        this.covers.push({  
            id:index+'',  
            zIndex: index + 900,  
            latitude: val.lat,  
            width:40,  
            height:40,  
            longitude: val.lng,  
            iconPath: `/static/img/markers/06-${p.icon}.png`,  
            label: { //marker气泡  
                content: `${val.pm10}`,  
                color: "#333",  
                bgColor: `${p.color}`,  
                borderWidth:100,  
                borderRadius: 10,  
                fontSize: 12,  
                textAlign: "center",  
                padding: padValue,  
                x: -79,  
                y: -103,  
            },  
            callout: { //marker气泡  
                content: `名称:${val.name}\n统计时间:${val.date}\npm10:${val.pm10}`,  
                color: "#fff",  
                bgColor: "rgba(15, 158, 250, 1)",  
                borderRadius: 10,  
                fontSize: 12,  
                textAlign: "left",  
                padding: 6,  
                display: 'BYCLICK',  
            }  
        })  
    break;
}

操作步骤:

<template>
    <view class="" style="height: 100%;">
        <map v-if='!mapVis' :scale="scaleValue" :style="{width:'750rpx',height:windowHeight+'px'}" class="map-style" id="myMap" :latitude="latitude" :longitude="longitude" show-location @tap="tapVisPanel" @markertap="markertap"></map>
        <map v-if='mapVis' :scale="scaleValue" :style="{width:'750rpx',height:windowHeight+'px'}" class="map-style" id="myMap" :latitude="latitude" :longitude="longitude" :markers="covers" show-location @tap="tapVisPanel" @markertap="markertap"></map>
    </view>
</template>

<script>
import api from '@/api/platform.js';
import componentMixin from '@/mixins/componentMixin.js';
import onLoadMixin from '@/mixins/onLoadMixin.js';

export default {
    mixins: [onLoadMixin],
    components: {},
    data() {
        return {
            mapVis: false,
            data: [],
            windowHeight: uni.getSystemInfoSync().windowHeight,
            title: '站点分布',
            IsOption: false,
            searchKey: "",
            scaleValue: 10,
            latitude: '',
            longitude: '',
            aaa: '',
            fixedCovers: [],
            covers: [],
            pieces: [
                { value: '', color: '#65789B', label: '离线' },
                { value: 0, color: '#3399FF', icon: 'zero', label: '0值' },
                { gt: 0, lte: 50, icon: 'excellent', color: '#61DDAA', label: '优' },
                { gt: 50, lte: 150, icon: 'good', color: '#F6BD16', label: '良' },
                { gt: 150, lte: 250, icon: 'mild', color: '#F6903D', label: '轻度' },
                { gt: 250, lte: 350, icon: 'med', color: '#F46649', label: '中度' },
                { gt: 350, lte: 420, icon: 'serious', color: '#CE1118', label: '重度' },
                { gt: 420, lte: 600, icon: 'severe', color: '#8A0C10', label: '严重' }
            ],
        };
    },
    onLoad(option) {
        this.windowHeight = uni.getSystemInfoSync().windowHeight - 144;
        uni.$on('popupPage', (data) => { this.searchHandle(data.content) });
        uni.$on('clickTap', (data) => { this.tapOption(data.item) });
        uni.$on('handleBadge', (data) => { this.handleMarker(data.index, data.colorValue) });
        this.mapCtx = wx.createMapContext('myMap');
        this.getAuthorizeInfo();
        this.qqmapsdk = new QQMapWX({
            key: 'ULWBZ-7D4WV-FNKPY-UOVE6-W4LO5-HCBD3'
        });
        uni.request({
            method: 'get',
            url: `https://geoapi.qweather.com/v2/city/lookup?key=4badcc2f942c435e885ace18831fc8e8&location=${option.areaCode}`
        }).then(res => {
            if (res[1].data.code === '200') {
                this.latitude = res[1].data.location[0].lat;
                this.longitude = res[1].data.location[0].lon;
            }
        });
        this.getPageData(option.areaCode, option.areaType);
    },
    methods: {
        bindChange(e) {
            console.log(e)
        },
        scaleValueHandle() {
            this.scaleValue++
        },
        tapVisPanel() {
            uni.$emit('tapVisPanel', {})
        },
        markertap(val) {},
        // 获取页面数据
        getPageData(areaCode, areaType) {
            const p1 = new Promise((resolve, reject) => {
                api.getStations({ pointType: 0, areaCode: areaCode, areaType: areaType }).then(res => {
                    resolve({ 'type': 1, 'res': res })
                })
            })
            const p2 = new Promise((resolve, reject) => {
                api.getStations({ pointType: 1, areaCode: areaCode, areaType: areaType }).then(res => {
                    resolve({ 'type': 2, 'res': res })
                })
            })
            const p3 = new Promise((resolve, reject) => {
                api.getProjectStations({ areaCode: areaCode, areaType: areaType }).then(res => {
                    resolve({ 'type': 3, 'res': res })
                })
            })
            Promise.all([p1, p2, p3]).then((result) => {
                this.setMap(result)
            }).catch((error) => {
                console.log(error)
            })
        },
        showSubNuvue() {
            let subNvueMap = uni.getSubNVueById('searchAndBar');
            subNvueMap.show('slide-in-bottom', 0)
        },
        setMap(result) {
            this.mapVis = false
            result.map(item => {
                item.res.data.data.forEach((element, index) => {
                    this.setSign(item.type, element, index)
                });
            })
            this.fixedCovers = this.covers
            this.$nextTick(() => {
                this.mapVis = true
            })
        },
        setSign(type, val, index) {
            this.pieces.map(p => {
                if (!val['pm10']) {
                    val['pm10'] = ''
                }
                if (val['pm10'] && ((val['pm10'] === p.value) || (p.gt <= val['pm10'] && val['pm10'] < p.lte && val['pm10'] !== ''))) {
                    let padValue = 6
                    switch (type) {
                        case 1:
                            this.covers.push({
                                id: index + '',
                                zIndex: index + 900,
                                latitude: val.lat,
                                width: 40,
                                height: 40,
                                longitude: val.lng,
                                iconPath: `/static/img/markers/06-${p.icon}.png`,
                                label: {
                                    content: `${val.pm10}`,
                                    color: "#333",
                                    bgColor: `${p.color}`,
                                    borderWidth: 100,
                                    borderRadius: 10,
                                    fontSize: 12,
                                    textAlign: "center",
                                    padding: padValue,
                                    x: -79,
                                    y: -103,
                                },
                                callout: {
                                    content: `名称:${val.name}\n统计时间:${val.date}\npm10:${val.pm10}`,
                                    color: "#fff",
                                    bgColor: "rgba(15, 158, 250, 1)",
                                    borderRadius: 10,
                                    fontSize: 12,
                                    textAlign: "left",
                                    padding: 6,
                                    display: 'BYCLICK',
                                }
                            })
                            break;
                        case 2:
                            this.covers.push({
                                id: index + '',
                                zIndex: index + 900,
                                latitude: val.lat,
                                width: 40,
                                height: 40,
                                longitude: val.lng,
                                iconPath: `/static/img/markers/06-${p.icon}.png`,
                                label: {
                                    content: `${val.pm10}`,
                                    color: "#333",
                                    bgColor: `${p.color}`,
                                    borderWidth: 100,
                                    borderRadius: 10,
                                    fontSize: 12,
                                    textAlign: "center",
                                    padding: padValue,
                                    x: -79,
                                    y: -103,
                                },
                                callout: {
                                    content: `名称:${val.name}\n统计时间:${val.date}\npm10:${val.pm10}`,
                                    color: "#fff",
                                    bgColor: "rgba(15, 158, 250, 1)",
                                    borderRadius: 10,
                                    fontSize: 12,
                                    textAlign: "left",
                                    padding: 6,
                                    display: 'BYCLICK',
                                }
                            })
                            break;
                        case 3:
                            this.covers.push({
                                id: index + '',
                                zIndex: index + 900,
                                latitude: val.lat,
                                width: 40,
                                height: 40,
                                longitude: val.lng,
                                iconPath: `/static/img/markers/07-${p.icon}.png`,
                                label: {
                                    content: `${val.pm10}`,
                                    color: "#333",
                                    bgColor: `${p.color}`,
                                    borderWidth: 90,
                                    borderRadius: 10,
                                    fontSize: 12,
                                    textAlign: "left",
                                    padding: 7,
                                    x: -74,
                                    y: -96,
                                },
                                callout: {
                                    content: `名称:${val.name}\n统计时间:${val.date}\npm10:${val.pm10}`,
                                    color: "#fff",
                                    bgColor: "rgba(15, 158, 250, 1)",
                                    borderRadius: 10,
                                    fontSize: 12,
                                    textAlign: "center",
                                    padding: 5,
                                    display: 'BYCLICK',
                                }
                            })
                            break;
                    }
                }
            })
        },
        //处理covers
        handleMarker(val, colorValue) {
            this.mapVis = false
            this.covers = this.fixedCovers.filter((item) => {
                if (item.iconPath.indexOf('03') > -1 && colorValue['1']) {
                    return item
                } else if (item.iconPath.indexOf('04') > -1 && colorValue['2']) {
                    return item
                } else if (item.iconPath.indexOf('05') > -1 && colorValue['3']) {
                    return item
                }
            });
            this.$nextTick(() => {
                this.mapVis = true
            })
        },
        // 搜索框
        searchHandle(val) {
            let self = this
            self.searchKey = val
            self.getProjectNameList({ projectName: self.searchKey })
        },
        getProjectNameList(val) {
            api.getProjectNameList(val).then(res => {
                this.aaa = res.data.data
                uni.$emit('popup-page2', {
                    data: res.data.data,
                })
            })
        },
        tapOption(item) {
            let self = this
            self.searchKey = item.title
            self.IsOption = false
            self.data = []
            var obj = {}
            obj.latitude = item.lat;
            obj.longitude = item.lng;
            self.scaleValue = 18
            self.toLocation(obj)
        },
        toLocation(obj) {
            this.mapVis = false
            this.mapCtx.moveToLocation(obj)
            this.mapCtx.translateMarker({
                markerId: 1,
                autoRotate: true,
                duration: 100,
                destination: {
                    latitude: obj.latitude,
                    longitude: obj.longitude,
                },
                animationEnd() {
                    if (self.scaleValue == 18) {
                        self.scaleValue = 17.9
                    } else {
                        self.scaleValue = 18
                    }
                }
            })
            this.$nextTick(() => {
                if (self.scaleValue == 18) {
                    self.scaleValue = 17.9
                } else {
                    self.scaleValue = 18
                }
                self.latitude = obj.latitude,
                self.longitude = obj.longitude,
                this.mapVis = true
            })
        },
        mapSearch(keyword, location) {
            console.log(keyword, location, "keyword,location")
            let promise = new Promise(function(resolve, reject) {
                qqmapsdk.search({
                    keyword: keyword, //搜索关键词
                    location: location, //设置周边搜索中心点
                    success: function(res) {
                        console.log(res)
                        resolve(res)
                    },
                    fail: function(res) {
                        console.log(12313)
                        console.log(res)
                        reject(res)
                    }
                });
            })
            return promise
        },
        // 位置授权
        getAuthorizeInfo() {
            // uni.authorize({
            //     scope: 'scope.userLocation',
            //     success() { // 允许授权
            //         self.getLocationInfo();
            //     },
            //     fail() { // 拒绝授权
            //         self.openConfirm();
            //         console.log("你拒绝了授权,无法获得周边信息")
            //     }
            // })
        },
        // 获取地理位置
        getLocationInfo() {
            uni.getLocation({
                type: 'wgs84',
                success(res) {
                    console.log(res, "当前位置");
                    self.toLocation(res)
                    self.latitude = res.latitude;
                    self.longitude = res.longitude;
                }
            });
        },
        // 再次获取授权
        // 当用户第一次拒绝后再次请求授权
        openConfirm() {
            uni.showModal({
                title: '请求授权当前位置',
                content: '需要获取您的地理位置,请确认授权',
                success(res) {
                    if (res.confirm) {
                        uni.openSetting(); // 打开地图权限设置
                    } else if (res.cancel) {
                        uni.showToast({
                            title: '你拒绝了授权,无法获得周边信息',
                            icon: 'none',
                            duration: 1000
                        })
                    }
                }
            });
        },
        poitap(e) {
            console.log(e, "poitap")
            var obj = e.detail
            self.searchKey = obj.name
            self.toLocation(obj)
        },
        getCenterLocation() {
            this.mapCtx.getCenterLocation({
                success(res) {
                    console.log(res.longitude)
                    console.log(res.latitude)
                }
            })
        }
    }
}
</script>

<style lang="less" scoped>
.top-search {
    position: absolute;
    top: 100px;
    right: 10rpx;
    z-index: 99999;
    background-color: red;
}

map {
    position: relative;
}

.btn-wrap {
    position: absolute;
    top: 180rpx;
    left: 100rpx;
    z-index: 99999;
    background-color: red;
}

.map-style {
    // height: calc(100vh - 44px);
    // height: 100%;
}

.controls-title {
    position: relative;
    margin-top: 350rpx;
    width: 100%;
    text-align: center;
    color: red;
}

.bar-wrap {
    width: 50rpx;
    height: 50rpx;
    background-color: red;
}
</style>

预期结果:

同操作步骤中的代码

实际结果:

同操作步骤中的代码

bug描述:

nvue页面使用label得x,y定位后不能适配所有手机 x,y不是用得upx定位

示例图片


更多关于uni-app label定位在marker中心位置并出现在上方 Bug反馈的实战教程也可以访问 https://www.itying.com/category-93-b0.html

11 回复

设置label的宽高 然后在设置xy 举例:label: { content: 11, fontSize: 20, width: 60, height: 60, bgColor: ‘#00ff00’, borderRadius: 30, textAlign: ‘center’, x: 0, y: -30, }

更多关于uni-app label定位在marker中心位置并出现在上方 Bug反馈的实战教程也可以访问 https://www.itying.com/category-93-b0.html


你就是秀儿

demo 直接运行进去首页

demo运行不起来 弄个简单demo重新提交一下

有没有哪位大佬再看 我们这边客户一直在催

手机这里我用得是p20调试得 这个调试好了 但是其他手机不适配

x y本身就是逻辑像素了 理论上不会相差很大。不同手机偏差很大?

很大 我是按p20调试出来的x,y 比p20小得手机在右下方 还挺多得,比p20屏幕大得手机 左上方 距离挺远得 逻辑上来说 不设置应该喝 经纬度在一起呢

回复 囿于江湖: 设置label的宽高 然后在设置xy 举例:label: { content: markerIds.length + ‘’, fontSize: 20, width: 60, height: 60, bgColor: ‘#00ff00’, borderRadius: 30, textAlign: ‘center’, x: 0, y: -30, }

你需要连接到手机上 我这个进去第一个页面就是nvue

根据你提供的代码和问题描述,这是一个典型的marker label定位适配问题。问题核心在于label的x和y坐标在不同设备上表现不一致。

在uni-app的map组件中,label的x和y坐标单位是像素(px),而不是rpx或upx。你的代码中设置了x: -79, y: -103,这些是固定像素值,在不同分辨率的设备上会出现定位偏差。

解决方案是动态计算x和y的值:

  1. 获取设备像素比
const systemInfo = uni.getSystemInfoSync();
const pixelRatio = systemInfo.pixelRatio;
  1. 根据marker图标尺寸计算偏移量
// 假设你的marker图标是40x40
const markerWidth = 40;
const markerHeight = 40;

// 计算label居中所需的偏移量
const x = -markerWidth / 2;
const y = -markerHeight - 10; // 10是label与marker的间距
  1. 应用到label配置
label: {
    content: `${val.pm10}`,
    color: "#333",
    bgColor: `${p.color}`,
    borderWidth: 100,
    borderRadius: 10,
    fontSize: 12,
    textAlign: "center",
    padding: padValue,
    x: x,
    y: y,
}
回到顶部