官网demo地址:
Layer Spy
这篇实现了鼠标跟随望远镜效果,鼠标移动时绘制一个圆形的剪裁区剪裁上层图层。
container.addEventListener("mousemove", function (event) {mousePosition = map.getEventPixel(event);map.render();});container.addEventListener("mouseout", function () {mousePosition = null;map.render();});
通过map.render()触发prerender,postrender两个函数来完成裁剪,其原理和上篇的卷帘效果一样。
上篇地址:
完整代码:
<template><div class="box"><h1>Layer Spy</h1><div id="map" class="map"></div></div>
</template><script>
import StadiaMaps from "ol/source/StadiaMaps.js";
import Map from "ol/Map.js";
import TileLayer from "ol/layer/Tile.js";
import View from "ol/View.js";
import XYZ from "ol/source/XYZ.js";
import { fromLonLat } from "ol/proj.js";
import { getRenderPixel } from "ol/render.js";
export default {name: "",components: {},data() {return {map: null,};},computed: {},created() {},mounted() {const container = document.getElementById("map");const layer = new TileLayer({source: new StadiaMaps({layer: "stamen_terrain_background",}),zIndex: 2,});const map = new Map({layers: [layer,new TileLayer({source: new StadiaMaps({layer: "outdoors",}),}),],target: "map",view: new View({center: [0, 0],zoom: 2,projection: "EPSG:4326",}),});let radius = 75;document.addEventListener("keydown", function (evt) {if (evt.key === "ArrowUp") {radius = Math.min(radius + 5, 150);map.render();evt.preventDefault();} else if (evt.key === "ArrowDown") {radius = Math.max(radius - 5, 25);map.render();evt.preventDefault();}});let mousePosition = null;container.addEventListener("mousemove", function (event) {mousePosition = map.getEventPixel(event);map.render();});container.addEventListener("mouseout", function () {mousePosition = null;map.render();});layer.on("prerender", function (event) {const ctx = event.context;ctx.save();ctx.beginPath();if (mousePosition) {const pixel = getRenderPixel(event, mousePosition);const offset = getRenderPixel(event, [mousePosition[0] + radius,mousePosition[1],]);const canvasRadius = Math.sqrt(Math.pow(offset[0] - pixel[0], 2) + Math.pow(offset[1] - pixel[1], 2));ctx.arc(pixel[0], pixel[1], canvasRadius, 0, 2 * Math.PI);ctx.lineWidth = (5 * canvasRadius) / radius;ctx.strokeStyle = "rgba(0,0,0,0.5)";ctx.stroke();}ctx.clip();});layer.on("postrender", function (event) {const ctx = event.context;ctx.restore();});},methods: {},
};
</script><style lang="scss" scoped>
#map {width: 100%;height: 500px;
}
.box {height: 100%;
}</style>