Showing
1 changed file
with
87 additions
and
9 deletions
| 1 | <!-- | 1 | <!-- |
| 2 | * @Date: 2025-01-22 11:40:12 | 2 | * @Date: 2025-01-22 11:40:12 |
| 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com | 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com |
| 4 | - * @LastEditTime: 2025-02-27 09:25:30 | 4 | + * @LastEditTime: 2025-03-04 15:13:41 |
| 5 | * @FilePath: /map-demo/src/views/mapCutter.vue | 5 | * @FilePath: /map-demo/src/views/mapCutter.vue |
| 6 | * @Description: 文件描述 | 6 | * @Description: 文件描述 |
| 7 | --> | 7 | --> |
| ... | @@ -110,8 +110,8 @@ | ... | @@ -110,8 +110,8 @@ |
| 110 | 110 | ||
| 111 | <!-- 旋转控制 --> | 111 | <!-- 旋转控制 --> |
| 112 | <div class="rotate-control"> | 112 | <div class="rotate-control"> |
| 113 | - <button class="z-button" @click="rotateMap(10)">↺</button> | 113 | + <button class="z-button" @click="rotateMap(1)">↺</button> |
| 114 | - <button class="z-button" @click="rotateMap(-10)">↻</button> | 114 | + <button class="z-button" @click="rotateMap(-1)">↻</button> |
| 115 | </div> | 115 | </div> |
| 116 | 116 | ||
| 117 | <!-- 透明度控制 --> | 117 | <!-- 透明度控制 --> |
| ... | @@ -408,18 +408,96 @@ const scaleImage = (factor) => { | ... | @@ -408,18 +408,96 @@ const scaleImage = (factor) => { |
| 408 | imageLayer.value.setBounds(bounds.value); | 408 | imageLayer.value.setBounds(bounds.value); |
| 409 | }; | 409 | }; |
| 410 | 410 | ||
| 411 | -// 旋转地图 | 411 | +// 在 script setup 顶部添加图片旋转角度变量 |
| 412 | +const imageRotation = ref(0); | ||
| 413 | + | ||
| 414 | +// 修改 rotateMap 方法,只旋转图片 | ||
| 412 | const rotateMap = (deltaAngle) => { | 415 | const rotateMap = (deltaAngle) => { |
| 413 | - if (!map.value) return; | 416 | + if (!imageLayer.value || !imageURL.value) return; |
| 417 | + | ||
| 418 | + imageRotation.value = (imageRotation.value + deltaAngle) % 360; | ||
| 419 | + console.log(`图片旋转: ${imageRotation.value}°`); | ||
| 414 | 420 | ||
| 415 | - mapRotation.value += deltaAngle; | 421 | + const img = new Image(); |
| 422 | + img.src = imageURL.value; | ||
| 423 | + | ||
| 424 | + img.onload = () => { | ||
| 425 | + const canvas = document.createElement('canvas'); | ||
| 426 | + const ctx = canvas.getContext('2d'); | ||
| 427 | + | ||
| 428 | + // 计算旋转后的画布大小 | ||
| 429 | + const angleRad = (imageRotation.value * Math.PI) / 180; | ||
| 430 | + const cosAngle = Math.abs(Math.cos(angleRad)); | ||
| 431 | + const sinAngle = Math.abs(Math.sin(angleRad)); | ||
| 432 | + | ||
| 433 | + // 计算旋转后需要的画布尺寸 | ||
| 434 | + const newWidth = img.width * cosAngle + img.height * sinAngle; | ||
| 435 | + const newHeight = img.width * sinAngle + img.height * cosAngle; | ||
| 436 | + | ||
| 437 | + // 设置画布大小为旋转后的尺寸 | ||
| 438 | + canvas.width = newWidth; | ||
| 439 | + canvas.height = newHeight; | ||
| 440 | + | ||
| 441 | + // 移动到画布中心点 | ||
| 442 | + ctx.translate(newWidth / 2, newHeight / 2); | ||
| 443 | + // 旋转画布 | ||
| 444 | + ctx.rotate(angleRad); | ||
| 445 | + // 绘制图片,从中心点开始绘制 | ||
| 446 | + ctx.drawImage(img, -img.width / 2, -img.height / 2); | ||
| 447 | + | ||
| 448 | + // 获取旋转后的图片 URL | ||
| 449 | + const rotatedImageURL = canvas.toDataURL(); | ||
| 450 | + | ||
| 451 | + // 重新计算边界框以适应旋转后的图片 | ||
| 452 | + const sw = bounds.value.getSouthWest(); | ||
| 453 | + const ne = bounds.value.getNorthEast(); | ||
| 454 | + const centerLng = (sw.lng + ne.lng) / 2; | ||
| 455 | + const centerLat = (sw.lat + ne.lat) / 2; | ||
| 456 | + | ||
| 457 | + // 计算四个角的经纬度 | ||
| 458 | + const calculateCorner = (x, y, centerX, centerY) => { | ||
| 459 | + const angle = imageRotation.value * Math.PI / 180; | ||
| 460 | + const rotatedX = centerX + (x - centerX) * Math.cos(angle) - (y - centerY) * Math.sin(angle); | ||
| 461 | + const rotatedY = centerY + (x - centerX) * Math.sin(angle) + (y - centerY) * Math.cos(angle); | ||
| 462 | + return { lng: rotatedX, lat: rotatedY }; | ||
| 463 | + }; | ||
| 464 | + | ||
| 465 | + // 以图片中心点为基准 | ||
| 466 | + const centerX = centerLng; | ||
| 467 | + const centerY = centerLat; | ||
| 468 | + | ||
| 469 | + const topLeft = calculateCorner(sw.lng, ne.lat, centerX, centerY); | ||
| 470 | + const topRight = calculateCorner(ne.lng, ne.lat, centerX, centerY); | ||
| 471 | + const bottomLeft = calculateCorner(sw.lng, sw.lat, centerX, centerY); | ||
| 472 | + const bottomRight = calculateCorner(ne.lng, sw.lat, centerX, centerY); | ||
| 473 | + | ||
| 474 | + // 找到四个角的最小和最大经纬度 | ||
| 475 | + const minLng = Math.min(topLeft.lng, topRight.lng, bottomLeft.lng, bottomRight.lng); | ||
| 476 | + const maxLng = Math.max(topLeft.lng, topRight.lng, bottomLeft.lng, bottomRight.lng); | ||
| 477 | + const minLat = Math.min(topLeft.lat, topRight.lat, bottomLeft.lat, bottomRight.lat); | ||
| 478 | + const maxLat = Math.max(topLeft.lat, topRight.lat, bottomLeft.lat, bottomRight.lat); | ||
| 479 | + | ||
| 480 | + const newBounds = new AMap.Bounds( | ||
| 481 | + [minLng, minLat], | ||
| 482 | + [maxLng, maxLat] | ||
| 483 | + ); | ||
| 484 | + | ||
| 485 | + // 更新图层 | ||
| 486 | + if (imageLayer.value) { | ||
| 487 | + map.value.remove(imageLayer.value); | ||
| 488 | + } | ||
| 416 | 489 | ||
| 417 | - console.log(`地图旋转: ${mapRotation.value}°`); | 490 | + imageLayer.value = new AMap.ImageLayer({ |
| 491 | + url: rotatedImageURL, | ||
| 492 | + bounds: newBounds, | ||
| 493 | + zooms: [17, 19], | ||
| 494 | + opacity: imageOpacity.value / 100 | ||
| 495 | + }); | ||
| 418 | 496 | ||
| 419 | - map.value.setRotation(mapRotation.value); | 497 | + map.value.add(imageLayer.value); |
| 498 | + }; | ||
| 420 | }; | 499 | }; |
| 421 | 500 | ||
| 422 | - | ||
| 423 | const onZoomChange = (value) => { // 调整地图图层 | 501 | const onZoomChange = (value) => { // 调整地图图层 |
| 424 | // map.value.setZoom(value); | 502 | // map.value.setZoom(value); |
| 425 | } | 503 | } | ... | ... |
-
Please register or login to post a comment