CSS clip-path с использованием всего SVG

Я пытаюсь использовать свойство clip-path в css, чтобы замаскировать размытое изображение в сетке, в основном, чтобы получить эффект размытия стекла, который вы видите, например, в Windows 10, а также в других местах.

Структура, которая у меня есть:

<div>
    <div><img src="img/not_blurred.jpg"/></div>
    <div><img src="img/blurred.jpg"/></div>
    <div>
        <span>Some text</span>
    </div>
</div>

Чтобы размытое изображение покрывало div, содержащий «Некоторый текст», сохраняя при этом пропорции нижнего изображения, я думал об использовании SVG clipPath с SVG, который покрывает весь div, содержащий «Некоторый текст».

<div>
    <div><img src="img/not_blurred.jpg"/></div>
    <div><img src="img/blurred.jpg"/></div>
    <div>
        <svg width="100%" height="100%">
            <defs>
                <clipPath id="test" clipPathUnits="objectBoundingBox">
                    <rect width="1" height="1"></rect>
                </clipPath>
            </defs>
        </svg>
        <span>Some text</span>
    </div>
</div>

Но проблема в том, что clippath не получает в качестве источника координату (0,0) SVG, а (0,0) страницы. Я создал для этого ручку, если вы хотите посмотреть https://codepen.io/Kerruba/pen/MBveoW

Возможно, я что-то неправильно понимаю, но я пробовал документировать это в Интернете и не смог найти ответа.

Любая помощь будет очень признательна


person Kerruba    schedule 26.07.2018    source источник


Ответы (1)


К сожалению, я не смог найти решения этой проблемы так, как я ее определил. Но с помощью JS и полигонального clip-path я смог воссоздать эффект, который искал.

Вот как:

HTML

<div class="grid glass">
    <div class="bg_normal">
        <img src="https://images.pexels.com/photos/991012/pexels-photo-991012.jpeg?cs=srgb&dl=above-aerial-aerial-view-991012.jpg&fm=jpg" alt="">
      </div>
      <div class="bg_blur">
        <img src="https://images.pexels.com/photos/991012/pexels-photo-991012.jpeg?cs=srgb&dl=above-aerial-aerial-view-991012.jpg&fm=jpg" alt="">
      </div>
      <div class="title">
        <h1>The greatest place ever!</h1>
      </div>
</div>

CSS

* {
  box-sizing: border-box;
}

html, body {
  height: 100%;
  margin: 0;
  overflow: hidden;
}

.grid {
  min-width: 100vw;
  min-height: 100vh;
  display: grid;
  grid-template-rows: repeat(4, 1fr);
  grid-auto-columns: unset;
  grid-gap: 0;
}


.bg_normal, .bg_blur {
  grid-row: 1 / -1;
  grid-column: 1;
}

.bg_normal img, .bg_blur img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.bg_blur img{
   filter: blur(5px);
}

.title {
  grid-row: 2/-2;
  grid-column: 1;
  z-index: 1;
  background: rgba(200, 200, 200, 0.3);
  margin: 0;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 3vmax;
  box-shadow: 0 5px 10px rgba(0,0,0,0.2);
  font-family: 'Jura', sans-serif;
  text-shadow: 0 5px 10px HSL(172, 27%, 39%);
}

Javascript

function setClipPath(target, source) {
    let sbox = source.getBoundingClientRect();
    let [xmin, ymin, xmax, ymax] = [ sbox.left, sbox.top, sbox.right, sbox.bottom];
    target.style.clipPath = `polygon(${xmin}px ${ymin}px, ${xmin}px ${ymax}px, ${xmax}px ${ymax}px, ${xmax}px ${ymin}px
    )`;

}
let blur_background = document.querySelector(".glass .bg_blur");
let text_overlay = document.querySelector(".glass .title");

setClipPath(blur_background, text_overlay);

window.onresize = function(event) {
    setClipPath(blur_background, text_overlay);
}

Здесь я подготовил перо, чтобы показать эффект https://codepen.io/Kerruba/pen/MBveoW?editors=0101

Любые комментарии о том, как улучшить это, или проблемы с макросами, которые вы обнаружите, дайте мне знать в комментариях.

person Kerruba    schedule 29.07.2018