Skip to content
目录

UI

地图引擎里的数据要素不仅仅有图形,有时我们还要在地图上加些UI元素,像弹窗,气泡等

在maptalks里关于domui方面主要提供了uicontrol两个命名空间,关于他们的区别:

  • control下的类,他们的位置是不随着地图视角的改变而改变的,他们的位置是死的,例如比例尺,指北针啊等
  • ui和control正好相反,他们的位置是随着地图视角的改变而改变的,他们的位置会跟随地图,例如弹窗,UIMarker等

WARNING

  • 地图上的UI他们的位置都是随着地图的视角改变而改变的

  • 如果你的UI元素不需要随着地图视角改变而改变其位置,那么你不应该使用地图的UI模块,应该直接使用原生的DOM

  • 例如下面的视频演示的DOM,他的位置是死的

InfoWindow和UIMarker怎样选择

InfoWindow和UIMarker都是在地图上展示UIDOM,但是他们还是有些区别的

  • InfoWindow 一般是随着图形(Geometry)来展示,其一般作为图形的附属信息展示的

  • UIMarker 是独立展示的,不需要成为 Geometry的附属者

  • InfoWindow的展示位置是固定的,一般都是放在Geometry的上面
  • UIMarker的位置就比较灵活了,可以随意放到四周,可以Geometry一起组成一些特殊的效果

你可以把该UIMarker随意的放到Geomtry的四周,UIMarker提供了对齐功能 UIMarker Align Demo
如果UI/UX设计师喜欢设计这种奇奇怪怪的效果就特别适合 UIMarker

Marker和UIMarker怎样选择?

Marker是纯图片渲染,采用canvas或者webgl等渲染技术,而UIMarker是纯的DOM,所以:

  • 纯图片的用Marker
  • 需要在地图展示表格,图表,表单,各种CSS效果,交互等的元素就采用UIMarker

地图展示的UI东西有点多乱糟糟的怎么办?

maptalks的UI已经内置碰撞了功能,开启碰撞即可 ui-collision demo

UI要素支持海拔高度吗?

支持的,不管是UIMarker还是InfoWindow都是支持的

js
const layer = new maptalks.VectorLayer("layer", {
    enableAltitude: true,
}).addTo(map);
const center = map.getCenter();
//海拔
center.z = 100;
const point = new maptalks.Marker(center).addTo(layer);
point.setInfoWindow({
    content: "hello",
});
//显示时会自动那point的坐标作为显示的点,也可以手动传入坐标的值
//openInfoWindow(coordinate)
point.openInfoWindow();

let c2 = center.copy();
c2.x += 0.01;
const marker = new maptalks.ui.UIMarker(c2, {
    content: '<div class="text-marker">maptalks</div>',
    verticalAlignment: "top",
}).addTo(map);

3D模型绑定InfoWindow自动读取模型的高度值

js
const layer = new maptalks.GLTFLayer("layer");

const groupLayer = new maptalks.GroupGLLayer("group", [layer]).addTo(map);

const center = map.getCenter().toArray();
const point = new maptalks.GLTFMarker(center, {
    symbol: {
        url: "./../assets/data/alien.gltf",
        modelHeight: 50, //model height,Unit is meters
        scaleX: 1,
        scaleY: 1,
        scaleZ: 1,
        rotationZ: 180,
    },
});
point.addTo(layer);
point.setInfoWindow({
    content: "hello I am a gltfmarker",
});

UI的内容只支持字符串吗?

UI的内容content不仅仅支持字符串的,也是支持dom节点的

原生的dom

js
const center = map.getCenter().toArray();
const point = new maptalks.Marker(center, {
    symbol: {
        markerType: "ellipse",
        markerWidth: 40,
        markerHeight: 40,
        markerFill: "#fff",
    },
});
point.addTo(layer);
point.setInfoWindow({
    content: document.getElementById("infowindow"),
});

支持Vue/React等组件

只需要把Vue/React等组件挂载的dom节点传递给content即可

js
randomCoordinates().map((c, index) => {
    var Profile = Vue.extend({
        template: `<div class="profile">  <el-button size="mini">默认按钮</el-button>
                            <el-button size="mini" type="danger">危险按钮</el-button>
                            <el-checkbox v-model="checked">备选项</el-checkbox>
                            <p>{{firstName}} {{lastName}} aka {{alias}}</p></div>`,
        data: function () {
            return {
                firstName: "Walter" + index,
                lastName: "White",
                alias: "Heisenberg",
                checked: index % 2 === 0,
            };
        },
    });
    const profile = new Profile().$mount();
    console.log(profile);
    var uiMarker = new maptalks.ui.UIMarker(c, {
        content: profile.$el,
        verticalAlignment: "top",
        // eventsPropagation: false
    });
    uiMarker.addTo(map);
});

设置UI的层级

ui创建时有个参数zIndex,就是css里的zIndex,自己设置合适的值即可

js
var uiMarker = new maptalks.ui.UIMarker(c, {
    content: profile.$el,
    verticalAlignment: "top",
    zIndex: 2,
    // eventsPropagation: false
});

注意事项

  • ui是纯dom,因为dom的性能问题,所以地图上不适合有大量的UI节点,否则性能很差

  • UIMarker默认是中心点对齐的,默认在地图上会比较大的视觉误差,导致其所在的位置和我们期望的不一样,尤其是将地图缩小时视觉误差更大,你可以把UIMarker的verticalAlignment设为top,让UIMarker垂直对齐方式为top来解决视觉误差的问题 关于UIMarker对齐方式的例子

  • maptalks里UI里的dom容器是maptalks自动生成的,所以要想关闭UI,请调用UI的hide或者remove方法,用户传入的dom只是UI的内容而已, 内容作为dom容器的子节点了,所以仅仅对你传入的dom节点进行隐藏等是不能关闭UI元素的

js
point.closeInfoWindow();
//or
point.removeInfoWindow();
//or
point.getInfoWindow().hide();
//or
infowindow.hide();

This document is generated by mdpress