You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
177 lines
5.1 KiB
177 lines
5.1 KiB
1 year ago
|
<template>
|
||
|
<div class="bg" id="content"></div>
|
||
|
</template>
|
||
|
|
||
|
<script>
|
||
|
import { getScaleByActualData } from './utils'
|
||
|
|
||
|
function setFont(size, bold = 'normal', family = '微软雅黑') {
|
||
|
return `${bold} ${size}px ${family}`
|
||
|
}
|
||
|
|
||
|
export default {
|
||
|
data() {
|
||
|
return {
|
||
|
list: getScaleByActualData()
|
||
|
}
|
||
|
},
|
||
|
|
||
|
mounted() {
|
||
|
this.$nextTick(() => {
|
||
|
this.mapInit()
|
||
|
})
|
||
|
},
|
||
|
methods: {
|
||
|
async mapInit() {
|
||
|
var content = document.getElementById('content')
|
||
|
const width = content.clientWidth
|
||
|
const height = content.clientHeight
|
||
|
const zoom = 3
|
||
|
const canvas = document.createElement('canvas')
|
||
|
canvas.style.width = width + 'px'
|
||
|
canvas.style.height = height + 'px'
|
||
|
const w = width * zoom
|
||
|
const h = height * zoom
|
||
|
canvas.width = w
|
||
|
canvas.height = h
|
||
|
content.appendChild(canvas)
|
||
|
|
||
|
const ctx = canvas.getContext('2d')
|
||
|
ctx.textAlign = 'center'
|
||
|
ctx.textBaseline = 'middle'
|
||
|
var imgbg = await this.loadImage(require('./images/bg.png'))
|
||
|
ctx.drawImage(imgbg, 0, 0, w, h)
|
||
|
ctx.font = setFont(12 * zoom)
|
||
|
ctx.fillStyle = '#ffffff'
|
||
|
ctx.fillText('G2001济南绕城高速', 66 * zoom, h / 2 - 21 * zoom)
|
||
|
ctx.fillText('G3021德上高速', w - 50 * zoom, h / 2 - 21 * zoom)
|
||
|
|
||
|
ctx.font = setFont(12 * zoom, 'italic 900', 'Arial Black')
|
||
|
|
||
|
ctx.fillStyle = '#ddc85a'
|
||
|
ctx.fillText('项目起点', 210 * zoom, h / 2 - 50 * zoom)
|
||
|
ctx.fillText('K55+378.7', 210 * zoom, h / 2 - 33 * zoom)
|
||
|
ctx.fillText('项目终点', w - 210 * zoom, h / 2 - 50 * zoom)
|
||
|
ctx.fillText('K208+153.4', w - 210 * zoom, h / 2 - 33 * zoom)
|
||
|
|
||
|
ctx.font = setFont(12 * zoom)
|
||
|
|
||
|
ctx.translate(-25 * zoom, 210 * zoom)
|
||
|
|
||
|
this.drawCongestionAreas(ctx, 1404, 80, zoom)
|
||
|
// this.drawCongestionAreas(ctx, 1365, 150, zoom)
|
||
|
|
||
|
for (let i of this.list) {
|
||
|
await this.drawTag(i, zoom, ctx)
|
||
|
}
|
||
|
},
|
||
|
async drayLine(zoom, text, ctx, isFoot = false) {
|
||
|
ctx.setLineDash([4 * zoom, 4 * zoom])
|
||
|
ctx.strokeStyle = '#37B5D4'
|
||
|
ctx.lineWidth = 6
|
||
|
if (isFoot) {
|
||
|
ctx.translate(0, 12 * zoom)
|
||
|
ctx.strokeRect(0, 0, 1, 161 * zoom)
|
||
|
ctx.translate(0, -12 * zoom)
|
||
|
} else {
|
||
|
ctx.strokeRect(0, 0, 1, 135 * zoom)
|
||
|
}
|
||
|
|
||
|
ctx.fillStyle = '#37B5D4'
|
||
|
ctx.translate(0, -16 * zoom)
|
||
|
|
||
|
if (isFoot) {
|
||
|
ctx.fillText(text, 0, 54)
|
||
|
ctx.translate(0, 226 * zoom)
|
||
|
ctx.fillText(text, 0, -90)
|
||
|
} else {
|
||
|
ctx.fillText(text, 0, 18)
|
||
|
}
|
||
|
},
|
||
|
async drawTag(info, zoom, ctx) {
|
||
|
let type = '3'
|
||
|
if (info.name.indexOf('枢纽') !== -1) {
|
||
|
type = '0'
|
||
|
} else if (info.name.indexOf('服务区') !== -1) {
|
||
|
type = '2'
|
||
|
} else if (info.name.indexOf('停车区') !== -1) {
|
||
|
type = '1'
|
||
|
}
|
||
|
if (type === '0') {
|
||
|
ctx.translate(info.distance * zoom, -188 * zoom)
|
||
|
ctx.font = setFont(12 * zoom, '600')
|
||
|
await this.drayLine(zoom, info.line, ctx, info.isFoot)
|
||
|
if (info.isFoot) {
|
||
|
ctx.translate(-10 * zoom, -180 * zoom)
|
||
|
} else {
|
||
|
ctx.translate(-10 * zoom, 35 * zoom)
|
||
|
}
|
||
|
if (info.name === '东平湖枢纽') {
|
||
|
const r = -110
|
||
|
ctx.rotate((r * Math.PI) / 180)
|
||
|
ctx.strokeRect(-15 * zoom, 0, 1, 90 * zoom)
|
||
|
ctx.rotate((r * Math.PI) / -180)
|
||
|
ctx.fillText('S33济徐高速', 124 * zoom, -27 * zoom)
|
||
|
}
|
||
|
} else {
|
||
|
ctx.translate(info.distance * zoom, -169 * zoom)
|
||
|
}
|
||
|
let y = 42 - (info.name.length - 5) * 10
|
||
|
ctx.fillStyle = '#ffffff'
|
||
|
ctx.font = setFont(12 * zoom)
|
||
|
var img = await this.loadImage(require(`./images/${info.icon || `tag${type}`}.png`))
|
||
|
ctx.drawImage(img, 0, 0, 21 * zoom, 117 * zoom)
|
||
|
ctx.translate(11.1 * zoom, y * zoom)
|
||
|
|
||
|
for (var i = 0; i < info.name.length; i++) {
|
||
|
ctx.fillText(info.name[i], 0, i * 15 * zoom)
|
||
|
}
|
||
|
|
||
|
ctx.translate(0, (169 - y) * zoom)
|
||
|
ctx.font = setFont(10.5 * zoom)
|
||
|
ctx.fillText(info.code, 0, -139)
|
||
|
},
|
||
|
loadImage(url) {
|
||
|
return new Promise((resolve, reject) => {
|
||
|
const img = new Image()
|
||
|
img.setAttribute('crossOrigin', 'anonymous')
|
||
|
img.src = url
|
||
|
img.onload = () => {
|
||
|
// 当图像加载完成后进行resolve
|
||
|
resolve(img)
|
||
|
}
|
||
|
img.onerror = () => {
|
||
|
reject(new Error('图像加载失败'))
|
||
|
}
|
||
|
})
|
||
|
},
|
||
|
drawCongestionAreas(ctx, x, y, zoom) {
|
||
|
const { e: translateX, f: translateY } = ctx.getTransform()
|
||
|
x = translateX * -1 + x * zoom
|
||
|
y = translateY * -1 + y * zoom
|
||
|
|
||
|
const rectWidth = 180 * zoom
|
||
|
const rectHeight = 8 * zoom
|
||
|
|
||
|
const grad = ctx.createLinearGradient(x, 0, x + rectWidth, 0)
|
||
|
grad.addColorStop(0, 'rgba(217,50,8,0)')
|
||
|
grad.addColorStop(0.27, '#D73208')
|
||
|
grad.addColorStop(0.42, '#D93208')
|
||
|
grad.addColorStop(0.81, '#F5FF83')
|
||
|
grad.addColorStop(1, 'rgba(215,50,8,0)')
|
||
|
|
||
|
ctx.fillStyle = grad
|
||
|
|
||
|
ctx.fillRect(x, y, rectWidth, rectHeight)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
</script>
|
||
|
|
||
|
<style scoped lang="scss">
|
||
|
.bg {
|
||
|
height: 100%;
|
||
|
width: 100%;
|
||
|
}
|
||
|
</style>
|