<template> <div class="bg" 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("项目起点", 270 * zoom, h / 2 - 50 * zoom); ctx.fillText("K55+378.7", 270 * 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>