vue3+ts+openlayers实现卷帘效果

在这里插入图片描述
实现思路:
1.加载layer的时候通过裁剪只加载一部分
2.设置一个变量记录当前卷帘图层所占的百分比
3.改变拉杆的位置时,记录变量随拉杆变化的值(拉杆距离左侧的百分比)
4。通过裁剪设置图层的大小即可
实现代码:

<template>
  <div id="map" @mouseup="Mouseup" @mousemove="MouseMove" class="map_cotainer">
    <div class="swiper" :style="{ left: swiperValue + '%' }" @mousedown="Mousedown" ref="swiperControlDom">
    </div>
  </div>
</template>

<script setup lang='ts'>
import { onMounted, ref } from 'vue';
import Map from 'ol/Map.js';
import View from 'ol/View';
import { fromLonLat } from 'ol/proj';
import TileLayer from 'ol/layer/Tile.js';
import XYZ from 'ol/source/XYZ.js';
import Control from "ol/control/Control";

const swiperControlDom = ref(null);
let swiperValue = ref(50)
let startX: number = 0;
let currentX: number = 0;
let map: Map
let swipeLayer: any
onMounted(() => {
  //底图图层
  const baseLayer = new TileLayer({
    source: new XYZ({
      url: 'http://wprd0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&style=7&x={x}&y={y}&z={z}'
    }),
  })
  //卷帘图层
  swipeLayer = new TileLayer({
    source: new XYZ({
      url: 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}'
    }),
  })
  map = new Map({
    target: 'map',
    layers: [baseLayer],
    view: new View({
      center: fromLonLat([114.30, 30.50]),
      zoom: 10
    }),
    controls: []
  });
  map.addLayer(swipeLayer)
  setSwipeLayer(swipeLayer)
  const rollerShutter = new Control({
    element: swiperControlDom.value!
  });
  map.addControl(rollerShutter);
});

let isMoving = ref(false);
const Mousedown = (event: any) => {
  isMoving.value = true;
  startX = event.clientX || event.touches[0].clientX;
  currentX = startX;
};
const Mouseup = () => {
  isMoving.value = false
}
const MouseMove = (event: any) => {
  if (isMoving.value) {
    const deltaX = (event.clientX || event.touches[0].clientX) - currentX;
    currentX = event.clientX || event.touches[0].clientX;
    swiperValue.value += (deltaX / window.innerWidth) * 100;
  }
}

function setSwipeLayer(swipeLayer: any) {
  if (swipeLayer) {
    swipeLayer.on("prerender", prerender);
    swipeLayer.on("postrender", postrender);
  }
}
function prerender(e: any) {
  const ctx = e.context;
  const hOrw = ctx.canvas.width;
  const nVal = (hOrw * swiperValue.value) / 100; //根据分割线显示
  ctx.save();
  ctx.beginPath();
  ctx.rect(0, 0, nVal, ctx.canvas.height);
  ctx.clip(); // 裁剪
  map.render();
}
function postrender(e: any) {
  const ctx = e.context;
  ctx.restore();
}
/**
 * 取消卷帘时调用该方法
 */
// function unsetSwipeLayer() {
//   if (swipeLayer) {
//     swipeLayer.un("prerender", prerender);
//     swipeLayer.un("postrender", postrender);
//     swipeLayer = null;
//   }
// }
</script>
<style scoped>
.map_cotainer {
  width: 100%;
  height: 95vh;
  position: relative;
}

.swiper {
  width: 10px;
  height: 95vh;
  position: absolute;
  z-index: 9999;
  transform: translate(-50%);
  background-color: #ffffff;
  cursor: pointer;
}
</style>

感谢您的关注,全部示例代码加v获取——
在这里插入图片描述

  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值