目录
- 1.前言
- 2.概念介绍
- 2.1 旋转
- 2.2 水平镜像
- 2.3 垂直镜像
- 3.要素的镜像
- 3.1 镜像轴始终是水平的或者垂直的
- 3.2 镜像轴是任意角度
- 4.图片的镜像
- 5.总结
1.前言
最近项目中用到了要素和图片的水平镜像和垂直镜像功能。这些功能说难不难,说简单也不简单,就是稍微费点劲,这里记录一下。
2.概念介绍
有很多人把镜像和旋转混淆,但镜像的图形是不可能通过旋转得到的,我们这里来看一下二者的区别,直接上图。
2.1 旋转
2.2 水平镜像
2.3 垂直镜像
3.要素的镜像
3.1 镜像轴始终是水平的或者垂直的
明白了原理之后,那么要素的镜像就方便多了。不论是水平镜像还是垂直镜像,首先图形的坐标我们是知道的,然后以某一个位置为锚去计算就行了。比如,如果是水平镜像,那么只要计算出来新的纬度值就可以了,经度值不变。相应的,如果是垂直镜像,那么只要计算出来新的经度值,纬度值不变。值得一提的是,如果我们以图形的中心为锚去计算,那么图形看起来就像在原始位置做了一个翻转一样。
这种情况下的代码太简单了,所以我们直接略过代码,下面开始上一点难度,考虑一下旋转轴的角度。
3.2 镜像轴是任意角度
什么叫镜像轴是任意角度?我们还是以图片来展示一下:
想一想这种情况下的垂直镜像应该怎么实现?这种情况下就不能再向上面一样去计算了,因为要考虑角度。
所以我们的做法是,首先将获取到这个镜像轴的角度,然后将图形逆时针旋转到0度,做垂直镜像,然后将镜像后的图形,再顺时针旋转这个角度,就可以了。水平镜像同理。
当然了,要实现这种带角度的镜像,还可以通过矩阵运算,但是我觉得这种方式比较简单易懂,读者可以自行选择实现方式。
getMirror(feature){
// 给定的角度(逆时针为正,顺时针为负,角度为度数而不是弧度)
let angle = 30; // 示例角度
// 将角度转换为弧度,因为OpenLayers的旋转函数需要弧度作为单位
let angleInRadians = angle * Math.PI / 180;
// 获取要素的几何对象
let geometry = feature.getGeometry();
// 获取要素的中心点
let center = extent.getCenter(geometry.getExtent());
// 步骤1: 逆时针旋转要素(传入正值)
geometry.rotate(angleInRadians, center);
// 水平镜像
// geometry.scale(1, -1, center);
//垂直镜像
geometry.scale(-1, 1, center);
// 步骤3: 顺时针旋转要素(传入负值)
geometry.rotate(-angleInRadians, center);
return feature
},
4.图片的镜像
图片的镜像需要借助canvas来实现,我们来看下效果
let point = new Feature({
geometry:new Point([116,39])
})
let image = new Image()
image.src = '300.jpg'
let obj={
width:375,
height:300,
image:image,
angle:0,
horizontalMirroring:true,
// verticalMirroring:true,
}
point.setStyle(this.getPicMirrorStyle(obj));
getPicMirrorStyle(obj){
const canvas = document.createElement('canvas');
canvas.width = obj.width;
canvas.height = obj.height;
const con = canvas.getContext('2d');
//水平镜像
if(obj.horizontalMirroring){
con.translate(0,obj.height);
con.scale(1,-1);
}
//垂直镜像
if(obj.verticalMirroring){
con.translate(obj.width,0);
con.scale(-1,1);
}
// 图像存在延迟加载的问题,不能直接画
obj.image.onload = () => {
con.drawImage(obj.image, 0, 0, obj.width, obj.height);
};
return new Style({
image:new Icon({
img:canvas,
// src:"300.jpg",
crossOrigin:'anonymous',
imgSize:[obj.width,obj.height],
rotation:(obj.angle * Math.PI) / 180,
scale:0.5
})
})
},
5.总结
我们在本文中实现了要素和图片的垂直镜像和水平镜像。值得注意的是:
1.要素的旋转和图片的旋转都需要传入弧度值
2.要素的旋转,逆时针为正,顺时针为负
3.图片的旋转,顺时针为正,逆时针为负