-
var items = [
{ title: 'X-rays', src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/9473/i-xrays.png' },
{ title: 'Worms', src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/9473/i-worms.png' },
{ title: 'Aurora', src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/9473/i-aurora.png' },
{ title: 'Angus', src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/9473/i-angus.png' },
{ title: 'Huitzi', src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/9473/i-huitzi.png' },
{ title: 'Dalí', src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/9473/i-dali.png' },
{ title: 'The Bride', src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/9473/i-bride.png' },
{ title: 'The Man', src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/9473/i-man.png' },
{ title: 'D', src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/9473/i-d.png' },
{ title: 'V', src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/9473/i-v.png' },
{ title: 'V II', src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/9473/i-v2.png' },
{ title: 'V III', src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/9473/i-v3.png' }
];
h1.intro [CSS+JS] clip hover effect
ul.items
each item in items
li.item
figure.figure
img.figure__img(src=item.src, title=item.title)
.figure__mask
figcaption.figure__figcaption= item.title
blockquote.info
| inspired from #[a(href="https://codepen.io/noeldelgado/") Noel Delgado]'s Pen #[a(href="https://codepen.io/noeldelgado/pen/PZJGLx/") SVG clip-path Hover Effect].
View Compiled
$text-color: #f5f5f5;
$mask-bgc: #3b3e46;
$mask-size: 800px;
$hole-size: 300px;
$img-size: 300px 200px;
@import "https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,600";
.items {
max-width: 1200px;
margin: 0 auto;
padding-left: 0;
font-family: 'Source Sans Pro', sans-serif;
font-weight: 900;
text-transform: uppercase;
font-size: 14px;
letter-spacing: 1px;
}
.item {
display: inline-block;
}
.figure {
position: relative;
width: nth($img-size, 1);
height: nth($img-size, 2);
overflow: hidden;
margin: 5px;
// fake border-radius for fixing (overflow: hidden + transform) bug
&::after {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
border-radius: 3px;
box-shadow: 0 0 0 5px #2f3238;
pointer-events: none;
}
}
.figure__img {
width: nth($img-size, 1);
height: nth($img-size, 2);
transform: scale(1.1);
transition: transform .3s;
pointer-events: none;
.item:hover & {
transform: scale(1);
}
}
.figure__figcaption {
position: absolute;
top: 50%;
left: 0;
right: 0;
transform: translateY(-50%);
opacity: .2;
pointer-events: none;
transition: opacity .15s;
.item:hover & {
opacity: 1;
}
}
.figure__mask {
position: absolute;
top: - $mask-size / 2;
left: - $mask-size / 2;
width: $mask-size;
height: $mask-size;
color: $mask-bgc;
border-radius: 50%;
box-shadow: inset 0 0 0 400px;
transition: box-shadow .3s;
pointer-events: none;
.item:hover & {
box-shadow: inset 0 0 0 ($mask-size - $hole-size)*.5;
}
}
// reset style
*,
*::before,
*::after {
box-sizing: border-box;
}
body {
position: relative;
margin: 0;
min-height: 100vh;
padding-top: 1px;
padding-bottom: 5rem;
text-align: center;
background-color: #2f3238;
color: $text-color;
}
.intro {
width: 80%;
max-width: 30rem;
padding-bottom: 1rem;
margin: .5em auto 1em;
text-transform: capitalize;
border-bottom: 1px dashed rgba($text-color, .3);
small {
display: block;
opacity: .5;
font-style: italic;
text-transform: none;
}
}
.info {
position: absolute;
bottom: 0;
right: 0;
margin: 1em;
font-size: .9em;
font-style: italic;
font-family: serif;
text-align: right;
opacity: .5;
a {
color: inherit;
}
}
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0,0,0,0);
border: 0;
}
View Compiled
let items = document.getElementsByClassName('item');
let masks = document.getElementsByClassName('figure__mask');
let calcTouchPos = ($pos, $item, $i) => {
let rect = $item.rect;
let x = ~~Math.min(Math.max($pos.clientX - rect.left, 0), 300);
let y = ~~Math.min(Math.max($pos.clientY - rect.top, 0), 200);
masks[$i].style.transform = `translate(${x}px, ${y}px)`;
};
let isSupportTouch = 'ontouchstart' in window;
[].forEach.call(items, (item, i) => {
item.addEventListener('mousemove', (e) => {
masks[i].style.transform = `translate(${e.offsetX}px, ${e.offsetY}px)`;
}, false);
if (isSupportTouch) {
item.addEventListener('touchstart', (e) => {
let pos = e.targetTouches[0];
let target = document.elementFromPoint(pos.clientX, pos.clientY);
item.rect = target.getBoundingClientRect();
});
item.addEventListener('touchmove', (e) => {
e.preventDefault();
calcTouchPos(e.targetTouches[0], item, i);
});
}
});
View Compiled
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.