VHS Filter
A Pen by Sam Beckham on CodePen.
<h1>VHS Filter</h1> | |
<div class="wrapper"> | |
<img src="https://source.unsplash.com/200x200/?i" class="js-vhs-filter" /> | |
<img src="https://source.unsplash.com/200x200/?got" class="js-vhs-filter" /> | |
<img src="https://source.unsplash.com/200x200/?love" class="js-vhs-filter" /> | |
<img src="https://source.unsplash.com/200x200/?for" class="js-vhs-filter" /> | |
<img src="https://source.unsplash.com/420x200/?those" class="js-vhs-filter" /> | |
<img src="https://source.unsplash.com/200x200/?who" class="js-vhs-filter" /> | |
<img src="https://source.unsplash.com/200x200/?were" class="js-vhs-filter" /> | |
<img src="https://source.unsplash.com/200x200/?born" class="js-vhs-filter" /> | |
<img src="https://source.unsplash.com/200x200/?in" class="js-vhs-filter" /> | |
<img src="https://source.unsplash.com/200x200/?the" class="js-vhs-filter" /> | |
<img src="https://source.unsplash.com/200x200/?80s" class="js-vhs-filter" /> | |
</div> | |
<svg> | |
<filter id="r"><feColorMatrix | |
type="matrix" | |
values="1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 "/> | |
</filter> | |
<filter id="g"><feColorMatrix | |
type="matrix" | |
values="0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 "/> | |
</filter> | |
<filter id="b"><feColorMatrix | |
type="matrix" | |
values="0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 "/> | |
</filter> | |
</svg> |
console.clear(); | |
const images = document.querySelectorAll(".js-vhs-filter"); | |
images.forEach(image => VHSify(image)); | |
function VHSify(image) { | |
if ( | |
!CSS.supports("mix-blend-mode", "screen") || | |
!CSS.supports("filter", "url()") | |
) { | |
return; | |
} | |
const container = document.createElement("div"); | |
const images = RGBImages(image); | |
images.forEach(image => container.appendChild(image)); | |
container.classList.add("vhs-filter"); | |
image.replaceWith(container); | |
} | |
function RGBImages(image) { | |
const colors = ["r", "g", "b"]; | |
const images = colors.map(color => { | |
const img = image.cloneNode(); | |
img.classList.add(`vhs-filter__${color}`); | |
return img; | |
}); | |
return images; | |
} |
.vhs-filter { | |
overflow: hidden; | |
position: relative; | |
img { display: block; } | |
&__r, | |
&__g { | |
left: 0; | |
mix-blend-mode: screen; | |
position: absolute; | |
top: 0; | |
transition: transform .4s; | |
z-index: 1; | |
} | |
&__r { | |
filter: url('#r'); | |
transform: translate(1px, 2px); | |
} | |
&__g { | |
filter: url('#g'); | |
transform: translate(-2px, -1px); | |
} | |
&__b { | |
filter: url('#b'); | |
} | |
&:hover { | |
// box-shadow: none; | |
.vhs-filter__r, | |
.vhs-filter__g { | |
transform: translate(0); | |
} | |
} | |
} | |
html { | |
color: #333; | |
text-align: center; | |
} | |
.wrapper { | |
display: flex; | |
justify-content: center; | |
flex-wrap: wrap; | |
margin: 0 auto; | |
max-width: 100%; | |
width: 900px; | |
> div { | |
margin: 10px; | |
} | |
} | |
h1 { | |
display: block; | |
margin: 1em auto; | |
} | |
img { | |
max-width: 100%; | |
} |
A Pen by Sam Beckham on CodePen.