济菏高速业务端

184 lines
5.4 KiB

1 year ago
<template>
<div class="bg" id="content" ref="ThumbnailRef"></div>
</template>
<script>
import { getScaleByActualData } from "./utils"
import { onceObserver } from "@screen/utils/resizeObserver";
function setFont(size, bold = "normal", family = "微软雅黑") {
return `${bold} ${size}px ${family}`;
}
export default {
name: "Thumbnail",
data() {
return {
list: getScaleByActualData(),
};
},
mounted() {
onceObserver.call(this, this.$refs.ThumbnailRef, () => {
this.$refs.ThumbnailRef.innerHTML = null;
this.mapInit();
})
},
methods: {
async mapInit() {
const content = this.$refs.ThumbnailRef;
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, 208 * 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, -132);
},
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="less">
.bg {
height: 100%;
width: 100%;
}
</style>