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
			| 
											2 years 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> |