# CustomLayer

# 使用

<amap>
  <amap-custom-layer :render="onRender">
    <canvas ref="canvas" />
  </amap-custom-layer>
</amap>
1
2
3
4
5

Source Code

# Props

属性名 类型 备注
render Function 自定义渲染函数 (必传)
visible boolean
zIndex number
opacity number
zooms number[2]
extraOptions object 其它未在上面列出的属性,仅支持单次绑定

# Slots

Slot 名 位置
default 默认 (必传,并且必须是<canvas>元素)

# Events

事件名 备注
complete

# Example

<template>
  <demo-view
    ref="demoView"
    :map-options="{
      center: center,
      zoom: 3,
    }"
    @map-complete="ready = true"
  >
    <template v-slot:control>
      <a-form-item label="opacity">
        <a-slider
          v-model="opacity"
          :min="0"
          :max="1"
          :step="0.1"
          style="width: 180px;"
        />
      </a-form-item>
    </template>
    <template v-slot:map-content>
      <amap-custom-layer :opacity="opacity" :render="draw">
        <canvas ref="canvas" />
      </amap-custom-layer>
    </template>
  </demo-view>
</template>

<script>
const DATA = Object.freeze(
  require('../../public/assets/data/custom-layer-data.json')
);

export default {
  data() {
    return {
      center: [116.306206, 39.975468],
      opacity: 0.8,
      ready: false,
      path: '',
    };
  },
  computed: {
    map() {
      if (!this.ready) return null;
      return this.$refs.demoView.map;
    },
    size() {
      if (!this.map) return { width: 0, height: 0 };
      const size = this.map.getSize();
      return {
        width: size.width,
        height: size.height,
      };
    },
  },
  mounted() {},
  methods: {
    draw() {
      const { map } = this;
      const { canvas } = this.$refs;
      if (!map) return;
      if (!canvas) return;

      const { retina } = AMap.Browser;
      let { width, height } = map.getSize();
      canvas.style.width = width + 'px';
      canvas.style.height = height + 'px';
      if (retina) {
        // 高清适配
        width *= 2;
        height *= 2;
      }
      canvas.width = width;
      canvas.height = height; // 清除画布
      const ctx = canvas.getContext('2d');
      ctx.fillStyle = '#08f';
      ctx.strokeStyle = '#fff';
      ctx.beginPath();
      for (let i = 0; i < DATA.length; i += 1) {
        const center = DATA[i].center;
        let pos = map.lngLatToContainer(center);
        let r = DATA[i].radius;
        if (retina) {
          pos = pos.multiplyBy(2);
          r *= 2;
        }
        ctx.moveTo(pos.x + r, pos.y);
        ctx.arc(pos.x, pos.y, r, 0, 2 * Math.PI);
      }
      ctx.lineWidth = retina ? 6 : 3;
      ctx.closePath();
      ctx.stroke();
      ctx.fill();
    },
  },
};
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98