Как прозрачно замаскировать объект, чтобы был виден только фон?

Цель

Я хотел бы создать анимированный многоугольник, части которого обрезаны/вырезаны/замаскированы, чтобы слой/элемент/фон под ним можно было увидеть следующим образом:

Анимированный многоугольник с маской, показывающей фон

Я создал анимацию с преобразованием CSS3. Это вращающийся блок, который выглядит так, будто его нижняя часть срезается во время движения. Я хотел бы, чтобы обрезанная часть показывала, что на самом деле находится за/под вращающимся блоком (то есть его фон).

Что я пробовал

Иллюзорное решение

Для одноцветных фонов вы можете просто добавить фигуру поверх анимации, чтобы создать иллюзию обрезания.

Анимированный многоугольник с иллюзорной маской с одноцветным фоном

Это явно не работает с изображениями:

Анимированный многоугольник с маской иллюзии не работает на обычном фоне

Ограниченное решение

Если вам нужно отрезать стороны прямоугольной формы, вы можете сделать это с помощью родительского элемента, но это имеет очевидные ограничения. Как сделать что-то подобное, но с произвольным полигоном? Можно ли маскировать в CSS?

body {
  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAYAAADEUlfTAAAAG0lEQVQYV2NMqL7ty4ADMIIkF7SqbsYmP+gkAbAbGgsk/ddhAAAAAElFTkSuQmCC);
}

.center {
  width: 200px;
  margin: 0 auto;
  padding-top: 50px;
  height: 100px;
  overflow: hidden;
}

.block {
  height: 100px;
  width: 100px;
  background-color: red;
  z-index: -1;
  transition: transform 1000s 0s linear;
  margin-left: 50px;
}

@keyframes rotating {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}

.rotate {
  animation: rotating 2s linear infinite;
}
<div class="center">
  <div class="block rotate"></div>
</div>


person totymedli    schedule 22.06.2014    source источник
comment
Похоже, что webkit должен решить вашу проблему с помощью свойства css -webkit-clip-path. jsfiddle.net/DpfW7/3 Но, к сожалению, он полностью удаляет объект, когда начинает анимацию. re все еще может использовать это без анимации.   -  person Wezelkrozum    schedule 23.06.2014
comment
background-position также является подсказкой: jsfiddle.net/DpfW7/4, что очень близко приближает к цели , отсутствует обложка...   -  person G-Cyrillus    schedule 23.06.2014


Ответы (3)


чтобы активировать z-индекс, вам нужно сбросить положение: относительное, фиксированное или абсолютное.

ДЕМО

#mask {
    height: 100px;
    width: 100px;
    background-color: white;
    z-index: 1;
    position:relative;/* to trigger z-index */
}

Чтобы выглядеть как в последнем примере, background-position может быть эффективным. Демо-окно отрезано от фона

в основном:

body {
    background: url('http://takeinsocialmedia.com/wp-content/uploads/2014/02/cute-kitten-images-photos-0223204033.jpg') fixed;
    background-size:100vw auto;
    background-repeat: no-repeat;
}

#mask {
    height: 100px;
    width: 100px;
    background:url('http://takeinsocialmedia.com/wp-content/uploads/2014/02/cute-kitten-images-photos-0223204033.jpg') fixed;
    background-size:100vw auto;
    z-index: 1;
    position:relative;
}

К сожалению, это не сработает с background-size:cover;, так как body и #mask имеют разный размер. background-size нужно будет установить с помощью JavaScript onload и onresize для #mask.

person G-Cyrillus    schedule 22.06.2014
comment
Вы, вероятно, неправильно поняли мой вопрос. У меня нет проблем с z-index. Белая коробка должна быть поверх красной. Это то, что обрезает нижнюю часть. Моя проблема в том, что белая коробка должна быть прозрачной, но при этом обрезать нижнюю часть красной коробки. См. решение Wezelkrozums, которое работает, но, к сожалению, только для этого конкретного примера. - person totymedli; 23.06.2014
comment
@totymedli ах, ладно, я думал, ты имеешь дело с z-индексом, который не запускается должным образом. Для того, что вы ищете, обычно используется background-position:fixed. Это работает нормально, но здесь обложка размера фона создает проблему, тело и маска не имеют одинакового размера. скомпрометированным может быть использование единиц vw. jsfiddle.net/DpfW7/4 . В противном случае вам нужно будет использовать javascript для получения высоты и ширины, чтобы адаптировать размер фона для #mask, чтобы он соответствовал размеру фона тела. ... - person G-Cyrillus; 23.06.2014
comment
Я тоже думал об этом решении. Но падает очень легко. Отзывчивый дизайн, динамический контент, всего несколько вещей, которые очень легко испортить. - person totymedli; 23.06.2014
comment
@totymedli На мой взгляд, у вас остался полный SVG или bg-position + javascript, взгляните на clip() css ?. удачи - person G-Cyrillus; 23.06.2014
comment
Да, я тоже думал об анимированном SVG, но там у меня такая же ситуация. Я не знаю, есть ли у меня лучшие варианты там. Тем не менее ваше решение является тем, которое в настоящее время наиболее близко к тому, что я хочу. - person totymedli; 23.06.2014

Вы пытались сделать белое поле невидимым с большим z-индексом, чем красное поле?

person DareDev1l    schedule 22.06.2014
comment
Таким образом, обрезка исчезла. Тогда в чем смысл маскировки? - person totymedli; 23.06.2014
comment
моя первая мысль тоже, но потом я снова прочитал вопрос... :) - person sinisake; 23.06.2014

Вот: http://jsfiddle.net/QxG74/2/ Симпатичная версия комплекта: http://jsfiddle.net/DpfW7/1/

Дайте центральному div высоту 100 пикселей и установите скрытое переполнение. Таким образом, вращающийся квадрат обрезается снизу.

#center {
   width: 200px;
   height: 100px;
   overflow: hidden;
}
person Wezelkrozum    schedule 22.06.2014
comment
Спасибо, это решение для этого конкретного примера. Вероятно, первоначальный пример был не лучшей демонстрацией. Смотрите мое редактирование: оно должно работать, даже если белый блок находится внутри вращающегося треугольника или если это круг. - person totymedli; 23.06.2014