Efecto carrusel de cortes de imagen.

Prefacio

Cuando visité un determinado sitio web sin querer, me sentí profundamente atraído por el efecto carrusel en su página de inicio. A través de la depuración del navegador, finalmente entendí el principio de implementación y finalmente escribí una copia por mí mismo Demo. El efecto final es el siguiente :( (El el código fuente está al final)

Efecto plano:

Inserte la descripción de la imagen aquí

Efecto 3D:

Inserte la descripción de la imagen aquí

Este carrusel corta la imagen en varias piezas, luego reproduce las piezas cortadas con efectos de animación a su vez y finalmente las une en una nueva imagen.

En el proceso de recuperación de la pila de tecnología front-end, parece que no existe ninguna tecnología que pueda recortar directamente la imagen y dividirla en varias partes, el efecto de recorte de imagen que solemos aplicar solo se utiliza canvaspara simular la generación.

A través de mi propia depuración, resulta que esta imagen de carrusel utiliza una canvasforma más sencilla de lograr el mismo efecto de recorte.

A continuación, proceda de lo menos profundo a lo más profundo, paso a paso para revelar el principio de implementación.

Efecto plano

Comencemos con el efecto plano, primero escriba un htmldiagrama de carrusel general , la estructura es la siguiente:

 <div class="main" id="el">
       <div class="item">
         <img src="./img/1.jpg" />
       </div>
       <div class="item">
         <img src="./img/2.jpg" />
       </div>
       <div class="item">
         <img src="./img/3.jpg" />
       </div>
 </div>

elEs el contenedor exterior, que contiene tres imágenes de carrusel.

Si queremos hacer un efecto de animación, tenemos que seguir un paso.

  • Genera u obtén los domelementos a animar
  • domAgrega efectos de animación al elemento.

Ahora ralentice la animación del efecto plano y observe atentamente sus características, como se muestra en la siguiente figura:

Inserte la descripción de la imagen aquí

htmlEste segmento de imagen no se encuentra en el código original , lo que significa que los elementos que se van a animar deben ser generados por nosotros y agregados al documento de la página para su representación.

Si la imagen de configuración se cortará en 5partes, entonces generamos una estructura de imagen de corte que es la siguiente:

   <div class="main" id="el">
         <div class="item">
           <img src="./img/1.jpg" />
         </div>
         <div class="item">
           <img src="./img/2.jpg" />
         </div>
         <div class="item">
           <img src="./img/3.jpg" />
         </div>
         <!--做动画的dom元素-->
         <div class="hook">
              <div><img src="./img/2.jpg" /></div>
              <div><img src="./img/2.jpg" /></div>
              <div><img src="./img/2.jpg" /></div>
              <div><img src="./img/2.jpg" /></div>
              <div><img src="./img/2.jpg" /></div>
         </div>
   </div>

En la página original jsgenerando una clase llamada período hookde html片段, como modo de posicionamiento absolute.

hookHay cinco div, respectivamente, muestran 2.jpgel correspondiente problema de corte foto enfrenta ahora es cómo hacer que este 5se divfuera a escalar esta imagen una parte de ella?

Si la configuración hookdel contenedor exterior tiene un ancho total del 1000pxsubelemento, el 5número divpromedio de 200pxpuede ser proporcionado por un segundo, deje que divsolo muestre imglos segundos cortes.

  <div style="position:absolute;width:200px;left:200px;overflow:hidden">
     <img src="./img/2.jpg" style="position:absolute;width:500%;left:-200px"/>
  </div>

Dado que el ancho total de la capa exterior 1000px, corte en 5partes que divrepresentan cada uno 200px(en la codificación real a 200través de jscalculado), y luego se mueve hacia la derecha 200pxocupando la segunda posición de corte.

imgLa asignación de la widthsuma leftes el punto clave, y su valor específico también se calcula por el ancho total y el número de cortes.

widthEstablezca en 500%, lo que significa que el ancho de la imagen es igual al 1000pxcontenedor más externo, y luego muévase hacia la izquierda 200px. Debido a que el padre está divestablecido overflow:hidden, imagine el efecto y saldrá.

Estos procesos mencionados anteriormente deben jsempalmarse y calcularse en una cadena html字符串, similar a la siguiente:

  for(i=0;i<n;i++){ //循环i次,n(总共将图片切成n份),unit_width对应每一个切块的宽度
           html += `
               <div 
               style="position:absolute;
               width:${unit_width}px;
               top:-100%;
               left:${ i * unit_width};
               overflow:hidden">
                   <img src="${src}" 
                       style="position:absolute;
                       width:${n*100}%;
                       left:${-i * unit_width}px"/>
              </div>
     `     
  }

5Después de divcompletar la costura, colóquelo <div class="hook"></div>y agréguelo a la representación del documento de la página. El domelemento final generado es el elemento que se animará a continuación.

Dado que se establece 5un divconjunto de posicionamiento y topvalor absolutos -100%, una vez que se representan, se encuentran en la posición superior de la página.

El siguiente efecto de animación es muy fácil de lograr, solo necesitamos divagregar uno a cada uno en el ciclo anterior transition:top linear 0.25s.

Una vez que se completa 5una divrepresentación, podemos jsestablecer dinámicamente en cada uno divde los topvalores de 0animación que se activa, cada página divse desliza lentamente hacia abajo desde la parte superior.

Espere hasta que se complete todo el proceso de animación, haremos que se elimine hookeste uso jsgenerado dom, y que se debe mostrar item(que contiene imágenes estáticas del original dom) se configura para mostrar oculto desde este punto todo el proceso de animación se completa.

Efecto 3D

El efecto plano es relativamente sencillo de implementar y el 3Defecto de volteo requiere primero una comprensión de csslos 3datributos.

Revisión de propiedad 3d

rotateX: Alrededor del Xeje de rotación, Lenovo 单杠运动.
rotateY: Alrededor del Yeje de rotación, Lenovo 钢管舞.
rotateZ: Alrededor del Zeje de rotación, Lenovo 老式钟表盘.

Los tres atributos anteriores generalmente se contactan mucho, por lo que no los repetiré. Lo siguiente se enfocará en los 3datributos.

    .container{
       perspective: 1200px;
       perspective-origin: right center;
      .wrapper {
        transform-style: preserve-3d;
        transform:translateZ(-100px);
      }
    }

El contenedor externo containercontiene un niño wrapper. El niño es el 3delemento específico que se va a animar, por lo que debe establecer una propiedad transform-style: preserve-3d.

Solo cuando se establece, el preserve-3delemento puede mostrar su 3defecto.

translateZY translateX, translateYestos dos atributos no son lo mismo. translateXEs a punto de moverse en el plano, translateYse mueve en el plano vertical.

translateZEs un 3datributo No realiza desplazamientos hacia arriba, abajo, izquierda y derecha en el plano, sino que realiza desplazamientos dentro o fuera de la dirección perpendicular al plano.

translateZ(-100px)Significa que el elemento se ha movido al interior de la pantalla 100px. Según la regla de cerca, grande, lejano, pequeño, el efecto visual final del elemento se 100pxreduce en su conjunto. Si es positivo , se moverá a la fuera de la pantalla 100px, y el efecto visual del elemento se agranda.

translateZpreserve-3dAplicar solo en el elemento con el conjunto de atributos tendrá efecto, de modo que preserve-3dtodos los 3datributos puedan tener efecto.

blockEs 3del domelemento a transformar , por lo que necesita ser ambientado preserve-3dy transformtransformado El elemento padre es containerequivalente a un escenario y blockpuede ser considerado como un actor de la representación escénica.

perspectiveRepresenta la distancia entre la audiencia y el escenario. Es concebible perspectiveque cuanto menor sea el valor, más cerca estará la audiencia del escenario, y la escena en el escenario se verá con mayor claridad.

Correspondiente a la escena real, perspectivecorrespondiente a domla distancia entre los elementos en los ojos del usuario, cuanto mayor es la distancia, cuanto más lejos, wrappermás pequeño y menos claro es el interior. Por el contrario, cuanto perspectivemayor es el mayor, wrappermayor es la apariencia y cuanto más claros sean los detalles internos.

perspective-originPuede entenderse como si el usuario está sentado en la posición izquierda, en la posición media o en la posición derecha del auditorio para ver la actuación en el escenario, y el efecto del campo visual es diferente.

Ahora volviendo al tema, continúe estudiando 3del diagrama de carrusel del efecto de volteo. Al disminuir el tiempo de animación, observe sus detalles, como se muestra en la siguiente figura:

Inserte la descripción de la imagen aquí

Al observar la imagen de arriba, rápidamente me di cuenta de que los elementos que se van a animar no están disponibles en la página actual y deben ser jsgenerados dinámicamente por nosotros.

El elemento de animación es un cubo, que contiene dos efectos de movimiento. Uno es moverse hacia la izquierda y el otro es voltear hacia adelante. Es fácil moverse hacia la izquierda, configúrelo en un leftvalor de cambio dinámico de posicionamiento absoluto . Y voltear puede RotateX(-90deg)se puede hacer configurando Arrived (equivalente a Xinvertir el 90grado a lo largo del eje ).

El efecto de animación del cubo no es difícil de lograr, la dificultad radica en cómo generar dicho cubo.

Dibujar cubo

En la escena actual, el cubo solo necesita dibujar cuatro caras: superior, frontal, izquierda y derecha. La parte superior se almacena para que la siguiente imagen sea un carrusel, la parte delantera se almacena para la imagen que se muestra actualmente, y la izquierda y la derecha son negro. El fondo está relleno para hacer que la imagen sea más tridimensional, la htmlestructura es la siguiente:


   <div class="wrapper">
            <div class="left"></div>
            <div class="right"></div>
            <div class="front"><img src="1.jpg"></div>
            <div class="up"><img src="2.jpg"></div>
   </div>

El left, right, fronty upse establecen para el posicionamiento absoluto, anchura y altura están llenos con el elemento de matriz, lefty topajuste 0.

frontEs la cara directamente al frente, originalmente se muestra en el plano y no es necesario realizar ningún procesamiento.

leftPara colocar el punto central en la esquina superior izquierda, el grado de yrenderizado a lo largo del eje 90formará el lado.

.left {
  transform-origin: 0% 0%;
  transform: rotateY(90deg);
  background-color: #333;
}

rightDebe mover todo el ancho hacia la derecha y luego girar a lo largo del eje y 90para formar el lado derecho.

html += `
    ... //js中dom字符串拼接
   <div class="right" style="transform: translateX(${unit_width}px) rotateY(90deg);">
      ...
   </div>
   ...
`

upLa superficie primero establece el punto central en la esquina inferior izquierda, gira alrededor del Xeje 90y luego se mueve hacia arriba en toda la altura para formar la parte superior.

.up{
    transform-origin: 0% 100%;
}
html += `
    ... //js中dom字符串拼接
   <div class="up" style="transform: rotateX(90deg) translateZ(${container_height}px);">
     ...
   </div>
   ...
`

La domestructura de estas cuatro caras jsse empalma adentro y se coloca en el wrapperpadre correspondiente.Como se divmencionó anteriormente , los atributos wrapperdeben establecerse adentro preserve-3d, y los wrapperelementos son los elementos que están realmente animados dom.

wrapperDespués se encapsula el elemento, que se lanza en el elemento etapa container, y los atributos y containerse fijan .3dperspectiveperspective-origin

Uno containercorresponde a una rebanada de cubo, y la htmlcadena formada por todos los cubos cortados se coloca en el documento de la página y se renderiza, de esta manera domse generan los elementos animados .

Agregar animación de volteo

Los domelementos que realizan la animación han sido generados y renderizados en la página. Según el análisis anterior, agregar un atributo a cada cubo ( wrappercorrespondiente div) rotateX(-90deg)puede hacer que el cubo se voltee. Los resultados son los siguientes:

Inserte la descripción de la imagen aquí
wrapperAdemás, el rotateX(-90deg)atributo se voltea hacia adelante, pero la posición final no está cerca del suelo.

La causa del accidente fue porque wrapperera un cubo, no un plano simple, también contenía cuatro planos, ahora cuando se gira el cubo, la posición de su punto central es muy importante.

wrapperLa altura de está 100%llena de todo el padre. A través de las pruebas, se encuentra que la transformación de atributo del cubo se basa en realidad en el frente ( frontcara). El punto central del cubo se encuentra en frontel medio de la frontaltura de la cara. . Si la altura de la cara es 600px, entonces Al 300pxdibujar un Xeje, gire todo el cubo a lo largo de este eje. Si la frontaltura de la superficie es 800px, entonces el cubo 400pxgirará a lo largo del eje.

Ahora regrese al caso anterior, frontla altura de la cara está configurada para 100%llenar el elemento principal, luego el cubo dibujará un eje en el medio y se volteará hacia adelante 90, por lo que habrá un hueco debajo. No podemos dejar que el cubo girar y detenerse en el aire, para encontrar una manera de volver a ponerlo en el suelo.

De acuerdo con lo que dije antes, el cubo usa la frontsuperficie como superficie de referencia. Después de voltear el 90grado, la frontsuperficie llega a la parte inferior. Luego, quieres que el cubo se mueva hacia abajo, porque está frontmirando hacia la parte inferior en este momento , y Solo es necesario configurarlo translateZ(contrainer_height/2)para mover el cubo hacia abajo. La mitad de la altura está unida a la parte inferior.

Aunque esta configuración puede garantizar que el cubo volteado se adhiera a la parte inferior, la imagen de su interior se deforma.

Porque cuando el cubo está configurado rotateX(-90deg)para girar hacia adelante, en realidad se mueve hacia adelante. De acuerdo con las reglas de casi grande y muy pequeño, el efecto visual de la imagen se agranda. Para resolver este problema, primero use el cubo translateZ(-contrainer_height/2)para empujar la mitad de la altura en el interior y luego dejar que el cubo se voltee hacia adelante, para que se resuelva el problema del estiramiento de la imagen, el código es el siguiente:


while ((el = eles.shift())) {
    //el对应着每个立方体的dom
    //立方体先沿Z轴往后推一半高度,再朝前做翻转,翻转完后向下移动一半高度贴底 
    el.style.transform = `translateZ(${  
      -this.container_height / 2
    }px) rotateX(-90deg) translateZ(${this.container_height / 2}px)`;
    ...
  }

Una vez finalizado el efecto de volteo, encontraremos que el cubo está frente a nosotros y girando, no podemos ver el lado derecho del cubo con un fondo negro right, por lo que parecerá muy adimensional.

Presenté un atributo antes perspective-origin:right center. Esto es como la audiencia sentada en el lado derecho del auditorio, y el escenario es tan ancho como el auditorio, y hay una jaula de hierro en el escenario mirando hacia el frente de la audiencia. En este momento, el campo de visión de la audiencia solo puede ver En el frente de la jaula de hierro, si la jaula se empuja hacia el lado izquierdo del escenario, entonces el cliente sentado en el lado derecho de la audiencia no solo puede ver el frente de la jaula de hierro , pero también puede ver el lado derecho de la jaula de hierro.

De la misma manera, para que el cubo parezca más tridimensional cuando se voltea, el fondo negro de la derecha se puede mostrar durante la animación. Para lograr este propósito, es necesario mover el cubo a la izquierda. , además perspective-origindel soporte de atributos, sale el cubo. El efecto tridimensional volteado sale.

Si desea que el cubo se mueva hacia la izquierda, solo necesita obtener los domelementos del cubo y leftasignarlos dinámicamente.

Código fuente

Código completo

Supongo que te gusta

Origin blog.csdn.net/brokenkay/article/details/115034048
Recomendado
Clasificación