Если возможно анимировать пикселизацию изображения без холста, используя только CSS - PullRequest
1 голос
/ 04 июня 2019

Таким образом, вы можете получить пикселизацию в CSS, выполнив следующие действия:

  • Установите background-image на очень маленькое изображение (скажем, 50px или 100px).
  • Установить image-rendering: pixelated на элемент.

Это даст вам пиксельный вид.

Теперь я хотел бы оживить это, заменив «очень маленькое изображение» большим изображением после завершения загрузки браузером:

let img = new Image()
img.src = largeVersion
img.onload = function(){
  // set css background-image to the new image perhaps, not sure...      
}

Проблема двоякая.

  1. Я хочу, чтобы background-image использовал background-size: cover, чтобы он правильно заполнял элемент контейнера. Таким образом, вы не можете использовать фоновый размер в любой пиксельной анимации.
  2. transform: scale(0.1) (чтобы приблизиться к исходному размеру пикселизации) не работает, потому что масштабирует весь элемент.

Я хотел бы сделать что-то вроде этого: анимировать transform: scale(x), чтобы перейти от пиксельного изображения 50 пикселей к непиксельному изображению 2000 пикселей, за 0,3 или 0,5 секунды. Но это не работает. Я подумал, может быть, используя background-size, но это тоже не работает из-за ограничения.

Интересно, есть ли способ сделать это?

Я видел это , который делает пикселизацию с помощью canvas. Хотите знать, если нет другого решения, которое работает без использования JS / canvas.

<style>
  div {
    background-size: cover;
    background-repeat: no-repeat;
    background-position: center center;
  }
</style>
<div style='background-image: url(/100px.jpg)'></div>

1 Ответ

1 голос
/ 05 июня 2019

Вы можете сделать пикселизацию с помощью фильтра SVG.Затем вы можете анимировать фильтр.чтобы использовать фильтр на фоне div, вы просто делаете фильтр: url(#filterid)

вместе это выглядит так:

#myDiv::before{
content:"";
position:absolute;
top:0;
left:0;
width:100%;
height:100%;
filter:url(#pixelate);
background-size:cover;
background-image:url(https://images.unsplash.com/photo-1475724017904-b712052c192a?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2850&q=80)

}

#myDiv {
  position:relative;
  width:350px;
  height:250px;
}

.inside {
  position: relative;
}
<div id="myDiv"> <div class="inside"><h1>Hello</h1></div> </div>
<svg>
  <filter id="pixelate" x="0" y="0">
    <feFlood x="4" y="4" height="1" width="1" />
    <feComposite id="composite1" width="10" height="10" />
    <feTile result="a" />
    <feComposite in="SourceGraphic" in2="a" operator="in" />
    <feMorphology id="morphology" operator="dilate" radius="5" />
  </filter>

  <animate xlink:href="#composite1" id="anim-width" 
    attributeName="width" from="40" to="10" dur=".8s"
    fill="freeze" />  
  <animate xlink:href="#composite1" id="anim-height" 
    attributeName="height" from="40" to="10" dur=".8s"
    fill="freeze" />
  <animate xlink:href="#morphology" id="anim-radius" 
    attributeName="radius" from="20" to="5" dur=".8s"
    fill="freeze"/>
</svg>

Обратите внимание, что мне пришлось создать внутренний div и применить фон к псевдоэлементу ::before, но "скоро" это станет ненужным, когда поддержкаиз backdrop-filter улучшается.

ссылки:

Pixelate SVG-эффект: https://codesandbox.io/s/km3opvn6yv

Анимируйте SVG-фильтр: https://codepen.io/chriscoyier/pen/dPRVqL

фон-фильтр: https://developer.mozilla.org/en-US/docs/Web/CSS/backdrop-filter

...