hookehuyr

fix

<!--
* @Date: 2025-01-22 11:40:12
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2025-03-05 10:39:58
* @LastEditTime: 2025-03-05 11:21:28
* @FilePath: /map-demo/src/views/mapCutter.vue
* @Description: 文件描述
-->
......@@ -419,7 +419,7 @@ const imageRotation = ref(0);
// 修改 rotateMap 方法,只旋转图片
const rotateMap = (deltaAngle) => {
if (!imageLayer.value || !imageURL.value || !originalBounds.value || !originalAspectRatio.value) return;
if (!imageLayer.value || !imageURL.value || !bounds.value) return;
imageRotation.value = (imageRotation.value + deltaAngle) % 360;
......@@ -430,8 +430,10 @@ const rotateMap = (deltaAngle) => {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d', { alpha: true });
// 提高Canvas分辨率
const scaleFactor = 2;
// 获取当前的边界
const currentBounds = bounds.value;
const sw = currentBounds.getSouthWest();
const ne = currentBounds.getNorthEast();
// 计算旋转后的画布大小
const angleRad = (imageRotation.value * Math.PI) / 180;
......@@ -439,27 +441,19 @@ const rotateMap = (deltaAngle) => {
const sinAngle = Math.abs(Math.sin(angleRad));
// 使用更精确的计算方式
const newWidth = Math.ceil((img.width * cosAngle + img.height * sinAngle) * scaleFactor);
const newHeight = Math.ceil((img.height * cosAngle + img.width * sinAngle) * scaleFactor);
const newWidth = Math.ceil((img.width * cosAngle + img.height * sinAngle));
const newHeight = Math.ceil((img.height * cosAngle + img.width * sinAngle));
// 设置高分辨率画布
canvas.width = newWidth;
canvas.height = newHeight;
canvas.style.width = `${newWidth / scaleFactor}px`;
canvas.style.height = `${newHeight / scaleFactor}px`;
// 清除画布背景
ctx.clearRect(0, 0, newWidth, newHeight);
// 设置更高质量的图像平滑
// 优化渲染上下文
ctx.imageSmoothingEnabled = true;
ctx.imageSmoothingQuality = 'high';
// 应用分辨率缩放
ctx.scale(scaleFactor, scaleFactor);
// 移动到画布中心点
ctx.translate(newWidth / (2 * scaleFactor), newHeight / (2 * scaleFactor));
// 应用变换矩阵
ctx.translate(canvas.width / 2, canvas.height / 2);
// 使用精确的旋转角度
ctx.rotate(angleRad);
......@@ -476,65 +470,22 @@ const rotateMap = (deltaAngle) => {
// 获取高质量的旋转后图片URL
const rotatedImageURL = canvas.toDataURL('image/png', 1.0);
// 基于原始边界计算旋转后的边界
const sw = originalBounds.value.getSouthWest();
const ne = originalBounds.value.getNorthEast();
// 计算新的边界,保持图片大小不变
const currentWidth = ne.lng - sw.lng;
const currentHeight = ne.lat - sw.lat;
const centerLng = (sw.lng + ne.lng) / 2;
const centerLat = (sw.lat + ne.lat) / 2;
// 计算四个角的经纬度
const calculateCorner = (x, y, centerX, centerY) => {
const angle = imageRotation.value * Math.PI / 180;
const rotatedX = centerX + (x - centerX) * Math.cos(angle) - (y - centerY) * Math.sin(angle);
const rotatedY = centerY + (x - centerX) * Math.sin(angle) + (y - centerY) * Math.cos(angle);
return { lng: rotatedX, lat: rotatedY };
};
// 以图片中心点为基准
const centerX = centerLng;
const centerY = centerLat;
const topLeft = calculateCorner(sw.lng, ne.lat, centerX, centerY);
const topRight = calculateCorner(ne.lng, ne.lat, centerX, centerY);
const bottomLeft = calculateCorner(sw.lng, sw.lat, centerX, centerY);
const bottomRight = calculateCorner(ne.lng, sw.lat, centerX, centerY);
// 找到四个角的最小和最大经纬度
const minLng = Math.min(topLeft.lng, topRight.lng, bottomLeft.lng, bottomRight.lng);
const maxLng = Math.max(topLeft.lng, topRight.lng, bottomLeft.lng, bottomRight.lng);
const minLat = Math.min(topLeft.lat, topRight.lat, bottomLeft.lat, bottomRight.lat);
const maxLat = Math.max(topLeft.lat, topRight.lat, bottomLeft.lat, bottomRight.lat);
// 计算旋转后的图片宽度和高度
const rotatedWidth = maxLng - minLng;
const rotatedHeight = maxLat - minLat;
// 以左下角为基准,计算新的右上角坐标
let newNeLng = bottomLeft.lng + rotatedWidth;
let newNeLat = bottomLeft.lat + rotatedHeight;
// 调整新的右上角坐标,确保图片完全显示在可视范围内
if (newNeLng > ne.lng) {
newNeLng = ne.lng;
}
if (newNeLat > ne.lat) {
newNeLat = ne.lat;
}
const newBounds = new AMap.Bounds(
[centerLng - currentWidth / 2, centerLat - currentHeight / 2],
[centerLng + currentWidth / 2, centerLat + currentHeight / 2]
);
// 更新图层
if (imageLayer.value) {
map.value.remove(imageLayer.value);
}
// 使用计算出的最小和最大经纬度创建新的边界,确保图片完整显示
let newBounds = new AMap.Bounds(
[minLng, minLat],
[maxLng, maxLat]
);
// 更新当前边界值
bounds.value = newBounds;
imageLayer.value = new AMap.ImageLayer({
url: rotatedImageURL,
bounds: newBounds,
......@@ -543,7 +494,7 @@ const rotateMap = (deltaAngle) => {
});
map.value.add(imageLayer.value);
// 移除FIXME注释,旋转后的图片位置已经通过新的边界计算方式修复
bounds.value = newBounds;
};
};
......