
<template>
<div class="map-container" ref="mapDom">
<canvas ref="cvsDom"></canvas>
<div class="map-tool" @click="changeActionType">
<div class="map-tool-item" :class="{ active: item.type == actionType }" :data-type="item.type" v-for="item in tools"
v-bind:key="item.type">{{ item.label }}</div>
</div>
<div class="map-menu">
<ul @click="handleMenuClick" v-if="showMenu" :style="menuStyle">
<li data-type="copy">复制</li>
<li data-type="delete">删除</li>
</ul>
</div>
</div>
</template>
<script lang="ts" setup>
import { onMounted, watch, ref } from 'vue';
var ctx, canvas, $scale: any = ref(1), $ratio = ref(2), $rate: any = ref(null), fps = 20, timer;
var actionType = ref<String>("select") // select: 选择和操作坐标区域 move: 移动画布 addPoint: 新增点 addArea: 新增区域
var showMenu = ref<boolean>(false)
var menuStyle = ref<any>({})
var colors = ref<any>({ "1": { level: "1", color: "#ff0000" }, "2": { level: "2", color: "#ff9900" }, "3": { level: "3", color: "#f0e81a" }, "4": { level: "4", color: "#009dd9" } })
const mapDom = ref(null)
const cvsDom = ref(null)
const tools = ref([
{ type: "select", label: "选择" },
{ type: "move", label: "移动" },
{ type: "addPoint", label: "新增点" },
{ type: "addArea", label: "新增区域" },
])
const emit = defineEmits(['update']);
var areaArr = [{ "x1": 211, "y1": 129.5484, "x2": 235.1254, "y2": 169.3311, level: 2 }]
var pointArr = [{ "x": 292.4639, "y": 137.4023, level: 2 }, { "x": 127.252, "y": 169.7545, level: 1 }, { "x": 217.8381, "y": 136.9709, level: 4 }, { "x": 220.8577, "y": 142.1472, level: 3 }, { "x": 307.9929, "y": 144.7354, level: 2 }, { "x": 62.9789, "y": 198.2244, level: 4 }, { "x": 66.8612, "y": 72.2665, level: 2 }]
var arr: any = []
const props = defineProps({
// 是否展示区域,默认为展示
showAreas: {
type: Boolean,
default: true,
},
// 是否展示点,默认为不展示
showPoints: {
type: Boolean,
default: false,
},
// 是否能编辑区域
editAreas: {
type: Boolean,
default: false,
},
// 是否能编辑点
editPoints: {
type: Boolean,
default: false,
},
// 点和区域列表
list: {
type: Array,
default: []
}
});
// 监听列表变化
watch(
() => props.list,
() => {
console.log(props.list)
arr = props.list
},
{ immediate: true, deep: true },
);
// const setPosition = (val) => {
// // console.log('update',val);
// emit('setPosition', val);
// };
// initMap()
onMounted(() => {
initMap()
});
// 初始化dom
function initMap() {
let dom: any = mapDom.value
let w = dom?.offsetWidth
let h = dom?.offsetHeight
canvas = cvsDom.value;
canvas.width = w * $ratio.value;
canvas.height = h * $ratio.value;
canvas.style.width = w + "px"
canvas.style.height = h + "px"
ctx = canvas.getContext("2d")
// 阻止右键菜单冒泡
dom.oncontextmenu = (e) => { e.preventDefault() }
// 绑定滚轮 和 鼠标按键 事件
canvas.addEventListener("wheel", handleWheel, false)
canvas.addEventListener("mousedown", mousedown, false)
canvas.addEventListener("mousemove", mousemoveRecord, false)
document.addEventListener("keydown", handleKeyDown, false)
document.addEventListener("keyup", handleKeyUp, false)
rendar()
}
var isMove = false, isCtrl = false, isMouseDown = false, isResize = false;
function handleKeyDown(e) {
if (e.code == "Space") isMove = true
if (e.key == "Control") {
isCtrl = true
} else {
document.removeEventListener("keydown", handleKeyDown, false)
}
}
function handleKeyUp(e) {
isMove = false
document.removeEventListener("keydown", handleKeyDown, false)
document.addEventListener("keydown", handleKeyDown, false)
}
// 滚轮 放大缩小事件 delta 变化量为 0.1
function handleWheel(e) {
let delta;
if (e.wheelDelta > 0) {
delta = 10
} else {
delta = -10
}
$scale.value = $scale.value * 100 + delta > 300 ? 3 : $scale.value * 100 + delta < 100 ? 1 : parseInt($scale.value * 100 + delta) / 100;
bgInfo.layerX = e.layerX
bgInfo.layerY = e.layerY
}
var moveInfo: any = {
x1: null,
x2: null,
y1: null,
y2: null
}
var moveTimer, isLongClick;
function mousedown(e) {
if (e.which == 1) {
isMouseDown = true
}
isLongClick = false;
bgInfo.originX = Number(bgInfo.x);
bgInfo.originY = Number(bgInfo.y);
moveInfo.x1 = e.layerX;
moveInfo.y1 = e.layerY;
moveInfo.which = e.which;
document.addEventListener("mouseup", mouseup, false)
moveTimer = setTimeout(() => {
isLongClick = true;
canvas.addEventListener("mousemove", mousemove, false)
}, 150)
}
function mousemove(e) {
moveInfo.x2 = e.layerX;
moveInfo.y2 = e.layerY;
}
var mouse = { x: 0, y: 0 }
function mousemoveRecord(e) {
mouse.x = e.layerX;
mouse.y = e.layerY;
}
function mouseup(e) {
isMouseDown = false
if (currentArea.isAdd) addArea()
if (isResize) updateArea()
if (!isLongClick) {
handleClick(e)
if (e.which == 3 && currentArea.selectIndex !== null) {
showMenu.value = true
menuStyle.value = { position: "absolute", left: e.layerX + "px", top: e.layerY + "px" }
} else {
showMenu.value = false
}
}
clearTimeout(moveTimer)
moveInfo = {
x: null,
x1: null,
x2: null,
y: null,
y1: null,
y2: null
}
canvas.removeEventListener("mousemove", mousemove, false)
document.removeEventListener("mouseup", mouseup, false)
}
function handleSelection(e) {
if (actionType.value !== "move" && !isMove && !isResize) {
currentArea.selectIndex = null
}
if (actionType.value == "select" && !isMove) {
let index = -1
// 选中点判定
for (let i = pointArr.length - 1; i >= 0; i--) {
ctx.save()
let { x, y } = mapToArea(pointArr[i].x, pointArr[i].y)
let scale = $ratio.value * $rate.value * 0.8
ctx.save()
ctx.translate(x * $ratio.value, y * $ratio.value)
ctx.beginPath()
ctx.moveTo(0, 6 * scale)
ctx.quadraticCurveTo(- 3 * scale, 3 * scale, - 4 * scale, - 1 * scale)
ctx.bezierCurveTo(- 5 * scale, - 8 * scale, 5 * scale, - 8 * scale, 4 * scale, - 1 * scale)
ctx.quadraticCurveTo(3 * scale, 3 * scale, 0, 6 * scale)
if (ctx.isPointInPath(e.layerX * $ratio.value, e.layerY * $ratio.value)) index = i
ctx.restore()
if (index >= 0) {
currentPoint.selectIndex = index
currentArea.selectIndex = null
break
}
}
// 选中区域判定
if (index < 0) {
let p = areaToMap(e.layerX, e.layerY)
for (let i = areaArr.length - 1; i >= 0; i--) {
if (areaArr[i].x1 <= p.x && areaArr[i].x2 >= p.x && areaArr[i].y1 <= p.y && areaArr[i].y2 >= p.y) {
index = i
break;
}
}
if (index < 0) {
currentArea.selectIndex = null
} else {
let { x1, x2, y1, y2 } = areaArr[index]
currentArea.selectIndex = index
currentArea.x1 = x1
currentArea.x2 = x2
currentArea.y1 = y1
currentArea.y2 = y2
}
currentArea.isAdd = false
}
}
}
function handleClick(e) {
handleSelection(e)
// 左键点击
if (e.which == 1) {
if (actionType.value == "addPoint" && !isMove && !isResize) {
addPoint(e.layerX, e.layerY, "layer")
}
}
// 右键点击
if (e.which == 3) { }
}
function changeActionType(e) {
let type = e.target.dataset.type
if (type) actionType.value = type
}
function handleMenuClick(e) {
let type = e.target.dataset.type
showMenu.value = false;
switch (type) {
case "delete":
if (currentPoint.selectIndex !== null) {
pointArr.splice(currentPoint.selectIndex, 1)
} else {
areaArr.splice(currentArea.selectIndex, 1)
}
break;
}
}
// 渲染
function rendar() {
let w = canvas.width
let h = canvas.height
// move: 移动 default: 箭头 crosshair: 十字
canvas.style.cursor = actionType.value == "move" || isMove ? (isMouseDown ? "grabbing" : "grab") : actionType.value == "addArea" ? "crosshair" : "default"
ctx.clearRect(0, 0, w, h);
ctx.save()
ctx.translate(0.5, 0.5);
darwBg(w, h)
areaArr.forEach((item, index) => {
drawArea(item, index)
})
drawArea(null, null) // 绘制新增区域
pointArr.forEach((item, index) => {
drawPoint(item, index)
})
// drawSelectArea()
ctx.restore()
timer = setTimeout(() => {
rendar()
}, 1000 / fps)
}
var currentPoint: any = { selectIndex: null }
// 新增点
function addPoint(x, y, type) {
let p = type == "layer" ? areaToMap(x, y) : { x, y }
pointArr.push(p)
}
// 绘制点
function drawPoint(item, index) {
let { x, y } = mapToArea(item.x, item.y)
let scale = $ratio.value * $rate.value * 0.8
ctx.save()
ctx.translate(x * $ratio.value, y * $ratio.value)
ctx.save()
ctx.beginPath()
ctx.moveTo(0, 6 * scale)
ctx.quadraticCurveTo(- 3 * scale, 3 * scale, - 4 * scale, - 1 * scale)
ctx.bezierCurveTo(- 5 * scale, - 8 * scale, 5 * scale, - 8 * scale, 4 * scale, - 1 * scale)
ctx.quadraticCurveTo(3 * scale, 3 * scale, 0, 6 * scale)
ctx.closePath()
ctx.fillStyle = colors.value[item.level]
ctx.lineWidth = 3
ctx.strokeStyle = currentPoint.selectIndex == index ? "#000" : "#fff"
ctx.globalAlpha = 0.8;
ctx.fill()
ctx.stroke()
ctx.restore()
ctx.beginPath()
ctx.arc(0, -1.6 * scale, 2.6 * scale, 0, 2 * Math.PI)
ctx.globalAlpha = 0.8;
ctx.fillStyle = "#fff"
ctx.fill()
ctx.restore()
}
var currentArea: any = {
isAdd: false,
selectIndex: null,
x1: null,
x2: null,
y1: null,
y2: null
}
// 新增区域
function addArea() {
let p1 = areaToMap(currentArea.x1, currentArea.y1)
let p2 = areaToMap(currentArea.x2, currentArea.y2)
let p = { x1: p1.x, y1: p1.y, x2: p2.x, y2: p2.y }
areaArr.push(p)
currentArea = {
isAdd: false,
selectIndex: areaArr.length - 1,
x1: null,
x2: null,
y1: null,
y2: null
}
}
function updateArea() {
let p1 = areaToMap(currentArea.x1, currentArea.y1)
let p2 = areaToMap(currentArea.x2, currentArea.y2)
let p = { x1: p1.x, y1: p1.y, x2: p2.x, y2: p2.y }
let item = areaArr[currentArea.selectIndex]
item = Object.assign(item, p)
areaArr[currentArea.selectIndex] = Object.assign({}, item)
delete currentArea["resizeType"]
isResize = false
}
function drawArea(obj, index) {
let { x1, x2, y1, y2 } = obj || moveInfo
if (obj || (!obj && !isMove && actionType.value == "addArea" && moveInfo.which == 1 && moveInfo.x2 !== null)) {
if (obj) {
let p1 = mapToArea(x1, y1)
let p2 = mapToArea(x2, y2)
x1 = Number(p1.x)
y1 = Number(p1.y)
x2 = Number(p2.x)
y2 = Number(p2.y)
} else {
currentArea.selectIndex = null
}
let x = x1 < x2 ? x1 : x2;
let y = y1 < y2 ? y1 : y2;
let w = Math.abs(x1 - x2)
let h = Math.abs(y1 - y2)
// 选区改变大小
if (obj && isResize && !isMove && currentArea.selectIndex == index) {
if (currentArea.resizeType > 0 && moveInfo.x2 !== null) {
if (currentArea.resizeType == 1 || currentArea.resizeType == 4) {
x += (moveInfo.x2 - moveInfo.x1)
w -= (moveInfo.x2 - moveInfo.x1)
} else {
w += (moveInfo.x2 - moveInfo.x1)
}
if (currentArea.resizeType == 1 || currentArea.resizeType == 2) {
y += (moveInfo.y2 - moveInfo.y1)
h -= (moveInfo.y2 - moveInfo.y1)
} else {
h += (moveInfo.y2 - moveInfo.y1)
}
}
// 选区改变位置
else if (currentArea.resizeType === 0 && moveInfo.x2 !== null) {
x += (moveInfo.x2 - moveInfo.x1)
y += (moveInfo.y2 - moveInfo.y1)
}
}
// 换算比例
x = x * $ratio.value
y = y * $ratio.value
w = w * $ratio.value
h = h * $ratio.value
// 绘制选区
let scale = $ratio.value * $scale.value * $rate.value
ctx.save()
ctx.beginPath()
ctx.rect(x, y, w, h)
ctx.save()
ctx.globalAlpha = 0.8;
ctx.fillStyle = colors.value[obj.level || "4"]
ctx.fill()
ctx.restore()
// 当前选区被选中时,框线加粗
ctx.lineWidth = scale * (!obj || (obj && currentArea.selectIndex == index) ? 1.5 : 0.8)
ctx.strokeStyle = "#000"
ctx.stroke()
ctx.restore()
// 新增区域时记录坐标点
if (!obj) {
currentArea = {
isAdd: true,
x1, x2, y1, y2,
selectIndex: null
}
}
// 选中区域绘制改变大小的图例
else if (currentArea.selectIndex == index) {
let resizeType = drawAreaSelection(x, y, w, h)
if (resizeType >= 0 && actionType.value == "select" && !isMove) calcResizeArea(resizeType, x, y, w, h)
}
}
}
// 绘制选中区域 操作示意
function drawAreaSelection(x, y, w, h) {
let resizeType = -1;
let scale = $ratio.value * $scale.value * $rate.value
ctx.save()
ctx.beginPath()
ctx.translate(parseInt(x), parseInt(y))
ctx.rect(-2 * scale, -2 * scale, 4 * scale, 4 * scale)
ctx.fillStyle = "#fff"
ctx.fill()
ctx.lineWidth = scale * 1.2
ctx.strokeStyle = "#000"
ctx.stroke()
if (ctx.isPointInPath(mouse.x * $ratio.value, mouse.y * $ratio.value)) resizeType = 1;
ctx.beginPath()
ctx.rect(-2 * scale + w, -2 * scale, 4 * scale, 4 * scale)
ctx.fill()
ctx.stroke()
if (ctx.isPointInPath(mouse.x * $ratio.value, mouse.y * $ratio.value)) resizeType = 2;
ctx.beginPath()
ctx.rect(-2 * scale + w, -2 * scale + h, 4 * scale, 4 * scale)
ctx.fill()
ctx.stroke()
if (ctx.isPointInPath(mouse.x * $ratio.value, mouse.y * $ratio.value)) resizeType = 3;
ctx.beginPath()
ctx.rect(-2 * scale, -2 * scale + h, 4 * scale, 4 * scale)
ctx.fill()
ctx.stroke()
if (ctx.isPointInPath(mouse.x * $ratio.value, mouse.y * $ratio.value)) resizeType = 4;
ctx.restore()
// 如果当前鼠标坐标没在四个resize点上则判断是否在区域内部
if (resizeType < 0) {
ctx.save()
ctx.beginPath()
ctx.rect(x, y, w, h)
if (ctx.isPointInPath(mouse.x * $ratio.value, mouse.y * $ratio.value)) resizeType = 0
ctx.restore()
}
return resizeType
}
// 计算是否为改变选区大小和位置的操作
function calcResizeArea(resizeType, x, y, w, h) {
// 改变大小 判断mouse的位置是否
currentArea.resizeType = resizeType;
if (resizeType) canvas.style.cursor = resizeType % 2 == 1 ? "nw-resize" : "sw-resize"
if (isMouseDown && !isResize) isResize = true
else if (isMouseDown && isResize) {
currentArea.x1 = x / $ratio.value
currentArea.y1 = y / $ratio.value
currentArea.x2 = (x + w) / $ratio.value
currentArea.y2 = (y + h) / $ratio.value
}
}
// function drawSelectArea() {
// if (actionType.value == "select" && !isMove && moveInfo.which == 1 && moveInfo.x2 !== null) {
// let { x1, x2, y1, y2 } = moveInfo
// let x = x1 < x2 ? x1 : x2;
// let y = y1 < y2 ? y1 : y2;
// let w = Math.abs(x1 - x2)
// let h = Math.abs(y1 - y2)
// ctx.save()
// ctx.beginPath()
// ctx.rect(x * $ratio.value, y * $ratio.value, w * $ratio.value, h * $ratio.value)
// ctx.save()
// ctx.globalAlpha = 0.1;
// ctx.fillStyle = "#6894cb"
// ctx.fill()
// ctx.restore()
// ctx.setLineDash([4 * $ratio.value, 4 * $ratio.value])
// ctx.lineWidth = $ratio.value * 1
// ctx.strokeStyle = "#000000"
// ctx.stroke()
// ctx.restore()
// }
// }
var bgInfo: any = {
x: null, // 当前背景偏移
y: null,
originScale: 1, // 选中前scale值
originX: null, // 选中前背景偏移
originY: null,
src: "/resource/img/map_img.jpg", // 背景图片地址
img: null, // 背景图片对象
load: false // 背景是否加载
}
bgInfo.img = new Image();
bgInfo.img.src = bgInfo.src.toString()
bgInfo.img.onload = () => {
bgInfo.load = true
}
function darwBg(w, h) {
if (!bgInfo.load) return
let img = bgInfo.img
let rate1 = w / h;
let rate2 = img.width / img.height;
$rate.value = rate1 > rate2 ? (w / img.width) : (h / img.height);
let width = img.width * $rate.value
let height = img.height * $rate.value
let x, y;
if (bgInfo.x === null) {
// 初始化居中显示
x = (w - width) / 2
y = (h - height) / 2
}
else if ($scale.value == bgInfo.originScale) {
if ((isMove || actionType.value == "move") && moveInfo.x2 !== null) {
// 移动画布
x = bgInfo.originX + (moveInfo.x2 - moveInfo.x1)
y = bgInfo.originY + (moveInfo.y2 - moveInfo.y1)
} else {
// 未改变scale
x = bgInfo.x
y = bgInfo.y
}
} else {
let delta = parseInt((bgInfo.originScale || 1) * 100 - $scale.value * 100) / 100
x = bgInfo.x + (bgInfo.layerX) * delta
y = bgInfo.y + (bgInfo.layerY) * delta
}
x = x > 0 ? 0 : x + width * $scale.value < w ? w - width * $scale.value : x;
y = y > 0 ? 0 : y + height * $scale.value < h ? h - height * $scale.value : y;
bgInfo.x = Number(x)
bgInfo.y = Number(y)
bgInfo.originScale = Number($scale.value)
ctx.drawImage(img, x, y, width * $scale.value, height * $scale.value)
}
// 坐标系转换 可视区域坐标转地图坐标
function areaToMap(layerX, layerY) {
let mapX = (layerX * $ratio.value - bgInfo.x) / ($scale.value * $ratio.value) / $rate.value
let mapY = (layerY * $ratio.value - bgInfo.y) / ($scale.value * $ratio.value) / $rate.value
mapX = parseInt(mapX * 10000) / 10000
mapY = parseInt(mapY * 10000) / 10000
return { x: mapX, y: mapY }
}
// 坐标系转换 地图坐标坐标转可视区域坐标
function mapToArea(mapX, mapY) {
let layerX = (mapX * ($scale.value * $ratio.value * $rate.value) + bgInfo.x) / $ratio.value
let layerY = (mapY * ($scale.value * $ratio.value * $rate.value) + bgInfo.y) / $ratio.value
layerX = parseInt(layerX * 10000) / 10000
layerY = parseInt(layerY * 10000) / 10000
return { x: layerX, y: layerY }
}
</script>
<style lang="less" scoped>
.map-container {
position: relative;
width: 100%;
height: 100%;
}
.map-tool {
position: absolute;
right: 6px;
bottom: 6px;
user-select: none;
}
.map-tool-item {
display: flex;
justify-content: center;
align-items: center;
width: 40px;
height: 40px;
line-height: 1.2;
margin-bottom: 6px;
text-align: center;
padding: 3px;
box-sizing: border-box;
background: #fff;
border: 1px solid #ddd;
border-radius: 4px;
cursor: pointer;
}
.map-tool-item.active {
background: #2a50ec;
color: #fff;
}
.map-tool-item:last-child {
margin-bottom: 0;
}
<<<<<<< .mine
</style>
||||||| .r12116
</style>=======
.map-select-area-resize {
position: absolute;
width: 10px;
height: 10px;
border: 2px solid #000;
background: rgba(255, 255, 255, 1);
}
.map-select-area-resize.point-1 {
top: -4px;
left: -4px;
}
.map-select-area-resize.point-2 {
top: -4px;
right: -4px;
}
.map-select-area-resize.point-3 {
bottom: -4px;
left: -4px;
}
.map-select-area-resize.point-4 {
bottom: -4px;
right: -4px;
}
.map-menu ul {
width: 100px;
padding: 2px;
background: #fff;
}
.map-menu ul li {
padding: 2px 10px;
border-bottom: 1px solid #eee;
cursor: pointer;
}
.map-menu ul li:hover {
background: rgba(108, 167, 216, .3);
}
.map-menu ul li:last-child {
border-bottom: none;
}
</style>>>>>>>> .r12122

<template>
<div class="map-container" ref="mapDom">
<canvas ref="cvsDom"></canvas>
<div class="map-tool" @click="changeActionType">
<div class="map-tool-item" :class="{ active: item.type == actionType }" :data-type="item.type" v-for="item in tools"
v-bind:key="item.type" v-show="item.isShow === undefined || (item.isShow && item.isShow())">{{ item.label }}</div>
</div>
<div class="map-menu">
<ul @click="handleMenuClick" v-if="showMenu" :style="menuStyle">
<li data-type="delete">删除</li>
</ul>
</div>
</div>
</template>
<script lang="ts" setup>
import { onMounted, onUnmounted, watch, ref } from 'vue';
var ctx, canvas, $scale: any = ref(1), $ratio = ref(2), $rate: any = ref(null), fps = 20, timer;
var actionType = ref<String>("select") // select: 选择和操作坐标区域 move: 移动画布 addPoint: 新增点 addArea: 新增区域
var showMenu = ref<boolean>(false)
var menuStyle = ref<any>({})
const colors = {
"3": { level: "3", color: "#ff0000" },
"2": { level: "2", color: "#ff8f05" },
"1": { level: "1", color: "#ffdf00" },
"0": { level: "0", color: "#009dd9" }
}
var color: String = "#009dd9"
const mapDom = ref(null)
const cvsDom = ref(null)
const tools = ref([
{ type: "select", label: "选择" },
{ type: "move", label: "移动" },
{ type: "addPoint", label: "新增点", isShow: () => { return props.editPoints && props.addPoint } },
{ type: "addArea", label: "新增区域", isShow: () => { return props.editAreas && props.addArea } },
])
const emit = defineEmits(['choose', 'update', 'delete', 'addArea']);
var areaArr = []
var pointArr = []
const props = defineProps({
// 是否能编辑区域
editAreas: {
type: Boolean,
default: false,
},
addArea: {
type: Boolean,
default: true,
},
// 是否能编辑点
editPoints: {
type: Boolean,
default: false,
},
addPoint: {
type: Boolean,
default: true,
},
// 点和区域列表
list: {
type: Array,
default: []
},
// 风险等级
level: {
type: String,
default: "0",
}
});
// 监听列表变化
watch(
() => props.list,
() => {
areaArr = []
pointArr = []
for (let i = 0; i < props.list.length; i++) {
let item: any = Object.assign({}, props.list[i])
if (item._type == "area") {
areaArr.push(item)
} else if (item._type == "point") {
pointArr.push(item)
}
}
},
{ immediate: true, deep: true },
);
watch(
() => props.level,
() => {
let level = (props.level || "").toString()
color = props.level ? colors[level].color.toString() : "#666"
if (currentArea.selectIndex || currentArea.selectIndex === 0) {
areaArr[currentArea.selectIndex].level = level
emit("update", "area", areaArr[currentArea.selectIndex])
}
if (currentPoint.selectIndex || currentPoint.selectIndex === 0) {
pointArr[currentPoint.selectIndex].level = level
emit("update", "point", pointArr[currentArea.selectIndex])
}
},
{ deep: true },
);
// const setPosition = (val) => {
// // console.log('update',val);
// emit('setPosition', val);
// };
// initMap()
onMounted(() => {
initMap()
});
onUnmounted(() => {
// 组件销毁
clearTimeout(timer)
clearTimeout(moveTimer)
canvas.removeEventListener("wheel", handleWheel, false)
canvas.removeEventListener("mousedown", mousedown, false)
canvas.removeEventListener("mousemove", mousemoveRecord, false)
canvas.removeEventListener("mousemove", mousemove, false)
document.removeEventListener("mouseup", mouseup, false)
document.removeEventListener("keydown", handleKeyDown, false)
document.removeEventListener("keyup", handleKeyUp, false)
})
var $dom: any;
// 初始化dom
var isMove = false, isCtrl = false, isMouseDown = false, isResize = false, moveTimer, isLongClick;
function initMap() {
$dom = mapDom.value
canvas = cvsDom.value;
isMove = false;
isCtrl = false;
isMouseDown = false;
isResize = false;
// let w = dom?.offsetWidth - 2
// let h = dom?.offsetHeight - 2
// canvas.width = w * $ratio.value;
// canvas.height = h * $ratio.value;
// canvas.style.width = w + "px"
// canvas.style.height = h + "px"
// ctx = canvas.getContext("2d")
// 阻止右键菜单冒泡
$dom.oncontextmenu = (e) => { e.preventDefault() }
// 绑定滚轮 和 鼠标按键 事件
canvas.addEventListener("wheel", handleWheel, false)
canvas.addEventListener("mousedown", mousedown, false)
canvas.addEventListener("mousemove", mousemoveRecord, false)
document.addEventListener("keydown", handleKeyDown, false)
document.addEventListener("keyup", handleKeyUp, false)
rendar()
}
function getSize() {
let w = $dom?.offsetWidth - 2
let h = $dom?.offsetHeight - 2
canvas.width = w * $ratio.value;
canvas.height = h * $ratio.value;
canvas.style.width = w + "px"
canvas.style.height = h + "px"
ctx = canvas.getContext("2d")
}
function handleKeyDown(e) {
if (e.code == "Space") isMove = true
if (e.key == "Control") {
isCtrl = true
} else {
document.removeEventListener("keydown", handleKeyDown, false)
}
if (e.key == "Delete") {
deleteItem()
}
}
function handleKeyUp(e) {
isMove = false
document.removeEventListener("keydown", handleKeyDown, false)
document.addEventListener("keydown", handleKeyDown, false)
}
// 滚轮 放大缩小事件 delta 变化量为 0.1
function handleWheel(e) {
let delta;
if (e.wheelDelta > 0) {
delta = 10
} else {
delta = -10
}
$scale.value = $scale.value * 100 + delta > 300 ? 3 : $scale.value * 100 + delta < 100 ? 1 : parseInt($scale.value * 100 + delta) / 100;
bgInfo.layerX = e.layerX
bgInfo.layerY = e.layerY
}
var moveInfo: any = {
x1: null,
x2: null,
y1: null,
y2: null
}
function mousedown(e) {
if (e.which == 1) {
isMouseDown = true
}
isLongClick = false;
bgInfo.originX = Number(bgInfo.x);
bgInfo.originY = Number(bgInfo.y);
moveInfo.x1 = e.layerX;
moveInfo.y1 = e.layerY;
moveInfo.x2 = null
moveInfo.y2 = null
moveInfo.which = e.which;
document.addEventListener("mouseup", mouseup, false)
moveTimer = setTimeout(() => {
isLongClick = true;
canvas.addEventListener("mousemove", mousemove, false)
}, 150)
}
function mousemove(e) {
moveInfo.x2 = e.layerX;
moveInfo.y2 = e.layerY;
}
var mouse = { x: 0, y: 0 }
function mousemoveRecord(e) {
mouse.x = e.layerX;
mouse.y = e.layerY;
}
function mouseup(e) {
isMouseDown = false
if (isResize && isLongClick && currentArea.selectIndex !== null) updateArea()
if (isResize && isLongClick && currentPoint.selectIndex !== null) updatePoint()
if (!isLongClick) {
showMenu.value = false
handleClick(e)
}
clearTimeout(moveTimer)
moveInfo = {
x: null,
x1: null,
x2: null,
y: null,
y1: null,
y2: null
}
isResize = false
canvas.removeEventListener("mousemove", mousemove, false)
document.removeEventListener("mouseup", mouseup, false)
}
function handleSelection(e) {
if (actionType.value !== "move" && !isMove && !isResize) {
currentArea.selectIndex = null
}
if (actionType.value == "select" && !isMove) {
let index = -1
// 选中点判定
for (let i = pointArr.length - 1; i >= 0; i--) {
if (!pointArr[i].disable) {
ctx.save()
let { x, y } = mapToArea(pointArr[i].x, pointArr[i].y)
let scale = $ratio.value * $rate.value * 0.8
ctx.save()
ctx.translate(x * $ratio.value, y * $ratio.value)
ctx.beginPath()
ctx.moveTo(0, 6 * scale)
ctx.quadraticCurveTo(- 3 * scale, 3 * scale, - 4 * scale, - 1 * scale)
ctx.bezierCurveTo(- 5 * scale, - 8 * scale, 5 * scale, - 8 * scale, 4 * scale, - 1 * scale)
ctx.quadraticCurveTo(3 * scale, 3 * scale, 0, 6 * scale)
if (ctx.isPointInPath(e.layerX * $ratio.value, e.layerY * $ratio.value)) index = i
ctx.restore()
if (index >= 0) {
currentArea.selectIndex = null
currentPoint.selectIndex = index
emit("choose", "point", pointArr[index], { x: e.layerX, y: e.layerY })
break
}
}
}
// 选中区域判定
if (index < 0) {
currentPoint.selectIndex = null
for (let i = areaArr.length - 1; i >= 0; i--) {
if (!areaArr[i].disable) {
let arr = areaArr[i].arr;
ctx.save()
ctx.beginPath()
for (let i = 0; i <= arr.length; i++) {
let _i = i == arr.length ? 0 : i;
let { x, y } = mapToArea(arr[_i].x, arr[_i].y)
x = x * $ratio.value
y = y * $ratio.value
ctx[i ? "lineTo" : "moveTo"](x, y)
}
if (ctx.isPointInPath(e.layerX * $ratio.value, e.layerY * $ratio.value)) {
index = i
emit("choose", "area", areaArr[index], { x: e.layerX, y: e.layerY })
}
ctx.restore()
}
}
if (index < 0) {
currentArea.selectIndex = null
} else {
currentArea.selectIndex = index
}
currentArea.isAdd = false
}
}
}
function handleClick(e) {
handleSelection(e)
// 左键点击
if (e.which == 1) {
if (actionType.value == "addPoint" && !isMove && !isResize) {
addPoint(e.layerX, e.layerY, "layer")
actionType.value = "select"
}
if (actionType.value == "addArea" && !isMove && !isResize) {
if (!currentArea.arr) currentArea.arr = []
let isOver = false;
currentArea.isAdd = true
let { x, y } = areaToMap(e.layerX, e.layerY)
if (currentArea.arr.length) {
currentArea.arr.forEach(p => {
if (Math.abs(x - p.x) < 10 && Math.abs(y - p.y) < 10) isOver = true
})
}
if (isOver) {
if (currentArea.arr.length >= 3) { addArea(currentArea.arr) }
currentArea.arr = []
}
else {
currentArea.arr.push({ x, y })
}
}
}
// 右键点击
if (e.which == 3) {
// 新增区域时,右键结束新增操作
if (actionType.value == "addArea" && !isMove && !isResize) {
if (currentArea.arr.length >= 3) { addArea(currentArea.arr) } else { currentArea.arr = [] }
}
// 右键打开删除操作弹窗
else if (currentArea.selectIndex !== null) {
showMenu.value = true
menuStyle.value = { position: "absolute", left: e.layerX + "px", top: e.layerY + "px" }
}
if (actionType.value == "select" && currentPoint.selectIndex !== null) {
showMenu.value = true
menuStyle.value = { position: "absolute", left: e.layerX + "px", top: e.layerY + "px" }
}
}
}
function changeActionType(e) {
let type = e.target.dataset.type
if (type) actionType.value = type
if (type == "addArea" && currentArea.isAdd && currentArea.arr.length >= 3) addArea(currentArea.arr)
if (type == "addArea") currentArea.arr = []
}
function handleMenuClick(e) {
let type = e.target.dataset.type
showMenu.value = false;
switch (type) {
case "delete":
deleteItem()
break;
}
}
function deleteItem() {
if (currentPoint.selectIndex !== null) {
let item = pointArr.splice(currentPoint.selectIndex, 1)
currentPoint.selectIndex = null
emit("delete", item.id)
} else {
let item = areaArr.splice(currentArea.selectIndex, 1)
currentArea.selectIndex = null
emit("delete", item.id)
}
}
// 渲染
function rendar() {
getSize()
let w = canvas.width
let h = canvas.height
// move: 移动 default: 箭头 crosshair: 十字
canvas.style.cursor = actionType.value == "move" || isMove ? (isMouseDown ? "grabbing" : "grab") : actionType.value == "addArea" ? "crosshair" : "default"
ctx.clearRect(0, 0, w, h);
ctx.save()
ctx.translate(0.5, 0.5);
darwBg(w, h)
areaArr.forEach((item, index) => {
drawArea(item, index)
})
if (currentArea.isAdd) drawArea(null, null) // 绘制新增区域
pointArr.forEach((item, index) => {
drawPoint(item, index)
})
// drawSelectArea()
ctx.restore()
timer = setTimeout(() => {
rendar()
}, 1000 / fps)
}
var currentPoint: any = { selectIndex: null }
// 新增点
function addPoint(x, y, type) {
let p = type == "layer" ? areaToMap(x, y) : { x, y }
p.level = 2
pointArr.push(p)
}
function updatePoint() {
let { x, y } = areaToMap(currentPoint.x, currentPoint.y)
pointArr[currentPoint.selectIndex].x = x
pointArr[currentPoint.selectIndex].y = y
}
// 绘制点
function drawPoint(item, index) {
let { x, y } = mapToArea(item.x, item.y)
let scale = $ratio.value * $rate.value * (1 + ($scale.value - 1) / 3)
let isChoose = currentPoint.selectIndex == index
if (isChoose && actionType.value == "select" && isResize && moveInfo.x2 !== null) {
x += (moveInfo.x2 - moveInfo.x1)
y += (moveInfo.y2 - moveInfo.y1)
currentPoint.x = Number(x)
currentPoint.y = Number(y)
}
ctx.save()
ctx.globalAlpha = isChoose ? 1 : 0.9;
ctx.translate(x * $ratio.value, y * $ratio.value)
ctx.save()
ctx.beginPath()
ctx.moveTo(0, 6 * scale)
ctx.quadraticCurveTo(- 3 * scale, 3 * scale, - 4 * scale, - 1 * scale)
ctx.bezierCurveTo(- 5 * scale, - 8 * scale, 5 * scale, - 8 * scale, 4 * scale, - 1 * scale)
ctx.quadraticCurveTo(3 * scale, 3 * scale, 0, 6 * scale)
let isInPath = ctx.isPointInPath(mouse.x * $ratio.value, mouse.y * $ratio.value)
if (actionType.value == "select" && isChoose && isInPath) {
canvas.style.cursor = isMouseDown ? "grabbing" : "grab"
if (isMouseDown && !isResize) isResize = true
}
ctx.closePath()
ctx.fillStyle = item.level !== undefined ? colors[item.level].color : color;
ctx.lineWidth = isChoose ? 5 : 3;
ctx.strokeStyle = isChoose ? "#000" : "#fff"
ctx.globalAlpha = 1;
ctx.fill()
ctx.globalAlpha = isChoose ? 0.7 : 1;
ctx.stroke()
ctx.restore()
ctx.beginPath()
ctx.arc(0, -1.6 * scale, 2.2 * scale, 0, 2 * Math.PI)
ctx.fillStyle = "#fff"
ctx.globalAlpha = isChoose ? 0.8 : 0.5;
ctx.fill()
ctx.restore()
}
var currentArea: any = {
isAdd: false,
selectIndex: null,
resizeType: null,
arr: [],
x: null,
y: null,
}
// 新增区域
function addArea(arr) {
areaArr.push({ arr, level: props.level || 4 })
currentArea.arr = []
currentArea.selectIndex = areaArr.length - 1
actionType.value = "select"
emit("addArea", arr)
}
function updateArea() {
if (currentArea.resizeType >= 0 && currentArea.x !== null) {
areaArr[currentArea.selectIndex].arr[currentArea.resizeType].x = currentArea.x
areaArr[currentArea.selectIndex].arr[currentArea.resizeType].y = currentArea.y
} else if (currentArea.resizeType == -1) {
areaArr[currentArea.selectIndex].arr = currentArea.arr
}
delete currentArea["resizeType"]
isResize = false
emit("update", "area", areaArr[currentArea.selectIndex])
}
function drawArea(obj, index) {
if (!obj && !currentArea.arr.length) return
let { arr, level } = obj || currentArea;
arr = arr.map((p) => {
let { x, y } = mapToArea(p.x, p.y)
x = x * $ratio.value
y = y * $ratio.value
return { x, y }
})
let minX, maxX, minY, maxY;
let scale = $ratio.value * $scale.value * $rate.value
ctx.save()
ctx.beginPath()
for (let i = 0; i < arr.length; i++) {
// 选区改变大小
if (obj && !obj._lock && isResize && !isMove && currentArea.selectIndex == index && moveInfo.x2 !== null && (currentArea.resizeType === i || currentArea.resizeType == -1)) {
arr[i].x += (moveInfo.x2 - moveInfo.x1) * $ratio.value
arr[i].y += (moveInfo.y2 - moveInfo.y1) * $ratio.value
}
if (minX === undefined) { minX = Number(arr[i].x) }
else if (minX > arr[i].x) { minX = Number(arr[i].x) }
if (maxX === undefined) { maxX = Number(arr[i].x) }
else if (maxX < arr[i].x) { maxX = Number(arr[i].x) }
if (minY === undefined) { minY = Number(arr[i].y) }
else if (minY > arr[i].y) { minY = Number(arr[i].y) }
if (maxY === undefined) { maxY = Number(arr[i].y) }
else if (maxY < arr[i].y) { maxY = Number(arr[i].y) }
ctx[i ? "lineTo" : "moveTo"](arr[i].x, arr[i].y)
}
if (obj) ctx.lineTo(arr[0].x, arr[0].y)
ctx.save()
ctx.globalAlpha = !obj || (obj && currentArea.selectIndex == index) ? 0.6 : 0.5;
ctx.fillStyle = level !== undefined ? colors[level].color : color;
ctx.fill()
ctx.globalAlpha = 1;
ctx.restore()
// 当前选区被选中时,框线加粗
ctx.lineWidth = scale * (!obj || (obj && currentArea.selectIndex == index) ? 1.2 : 0.8)
ctx.strokeStyle = "#000"
ctx.stroke()
ctx.restore()
if (obj && obj._name && arr.length >= 3) {
let fontSize = 6.2
ctx.save()
ctx.textBaseline = "middle"
ctx.textAlign = "center"
ctx.font = fontSize * scale + "px 黑体 bold"
ctx.fillStyle = "#fff"
ctx.globalAlpha = obj && currentArea.selectIndex == index ? 1 : 0.8;
drawText(obj._name, minX, maxX, minY, maxY, fontSize)
ctx.restore()
}
if (!obj) {
drawAreaSelection(arr)
}
// 选中区域绘制改变大小的图例
else if (currentArea.selectIndex == index && !obj._lock) {
let resizeType = drawAreaSelection(arr)
if (resizeType !== null && actionType.value == "select" && !isMove) calcResizeArea(resizeType, arr)
}
return
}
function drawText(text, x1, x2, y1, y2, font) {
let scale = $ratio.value * $scale.value * $rate.value
let arr = text.split("")
let line = [[]], line_index = 0;
arr.forEach(item => {
if (line[line_index].length) {
let text = line[line_index].join("") + item
let w = ctx.measureText(text).width
if (w < x2 - x1) {
line[line_index].push(item)
} else {
line.push([item])
line_index++
}
} else {
line[line_index].push(item)
}
})
let lineHeight = font * scale;
ctx.translate(x1, y1)
let w = x2 - x1;
let h = y2 - y1;
let deltaY = -(line.length - 1) * lineHeight / 2
line.forEach((item, index) => {
let str = item.join("")
ctx.fillText(str, w / 2, h / 2 + lineHeight * index + deltaY, w - 2 * scale)
})
}
// 绘制选中区域 操作示意
function drawAreaSelection(arr) {
let resizeType: any = -1;
let scale = $ratio.value * $scale.value * $rate.value
for (let i = 0; i < arr.length; i++) {
ctx.save()
ctx.translate(parseInt(arr[i].x), parseInt(arr[i].y))
ctx.beginPath()
ctx.rect(-2 * scale, -2 * scale, 4 * scale, 4 * scale)
ctx.fillStyle = "#fff"
ctx.fill()
ctx.lineWidth = scale * 1.2
ctx.strokeStyle = "#000"
ctx.stroke()
if (ctx.isPointInPath(mouse.x * $ratio.value, mouse.y * $ratio.value)) resizeType = i;
ctx.restore()
}
if (resizeType < 0) {
ctx.save()
ctx.beginPath()
for (let i = 0; i < arr.length; i++) {
ctx[i ? "lineTo" : "moveTo"](arr[i].x, arr[i].y)
}
ctx.closePath()
if (!ctx.isPointInPath(mouse.x * $ratio.value, mouse.y * $ratio.value)) resizeType = null;
ctx.restore()
}
return resizeType
}
// 计算是否为改变选区大小和位置的操作
function calcResizeArea(resizeType, arr) {
// 改变大小 判断mouse的位置是否
canvas.style.cursor = "move"
if (isMouseDown && !isResize) {
isResize = true
currentArea.resizeType = resizeType;
}
else if (isMouseDown && isResize && resizeType >= 0) {
let { x, y } = areaToMap(arr[resizeType].x / $ratio.value, arr[resizeType].y / $ratio.value);
currentArea.x = x
currentArea.y = y
} else if (isMouseDown && isResize && resizeType == -1) {
let new_arr = arr.map(item => {
let { x, y } = areaToMap(item.x / $ratio.value, item.y / $ratio.value);
return { x, y }
})
currentArea.arr = new_arr
}
}
// function drawSelectArea() {
// if (actionType.value == "select" && !isMove && moveInfo.which == 1 && moveInfo.x2 !== null) {
// let { x1, x2, y1, y2 } = moveInfo
// let x = x1 < x2 ? x1 : x2;
// let y = y1 < y2 ? y1 : y2;
// let w = Math.abs(x1 - x2)
// let h = Math.abs(y1 - y2)
// ctx.save()
// ctx.beginPath()
// ctx.rect(x * $ratio.value, y * $ratio.value, w * $ratio.value, h * $ratio.value)
// ctx.save()
// ctx.globalAlpha = 0.1;
// ctx.fillStyle = "#6894cb"
// ctx.fill()
// ctx.restore()
// ctx.setLineDash([4 * $ratio.value, 4 * $ratio.value])
// ctx.lineWidth = $ratio.value * 1
// ctx.strokeStyle = "#000000"
// ctx.stroke()
// ctx.restore()
// }
// }
var bgInfo: any = {
x: null, // 当前背景偏移
y: null,
originScale: 1, // 选中前scale值
originX: null, // 选中前背景偏移
originY: null,
src: "/resource/img/map_img.jpg", // 背景图片地址
img: null, // 背景图片对象
load: false // 背景是否加载
}
bgInfo.img = new Image();
bgInfo.img.src = bgInfo.src.toString()
bgInfo.img.onload = () => {
bgInfo.load = true
}
function darwBg(w, h) {
if (!bgInfo.load) return
let img = bgInfo.img
let rate1 = w / h;
let rate2 = img.width / img.height;
$rate.value = rate1 > rate2 ? (w / img.width) : (h / img.height);
let width = img.width * $rate.value
let height = img.height * $rate.value
let x, y;
if (bgInfo.x === null) {
// 初始化居中显示
x = (w - width) / 2
y = (h - height) / 2
}
else if ($scale.value == bgInfo.originScale) {
if ((isMove || actionType.value == "move") && moveInfo.x2 !== null) {
// 移动画布
x = bgInfo.originX + (moveInfo.x2 - moveInfo.x1)
y = bgInfo.originY + (moveInfo.y2 - moveInfo.y1)
} else {
// 未改变scale
x = bgInfo.x
y = bgInfo.y
}
} else {
let delta = parseInt((bgInfo.originScale || 1) * 100 - $scale.value * 100) / 100
x = bgInfo.x + bgInfo.layerX * $ratio.value * delta
y = bgInfo.y + bgInfo.layerY * $ratio.value * delta
}
x = x > 0 ? 0 : x + width * $scale.value < w ? w - width * $scale.value : x;
y = y > 0 ? 0 : y + height * $scale.value < h ? h - height * $scale.value : y;
bgInfo.x = Number(x)
bgInfo.y = Number(y)
bgInfo.originScale = Number($scale.value)
ctx.drawImage(img, x, y, width * $scale.value, height * $scale.value)
}
// 坐标系转换 可视区域坐标转地图坐标
function areaToMap(layerX, layerY) {
let mapX = (layerX * $ratio.value - bgInfo.x) / ($scale.value * $ratio.value) / $rate.value
let mapY = (layerY * $ratio.value - bgInfo.y) / ($scale.value * $ratio.value) / $rate.value
mapX = parseInt(mapX * 10000) / 10000
mapY = parseInt(mapY * 10000) / 10000
return { x: mapX, y: mapY }
}
// 坐标系转换 地图坐标坐标转可视区域坐标
function mapToArea(mapX, mapY) {
let layerX = (mapX * ($scale.value * $ratio.value * $rate.value) + bgInfo.x) / $ratio.value
let layerY = (mapY * ($scale.value * $ratio.value * $rate.value) + bgInfo.y) / $ratio.value
layerX = parseInt(layerX * 10000) / 10000
layerY = parseInt(layerY * 10000) / 10000
return { x: layerX, y: layerY }
}
</script>
<style lang="less" scoped>
.map-container {
position: relative;
width: 100%;
height: 100%;
}
.map-tool {
position: absolute;
right: 6px;
bottom: 6px;
user-select: none;
}
.map-tool-item {
display: flex;
justify-content: center;
align-items: center;
width: 40px;
height: 40px;
line-height: 1.2;
margin-bottom: 6px;
text-align: center;
padding: 3px;
box-sizing: border-box;
background: #fff;
border: 1px solid #ddd;
border-radius: 4px;
cursor: pointer;
}
.map-tool-item.active {
background: #2a50ec;
color: #fff;
}
.map-tool-item:last-child {
margin-bottom: 0;
}
.map-select-area-resize {
position: absolute;
width: 10px;
height: 10px;
border: 2px solid #000;
background: rgba(255, 255, 255, 1);
}
.map-select-area-resize.point-1 {
top: -4px;
left: -4px;
}
.map-select-area-resize.point-2 {
top: -4px;
right: -4px;
}
.map-select-area-resize.point-3 {
bottom: -4px;
left: -4px;
}
.map-select-area-resize.point-4 {
bottom: -4px;
right: -4px;
}
.map-menu ul {
width: 100px;
padding: 2px;
background: #fff;
}
.map-menu ul li {
padding: 2px 10px;
border-bottom: 1px solid #eee;
cursor: pointer;
}
.map-menu ul li:hover {
background: rgba(108, 167, 216, .3);
}
.map-menu ul li:last-child {
border-bottom: none;
}
</style>
html
<template>
<div class="canvas_container">
<j-map :list="list" @choose="choose"></j-map>
</div>
</template>
<script lang="ts">
export default defineComponent({
name: 'riskDistributionMap'
});
</script>
<script lang="ts" setup>
import { defineComponent, ref } from 'vue';
import jMap from "/@/views/doublecontrol/components/map.vue"
import { controlRiskAreaListData } from '/@/api/doublecontrol/riskarea/controlRiskArea';
const list = ref<any>([])
var areaArr: any = []
getRiskAreaList(1)
function getRiskAreaList(pageNo: 1) {
let pageSize = 50
if (pageNo == 1) areaArr = []
controlRiskAreaListData({ pageNo, pageSize }).then(res => {
if (res.list && res.list.length) {
res.list.forEach(item => {
item.level = item.riskLevel
item._type = "area"
item.arr = JSON.parse(item.regionalDivision) || null
item._lock = true
item._name = item.areaUnitName.toString()
areaArr.push(Object.assign({}, item))
})
list.value = [...areaArr]
if (res.list.length == pageSize) getRiskAreaList(pageNo + 1)
}
console.log(list);
})
}
const choose = (_type, item) => {
console.log(_type, item)
}
</script>
<style lang="less" scoped>
.canvas_container {
width: 1200px;
height: 760px;
border: 1px solid #aaa;
margin: 20px auto 0;
}
</style>