leaflet制作3D地图边界效果(js实现,css效果不好)

使用L.geoJSON方法添加地图边界,并且添加类名:

geoJSON(cityMap as any, {
    interactive: false,
    style: {
      fill: false,
      color: '#fff',
      weight: 3,
      pane: 'bottom',
      className: 'map-border',
    },
  });


leaflet添加geojson后的dom结构:
<svg>
        <g>
                <path class="map-border">


给边界添加3D效果:
 

  // 1. 获取 SVG 元素
  const svg = document.querySelector('div.leaflet-bottom-pane')?.children[0] as SVGSVGElement;

  // 2. 创建 <defs> 元素
  const defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs');

  // 3. 创建 <filter> 元素,并设置其属性
  const filter = document.createElementNS('http://www.w3.org/2000/svg', 'filter');
  filter.setAttribute('x', '-50%');
  filter.setAttribute('y', '-50%');
  filter.setAttribute('width', '200%');
  filter.setAttribute('height', '200%');
  filter.setAttribute('id', 'filter3D');

  // 4. 创建阴影的 feOffset
  const feOffset = document.createElementNS('http://www.w3.org/2000/svg', 'feOffset');
  feOffset.setAttribute('in', 'SourceAlpha');
  feOffset.setAttribute('dx', '-20');
  feOffset.setAttribute('dy', '20');
  feOffset.setAttribute('result', 'offset');

  // 5. 创建高斯模糊
  const feGaussianBlur = document.createElementNS('http://www.w3.org/2000/svg', 'feGaussianBlur');
  feGaussianBlur.setAttribute('in', 'offset');
  feGaussianBlur.setAttribute('stdDeviation', '0');
  feGaussianBlur.setAttribute('result', 'blur');

  // 6. 创建阴影填充
  const feFlood = document.createElementNS('http://www.w3.org/2000/svg', 'feFlood');
  feFlood.setAttribute('flood-color', '#051b45');
  feFlood.setAttribute('flood-opacity', '0.5');
  feFlood.setAttribute('result', 'color');

  // 7. 将模糊和颜色合成
  const feComposite1 = document.createElementNS('http://www.w3.org/2000/svg', 'feComposite');
  feComposite1.setAttribute('operator', 'in');
  feComposite1.setAttribute('in', 'color');
  feComposite1.setAttribute('in2', 'blur');
  feComposite1.setAttribute('result', 'shadow');

  // 8. 创建亮光效果
  const feFloodLight = document.createElementNS('http://www.w3.org/2000/svg', 'feFlood');
  feFloodLight.setAttribute('flood-color', '#ffffff');
  feFloodLight.setAttribute('flood-opacity', '0.2');
  feFloodLight.setAttribute('result', 'light');

  // 9. 创建亮光偏移
  const feOffsetLight = document.createElementNS('http://www.w3.org/2000/svg', 'feOffset');
  feOffsetLight.setAttribute('in', 'SourceAlpha');
  feOffsetLight.setAttribute('dx', '3');
  feOffsetLight.setAttribute('dy', '-3');
  feOffsetLight.setAttribute('result', 'offsetLight');

  // 10. 合并亮光和形状
  const feCompositeLight = document.createElementNS('http://www.w3.org/2000/svg', 'feComposite');
  feCompositeLight.setAttribute('operator', 'in');
  feCompositeLight.setAttribute('in', 'light');
  feCompositeLight.setAttribute('in2', 'offsetLight');
  feCompositeLight.setAttribute('result', 'highlightEffect');

  // 11. 合并所有效果
  const feMerge = document.createElementNS('http://www.w3.org/2000/svg', 'feMerge');

  const feMergeNode1 = document.createElementNS('http://www.w3.org/2000/svg', 'feMergeNode');
  feMergeNode1.setAttribute('in', 'shadow');

  const feMergeNode2 = document.createElementNS('http://www.w3.org/2000/svg', 'feMergeNode');
  feMergeNode2.setAttribute('in', 'highlightEffect');

  const feMergeNode3 = document.createElementNS('http://www.w3.org/2000/svg', 'feMergeNode');
  feMergeNode3.setAttribute('in', 'SourceGraphic');

  feMerge.appendChild(feMergeNode1);
  feMerge.appendChild(feMergeNode2);
  feMerge.appendChild(feMergeNode3);

  // 12. 将所有滤镜元素添加到 filter 中
  filter.appendChild(feOffset);
  filter.appendChild(feGaussianBlur);
  filter.appendChild(feFlood);
  filter.appendChild(feComposite1);
  filter.appendChild(feFloodLight);
  filter.appendChild(feOffsetLight);
  filter.appendChild(feCompositeLight);
  filter.appendChild(feMerge);

  // 13. 将 filter 添加到 defs 中
  defs.appendChild(filter);

  // 14. 将 defs 添加到 SVG 中
  svg.appendChild(defs);

  // 15. 获取 .map-border 类的 path 元素,并应用滤镜
  const path = document.querySelector('.map-border');
  path!.setAttribute('fill', '#0F4398');
  path!.setAttribute('filter', 'url(#filter3D)');

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值