Background Segment Effect
Today we’d like to share a little decorative effect with you that we’ve encountered on Filippo Bello’s Portfolio, maybe you’ve seen it. It’s a really neat way to add some jazz to background images. The idea is to replicate boxes from a background with the same background image and make these boxes move in perspective towards the viewer. Adding a fitting shadow and some parallax makes all this look quite interesting. Furthermore, we’re employing anime.js, the easy-to-use JavaScript animation library by Julian Garnier.
Have a look at the effect seen on Filippo’s portfolio:
The technique that we use for this effect is based on the CSS clip property. Although the technique seen on Filippo’s portfolio uses a different approach (background-size: cover combined with background-attachment: fixed), we found that the clip approach has more browser support, especially for Firefox which does not seem to like the cover/fixed combination.
If you’d like to understand how the CSS clip property works, have a look at Hugo’s article “Understanding the CSS Clip Property”. One of our tutorials also uses a clip-based technique and helps understand how to apply it: “Putting CSS Clip to Work: Expanding Overlay Effect”.
The Segment Effect
The script that we’ve built takes care of the basic functioning of the segment effect which includes a couple of adjustable options.
For the markup we simply need a division and a background image:
<div class="segmenter" style="background-image: url(img/3.jpg)"></div>
The script turns this into the following structure:
<div class="segmenter">
<div class="segmenter__background" style="background-image: url(img/3.jpg);"></div>
<div class="segmenter__pieces">
<div class="segmenter__piece-wrap">
<div class="segmenter__shadow" style="top: 80%; left: 10%; width: 30%; height: 20%"></div>
<div class="segmenter__piece" style="background-image: url(img/3.jpg); clip: rect(620.8px,357.6px,776px,89.4px)"></div>
</div>
<div class="segmenter__piece-wrap">
<div class="segmenter__shadow" style="top: 2%; left: 2%; width: 40%; height: 40%"></div>
<div class="segmenter__piece" style="background-image: url(img/3.jpg); clip: rect(15.52px,375.48px,325.92px,17.88px)"></div>
</div>
<div class="segmenter__piece-wrap">
<div class="segmenter__shadow" style="top: 30%; left: 60%; width: 30%; height: 60%"></div>
<div class="segmenter__piece" style="background-image: url(img/3.jpg); clip: rect(232.79px,804.5px,698.4px,536.4px)"></div>
</div>
<div class="segmenter__piece-wrap">
<div class="segmenter__shadow" style="top: 10%; left: 20%; width: 50%; height: 60%"></div>
<div class="segmenter__piece" style="background-image: url(img/3.jpg); clip: rect(77.6px,625.8px,543.19px,178.8px)"></div>
</div>
</div>
</div>
As you can see, the images becomes a division with a background image and all pieces are wrapped into the segmenter__pieces div. Each piece consists of an element for the shadow (if set) and an element for the image piece that has a clip defined based on the options input we define.
The styles needed for this to work are the following (vendor prefixes omitted):
.segmenter {
width: 100vw;
height: 100vh;
position: relative;
overflow: hidden;
}
.segmenter__background,
.segmenter__pieces,
.segmenter__piece-wrap,
.segmenter__piece-parallax,
.segmenter__piece {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
transform-style: preserve-3d;
}
.segmenter__piece-parallax {
transition: transform 0.2s ease-out;
}
.segmenter__pieces {
perspective: 400px;
}
.segmenter__background,
.segmenter__piece,
.segmenter {
background-size: cover;
background-repeat: no-repeat;
background-position: 50% 50%;
}
.segmenter__shadow {
position: absolute;
opacity: 0;
box-shadow: 0px 2px 15px rgba(0,0,0,0.7);
}
Note how the pieces all have the size of the full wrapper; it’s the clip that cuts them to the correct size and position. This element is hence a bit restricted as to what styles we can apply to it, i.e. we can’t just add a box shadow because the element is clipped.
Let’s have a look at the default options:
Segmenter.prototype.options = {
// Number of pieces.
pieces: 4,
// Show pieces already styled.
renderOnLoad: false,
// Add an element for the shadow.
shadows: true,
// Animations for the shadow (valid properties: opacity, translateX, translateY).
shadowsAnimation: {
opacity: 1,
// translateX: 20,
// translateY: 20
},
// Parallax effect for the pieces.
parallax: false,
// Movements for the parallax effect.
parallaxMovement: {min: 10, max: 40},
// Animation for the pieces (valid properties: duration, easing, delay, opacity, translate[XYZ]).
animation: {
duration: 1500,
easing: 'easeOutQuad',
delay: 0, // Delay increment per piece.
// opacity: 0.5,
translateZ: {min: 10, max: 65}, // We can also use an integer for a specific value.
// translateX: {min: -100, max: 100}, // We can also use an integer for a specific value.
// translateY: {min: -100, max: 100} // We can also use an integer for a specific value.
},
// Callbacks
onAnimationComplete: function() { return false; },
onAnimationStart: function() { return false; },
// The positions of the pieces in percentage values.
// We can also use random values by setting options.positions to "random".
positions: [
{
top: 80, left: 10, width: 30, height: 20
},
{
top: 2, left: 2, width: 40, height: 40
},
{
top: 30, left: 60, width: 30, height: 60
},
{
top: 10, left: 20, width: 50, height: 60
}]
};
The options allow for a variety of looks, including the extreme abuse of the parallax effect to a psychedelic absurdum (in combination with several same-sized pieces):
We hope you enjoy this little effect and find it useful!
References and Credits
- Inspired by the effect seen on Filippo Bello’s Portfolio
- Animations powered by anime.js, the easy-to-use JavaScript animation library by Julian Garnier.
- We’re using imagesLoaded by Dave DeSandro.
- The images used in the demos are from Unsplash.com
Browser Support:
- ChromeSupported
- FirefoxSupported
- Internet ExplorerSupported from version 11
- SafariSupported
- OperaSupported
Background Segment Effect was written by Mary Lou and published on Codrops.
LEAVE A REPLY
You must be logged in to post a comment.