Some time ago, I was experimenting with CSS3 transformations and transitions using Sass. Then, I decided to port these experiments into a Codepen to share it with the Internet community because I think that they are interesting.
The next experiment consists in a dynamic animation of a plane giving an effect of a paper being folded. To achieve this I have used just a DIV element in the HTML and CSS code using Sass. The animation can be modified in term of number of folds and the speed of each one changing some global variables in the Sass code.
It is important to remark, that the Sass code used is almost unreadable and complex besides of generating a bunch of CSS code when compiles. You should use it just to experiment, get fun coding and see the possibilities of Sass dynamically generating CSS transformations, but I don’t recommend you using a similar code in a real project in production.
If you make a fork of the project and you get something interesting too, I would request you to share it with the Internet community.
HTML code
<div id="fold"></div>
Sass code
/* ------------VARIABLES TO EDIT------------------ */
$folds: 6 // Number of folds
$time: 0.5 // Time of each fold animation
$back: #E25875 // Background color
$base: #EEE // Paper color
/* ----------------------------------------------- */
$darken: darken($base, 10)
$darken2: darken($base, 20)
$height: 75%
$width: 15%
html
height: 100%
body
background: linear-gradient(to bottom, $back, darken($back, 10))
height: 100%
margin: 0
padding: 0
position: relative
@function pow($b, $e)
$v: 1
@if $e > 0
@for $i from 1 through $e
$v: $v * $b
@return $v
@function foldSizes($step)
$even: $step % 2 == 0
$h: $height / if($even, pow(3, $step / 2), pow(3, ($step - 1) / 2))
$w: $width / if($even, pow(3, $step / 2 - 1), pow(3, ($step - 1) / 2))
@return $w, $h
@function getSizesSteps($steps)
$str: ""
@for $i from 1 to $steps
$state: if(($steps - $i + 1) % 2 == 0, "even", "odd")
$delay: (($i - 1) * 2) * $time
$sdelay1: (($i - 1) * 2) * $time
$sdelay2: (($i - 1) * 2 + 1) * $time
$str: $str + "center-" + $i + " " + ($time * 2) + "s " + $delay + "s forwards"
$str: $str + ",before-shadow-center-" + $state + " " + $time + "s " + $sdelay1 + "s forwards"
$str: $str + ",after-shadow-center-" + $state + " " + $time + "s " + ($sdelay1 + $time) + "s forwards"
@if $i < $steps - 1
$str: $str + ","
@return unquote($str)
@function getAnimations($prefix, $steps)
$str: ""
@for $i from 1 to $steps
$state: if(($steps - $i + 1) % 2 == 0, "even", "odd")
$delay: if($prefix == before, (($i - 1) * 2) * $time, (($i - 1) * 2 + 1) * $time)
$str: $str + $prefix + "-" + $state + " " + $time + "s " + $delay + "s forwards"
$str: $str + "," + $prefix + "-shadow-" + $state + " " + $time + "s " + $delay + "s forwards"
@if $i < $steps - 1
@if $prefix == after
$str: $str + ",after-end-" + $state + " " + $time + "s " + ($delay + $time) + "s forwards"
$str: $str + ","
@return unquote($str)
=fold-center($step)
$sizes: foldSizes($step)
height: nth($sizes, 2)
width: nth($sizes, 1)
=shadow-center($prefix, $even, $initial: true)
@if $prefix == before
background: linear-gradient(if($even, to right, to bottom), $darken2, $darken2, $base, $base, $base)
background-position: if($even, if($initial, 0, 100%), if($initial, 0 0, 0 100%))
@else
background: linear-gradient(if($even, to left, to top), $darken2, $darken2, $base, $base, $base)
background-position: if($even, if($initial, 100%, 0), if($initial, 0 100%, 0 0))
background-size: 200% 200%
=fold-before($even, $initial: true)
left: if($even, -100%, 0)
top: if($even, 0, -100%)
transform-origin: if($even, 100% 0, 0 100%)
transform: if($even, rotateY(if($initial, 180deg, 0deg)), rotateX(if($initial, -180deg, 0deg)))
=fold-after($even, $initial: true)
right: if($even, -100%, 0)
bottom: if($even, 0, -100%)
opacity: 1
transform: if($even, rotateY(if($initial, -180deg, 0deg)), rotateX(if($initial, 180deg, 0deg)))
=shadow-pages($prefix, $even, $initial: true)
@if $prefix == before
background: linear-gradient(if($even, to left, to top), $darken, $base, $base)
background-position: if($even, if($initial, 0, 100%), if($initial, 0 0, 0 100%))
@else
background: linear-gradient(if($even, to right, to bottom), $darken, $base, $base)
background-position: if($even, if($initial, 100%, 0), if($initial, 0 100%, 0 0))
background-size: 200% 200%
=create-fold($id, $steps)
$max: $steps + 1
@for $i from 1 to $max
$j: $steps - $i + 1
@keyframes center-#{$i}
0%,
100%
+fold-center($j)
$states: even odd
$sides: before after
@each $state in $states
$even: $state == even
@each $side in $sides
$before: $side == before
@keyframes #{$side}-#{$state}
@if $before
0%
+fold-before($even)
100%
+fold-before($even, false)
@else
0%
+fold-after($even)
100%
+fold-after($even, false)
@keyframes #{$side}-shadow-#{$state}
0%,
100%
+shadow-pages($side, $even)
50%
+shadow-pages($side, $even, false)
@keyframes #{$side}-shadow-center-#{$state}
0%
+shadow-center($side, $even)
100%
+shadow-center($side, $even, false)
@if $side == after
@keyframes after-end-#{$state}
0%,
100%
+fold-after(not $even)
background: $base
opacity: 0
##{$id}
animation: getSizesSteps($max)
background: $base
left: 50%
perspective: 1000
position: relative
top: 50%
transform: translate(-50%, -50%)
&::before,
&::after
content: ""
height: 100%
position: absolute
width: 100%
&::before
animation: getAnimations(before, $max)
z-index: 2
&::after
animation: getAnimations(after, $max)
transform-origin: 0 0
z-index: 1
+create-fold("fold", $folds)
Codepen
Ver el código en by (@elchininet) on CodePen.3
Exceptional work dude.
Looking forward to working my through this for some insight,
Thanks Bob, I’m glad that you like it 😉
In all seriousness – the sass code may be complex, but what in particular flags it up for you as a no in production ?
appears to perform reasonably and you could always support a basic fallback no?
The main flag is that it is a hard-to-read code and it would make hard for other developers make changes or improve it, but it will not break the page or anything like that. I made that warning because one should be careful with the setup, the generated code becomes bigger and bigger depending on the number of folds.
Regards!