Skip to content

Instantly share code, notes, and snippets.

@CodeMyUI
Created February 10, 2020 22:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save CodeMyUI/26c2ac6acce7ef2fef4acba950658830 to your computer and use it in GitHub Desktop.
Save CodeMyUI/26c2ac6acce7ef2fef4acba950658830 to your computer and use it in GitHub Desktop.
VHS Filter
<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%;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment