Hace un tiempo atrás estuve experimentando con transformaciones y transiciones en CSS3 usando para ello Sass. Decidí entonces pasar estos experimentos a un Codepen para compartirlo con la comunidad porque me parecieron intersantes.
El siguiente experimento consiste en la animación dinámica de un plano dando el efecto de un papel plegado. Para lograrlo solo he utilizado un elemento DIV en el HTML y código CSS usando Sass. La animación puede ser variada en cuanto a cantidad de dobleces y la velocidad de cada doblez modificando unas variables globales en Sass.
Es importante aclarar que el código Sass es ilegible y complejo de leer aparte de generar una ingente cantidad de código CSS al compilar. Solo deberías utilizarlo para experimentar, divertirte codificando y ver las posibilidades de Sass generando transformaciones dinámicamente, pero no te recomendaría que usaras un código similar para un proyecto en producción.
Si haces algún fork del proyecto y logras algo que crees que pudiera ser interesante también te agradecería que lo compartieras con la comunidad.
Código HTML
<div id="fold"></div>
Código Sass
/* ------------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
Puedes situar fragmentos de código dentro de etiquetas <pre></pre> y código HTML o XML entre etiquetas <xmp></xmp>.