Slideshow de Fragmentos Animados 25.02.18 11:32
Traduzido pelo Google Tradutor
Artigo Oficial
https://tympanus.net/codrops/2018/02/21/animated-fragment-slideshow/
Um tutorial sobre como criar uma apresentação de slides experimental que se anima em fragmentos. O controle deslizante é alimentado pela biblioteca "Pieces", que foi criada para obter efeitos interessantes como esses facilmente.
Hoje gostaríamos de mostrar como criar um controle deslizante brincalhão com um visual fragmentado original. Cada elemento do controle deslizante será dividido em pedaços que irão animar de maneiras diferentes, usando Pieces , uma biblioteca que eu criei para obter efeitos interessantes como esses facilmente.
Este será o resultado final:
As animações são alimentadas por anime.js .
A demonstração é gentilmente patrocinada por: Northwestern's Online Master's em Design e Estratégia de Informação .
Se você quiser patrocinar uma das nossas demonstrações, descubra mais aqui .
A idéia original
A fonte de inspiração para esse tipo de efeito veio do Dribbble shot Shift Animation de Alexander Saunki:
Desde que eu vi, queria implementar um efeito como esse para o meu novo site pessoal, que lancei recentemente: lmgonzalves.com .
Para alcançar os efeitos desejados, desenvolvi uma biblioteca que chamei de "Peças", pois permite desenhar e animar texto, imagens e caminhos SVG através de peças retangulares. Então, sem mais delongas, vejamos como usar esta biblioteca!
Começando com Pieces
Toda a documentação detalhada sobre a biblioteca Pieces pode ser encontrada em seu repositório Github . Mas, de qualquer forma, vejamos rapidamente alguns conceitos essenciais para começar a usar esta biblioteca.
Supondo que desejamos desenhar e animar uma imagem, esses são os elementos básicos que compõem a cena:
Como você pode ver, a imagem que queremos desenhar será a nossa item, que será dividida em vários pieces, que também podem variar em tamanho e posição de acordo com as opções que definimos. Para ver todas as opções possíveis, recomendo que você verifique a documentação no Github .
Ao longo do tutorial, explicaremos cada código, para que você possa aprender a implementar suas próprias animações usando a biblioteca Pieces. Vamos começar!
Estrutura de HTML
Antes de começar a escrever código Javascript, vejamos como definimos o HTML para o nosso controle deslizante. A marcação é bastante simples, pois temos cada slide com uma imagem e texto correspondentes, o canvaselemento para animar coisas e botões para navegar pelo controle deslizante.
- Código:
<!-- Pieces Slider -->
<div class="pieces-slider">
<!-- Each slide with corresponding image and text -->
<div class="pieces-slider__slide">
<img class="pieces-slider__image" src="img/ricardo-gomez-angel-381749.jpg" alt="">
<div class="pieces-slider__text">Ricardo Gomez Angel</div>
</div>
<div class="pieces-slider__slide">
<img class="pieces-slider__image" src="img/josh-calabrese-527813.jpg" alt="">
<div class="pieces-slider__text">Josh Calabrese</div>
</div>
<div class="pieces-slider__slide">
<img class="pieces-slider__image" src="img/samuel-zeller-103111.jpg" alt="">
<div class="pieces-slider__text">Samuel Zeller</div>
</div>
<div class="pieces-slider__slide">
<img class="pieces-slider__image" src="img/sweet-ice-cream-photography-143023.jpg" alt="">
<div class="pieces-slider__text">Sweet Ice Cream</div>
</div>
<div class="pieces-slider__slide">
<img class="pieces-slider__image" src="img/sticker-mule-199237.jpg" alt="">
<div class="pieces-slider__text">Sticker Mule</div>
</div>
<!-- Canvas to draw the pieces -->
<canvas class="pieces-slider__canvas"></canvas>
<!-- Slider buttons: prev and next -->
<button class="pieces-slider__button pieces-slider__button--prev">prev</button>
<button class="pieces-slider__button pieces-slider__button--next">next</button>
</div>
Estilizando o Slider
A apresentação de slides precisa de um estilo especial para o nosso efeito. Precisamos esconder as imagens e os textos à medida que os redimensionarmos com a nossa biblioteca. Mas também queremos que eles recuem para sua marcação inicial se nenhum JavaScript estiver disponível. Finalmente, precisamos ter certeza de que o controle deslizante é responsivo com algumas consultas de mídia:
- Código:
.pieces-slider {
position: relative;
text-align: center;
padding: 8rem 0;
}
.js .pieces-slider {
padding: 0;
}
/* Make all slides absolutes and hide them */
.js .pieces-slider__slide {
position: absolute;
right: 100%;
}
/* Define image dimensions and also hide them */
.pieces-slider__image {
max-width: 600px;
max-height: 400px;
}
.js .pieces-slider__image {
visibility: hidden;
}
/* Hide the titles */
.js .pieces-slider__text {
text-indent: -9999px;
}
/* Canvas with viewport width and height */
.js .pieces-slider__canvas {
position: relative;
width: 100vw;
height: 100vh;
transition: 0.2s opacity;
}
/* Class for when we resize */
.pieces-slider__canvas--hidden {
opacity: 0;
transition-duration: 0.3s;
}
/* Navigation buttons */
.pieces-slider__button {
position: absolute;
left: 0;
top: 50%;
width: 100px;
height: 100px;
margin: -25px 0 0 0;
background-color: #5104ab;
color: #fff;
font-family: inherit;
font-weight: bold;
border: none;
cursor: pointer;
transition: 0.1s background-color;
}
.pieces-slider__button:hover {
background: #5f3abf;
}
.pieces-slider__button--next {
left: auto;
right: 0;
}
/* Hide the buttons when no JS */
.no-js .pieces-slider__button {
display: none;
}
/* Media queries with styles for smaller screens */
@media screen and (max-width: 720px) {
.pieces-slider__image {
max-width: 300px;
}
}
@media screen and (max-width: 55em) {
.pieces-slider__canvas {
width: 100vw;
height: 100vw;
}
.pieces-slider__button {
width: 60px;
height: 60px;
}
}
Como você pode ver, escondemos os elementos HTML que definimos para o nosso controle deslizante (exceto os botões), pois desenhamos tudo no canvaselemento.
Usando Pieces para animar o controle deslizante
Vamos começar por definir algumas variáveis e obter as informações do controle deslizante do DOM:
- Código:
// Get all images and texts, get the `canvas` element, and save slider length
var sliderCanvas = document.querySelector('.pieces-slider__canvas');
var imagesEl = [].slice.call(document.querySelectorAll('.pieces-slider__image'));
var textEl = [].slice.call(document.querySelectorAll('.pieces-slider__text'));
var slidesLength = imagesEl.length;
Então precisamos definir variáveis de índices para lidar com todos os itens que desenharemos na tela:
- Código:
// Define indexes related variables, as we will use indexes to reference items
var currentIndex = 0, currentImageIndex, currentTextIndex, currentNumberIndex;
var textIndexes = [];
var numberIndexes = [];
// Update current indexes for image, text and number
function updateIndexes() {
currentImageIndex = currentIndex * 3;
currentTextIndex = currentImageIndex + 1;
currentNumberIndex = currentImageIndex + 2;
}
updateIndexes();
Agora vamos começar a definir as opções para cada tipo de item (imagem, texto, número e botão). Você pode encontrar uma referência completa na documentação Pieces, mas aqui está uma explicação detalhada para cada opção usada para desenhar as imagens:
- Código:
// Options for images
var imageOptions = {
angle: 45, // rotate item pieces 45deg
extraSpacing: {extraX: 100, extraY: 200}, // this extra spacing is needed to cover all the item, because angle != 0
piecesWidth: function() { return Pieces.random(50, 200); }, // every piece will have a random width between 50px and 200px
ty: function() { return Pieces.random(-400, 400); } // every piece will be translated in the Y axis a random distance between -400px and 400px
};
Da mesma forma, definiremos as opções para os outros tipos de itens. Veja os comentários para entender algumas das propriedades usadas:
- Código:
// Options for texts
var textOptions = {
color: 'white',
backgroundColor: '#0066CC',
fontSize: function() { return windowWidth > 720 ? 50 : 30; },
padding: '15 20 10 20',
angle: -45,
extraSpacing: {extraX: 0, extraY: 300},
piecesWidth: function() { return Pieces.random(50, 200); },
ty: function() { return Pieces.random(-200, 200); },
translate: function() {
if (windowWidth > 1120) return {translateX: 200, translateY: 200};
if (windowWidth > 720) return {translateX: 0, translateY: 200};
return {translateX: 0, translateY: 100};
}
};
// Options for numbers
var numberOptions = {
color: 'white',
backgroundColor: '#0066CC',
backgroundRadius: 300,
fontSize: function() { return windowWidth > 720 ? 100 : 50; },
padding: function() { return windowWidth > 720 ? '18 35 10 38' : '18 25 10 28'; },
angle: 0,
piecesSpacing: 2,
extraSpacing: {extraX: 10, extraY: 10},
piecesWidth: 35,
ty: function() { return Pieces.random(-200, 200); },
translate: function() {
if (windowWidth > 1120) return {translateX: -340, translateY: -180};
if (windowWidth > 720) return {translateX: -240, translateY: -180};
return {translateX: -140, translateY: -100};
}
};
Agora, temos todas as opções para cada tipo de item, vamos colocá-los para o passar para a biblioteca Pieces!
- Código:
// Build the array of items to draw using Pieces
var items = [];
var imagesReady = 0;
for (var i = 0; i < slidesLength; i++) {
// Wait for all images to load before initializing the slider and event listeners
var slideImage = new Image();
slideImage.onload = function() {
if (++imagesReady == slidesLength) {
initSlider();
initEvents();
}
};
// Push all elements for each slide with the corresponding options
items.push({type: 'image', value: imagesEl[i], options: imageOptions});
items.push({type: 'text', value: textEl[i].innerText, options: textOptions});
items.push({type: 'text', value: i + 1, options: numberOptions});
// Save indexes
textIndexes.push(i * 3 + 1);
numberIndexes.push(i * 3 + 2);
// Set image src
slideImage.src = imagesEl[i].src;
}