OpenLayers水平镜像和垂直镜像

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.图片的旋转,顺时针为正,逆时针为负
4.图片的延迟加载问题一定要注意,尤其当代码没问题,但又地图上没效果的时候

  • 6
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AIGIS.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值