Wyobraź sobie dramat kryminalny z lat trzydziestych ubiegłego wieku. Po masowym upadku banków, młody detektyw dostaje sprawę swojego życia. Akceptuje to wyzwanie i po wielu miesiącach ciężkiej pracy pociąga do odpowiedzialności winne osoby.
To co wykonamy za chwilkę, to typowo wyglądająca, wirująca gazeta. Efekt ten jest bardzo popularnie wykorzystywany przez twórców filmów, których akcja dzieje się właśnie w pierwszej połowie XX w.
Pobawmy się zatem trochę i zbudujmy taką gazetę przy pomocy animacji CSS 3, w których obsługę zostały wyposażone najnowsze wersje przeglądarek Firefox, Chrome oraz Safari.
Pomysł
Używając JavaScript załadujemy ?pokrojoną? wersję naszej gazety i połączymy je w tak zwany canvas. Będziemy również załączać czcionkę z Google WebFonts (https://developer.mozilla.org/en/CSS/CSS_animations). Użyjemy jej do napisania tytułu artykułu w naszej gazecie.
Definiujemy także prostą animację CSS 3, która używa transformacji takich jak scale() oraz rotate() do animowania elementów canvas. Dodanie canvas do naszej animacji gwarantuje nam, że nie będziemy musieli dodawać pojedynczych linii do JavaScript, aby uzyskać odpowiedni efekt.
Obecnie, animacje CSS 3 są obsługiwane przez Firefox, Safari i Chrome, więc jeśli korzystasz z najnowszej wersji jednej z tych przeglądarek, będziesz mógł cieszyć się przedstawionym poniżej efektem.
Oto kilka mniej istotnych powodów, które doprowadziły do powyższych wniosków:
- Cały obraz gazety zapisany w formacie PNG waży ponad 250 kb. Natomiast pocięcie jej oszczędza nam około 200 kb. Wszystko dzięki temu, że centralna część gazety, dzięki pocięciu, nie potrzebuje transparentnego tła i może zostać zapisana do formatu jpg.
- Obrócony tekst nie wygląda zbyt dobrze w przeglądarce, ponieważ litery mogą tracić anti-aliasing. Jest to szczególnie widoczne w przypadku Firefoxa. Użycie canvas rozwiązuje ten problem.
HTML
Znaczników użytych w HTML?u powinno być jak najmniej- wszystko powinno zostać wykonane przy uzyciu jQuery. Zatem musimy jedynie załączyć pliki źródłowe JS oraz CSS.
index.html
Efekt wirującej gazety | Magazyn T3
To wszystko
.
W sekcji head, włączamy nasz plik styles.css (omówione poniżej) oraz stylsheet, który osadza czcionkę Anton z WebFonts Google. Pod koniec pliku dołączamy bibliotekę jQuery w wersji 1.6.2 oraz nasz plik script.js (szczegółowo omówione później).
Najważniejsza część znaczników w kodzie jest również najbardziej skromna. Blok #fontPreload jest kluczowy dla tego przykładu. Jego zadaniem jest użycie osadzonej wcześniej czcionki Anton. Jest to konieczne, aby przeglądarki właściwie rozpoznały czcionkę przed jej użyciem w elemencie canvas. Bez tego gapilibyśmy się na pustą gazetę.
jQuery
Jako że używamy niestandardowych czcionek sieci Web, musimy być pewni, że czcionka jest załadowana zanim użyjemy jej do tworzenia tytułów prasowych. Dlatego też używamy w tutaj $(window).load().
script.js
$(window).load(function(){
var imgPath = "assets/img/";
// Define 6 paper covers:
var papers = [
{
line1:"Swiatowy kryzys",
line2:"to mistyfikacja!",
subtitle:"Ekonomiści przyznają, że był to tylko żart"
}, {
line1:"Gleboko smazone potrawy",
line2:"uznane za zdrowe",
subtitle:"Naukowcy zmieniaja definicje slowa \"Zdrowie\""
}, {
line1:"Apple zapowiada",
line2:"nowego iPhona 9",
subtitle:"5, 6, 7 i 8 odchodza do lamusa"
}, {
line1:"Swiat sie skonczyl",
line2:"21 maja!",
subtitle:"Ksieza mowia, iz jestesmy juz martwi"
}, {
line1:"Francja naklada",
line2:"podatek od zdjec kota",
subtitle:"Opublikowanie zdjecia kota bedzie teraz kosztowalo ?3"
}, {
line1:"Dziekuje i",
line2:"do widzenia",
subtitle:"Magazyn T3 zegna sie"
}
];
// Sprawdź, czy canvas i animacje CSS3 są obłsugiwane:
if(!$.support.canvas){
$('#fin').html('Przykro mi, Twoja przeglądarka
nie obsługuje <canvas>').show();
return;
}
if(!$.support.css3Animation){
$('#fin').html('Przykro mi, Twoja przeglądarka
nie obsługuje animacji CSS3').show();
return;
}
// Uzyj jQuery.Deferred aby załadować gazetę
$.when(
loadImage(imgPath+"paper_top.png"),
loadImage(imgPath+"paper_left.png"),
loadImage(imgPath+"paper_center.jpg"),
loadImage(imgPath+"paper_right.png"),
loadImage(imgPath+"paper_bottom.png")
).then(function( imgTop, imgLeft, imgCenter, imgRight, imgBottom ){
$.each(papers,function(i){
var canvas = document.createElement("canvas"),
c = canvas.getContext("2d");
canvas.width = 717;
canvas.height = 526;
c.drawImage( imgTop, 0, 0 );
c.drawImage( imgLeft, 0, 12 );
c.drawImage( imgCenter, 14, 12 );
c.drawImage( imgRight, 711, 12 );
c.drawImage( imgBottom, 0, 516 );
drawText( this.line1, this.line2, this.subtitle, c, 358, 250 );
setTimeout(function(){
$("body").append(canvas);
},i*5800);
});
$('#fin').delay(papers.length*5800).fadeIn();
});
/*------------------------
Funkcje pomocnicze
------------------------*/
function loadImage(src){
var def = new $.Deferred(),
img = new Image();
img.onload = function(){
def.resolve(img);
}
img.src = src;
return def.promise();
}
function drawText( line1, line2, subtitle, c, x, y ){
c.font = "65px Anton,Calibri";
c.textAlign = "center";
c.fillStyle = "#3e3e3e";
c.fillText(line1.toUpperCase(),x,y);
c.fillText(line2.toUpperCase(),x,y+80);
c.font = "italic 20px Georgia,serif";
c.fillStyle = "#737373";
c.fillText(subtitle,x,y+120);
}
});
(function(){
$.support.canvas = 'getContext' in document.createElement('canvas');
$.support.css3Animation = (function(){
var sp = $('');
return (
sp.css("-webkit-animation") !== undefined ||
sp.css("-moz-animation") !== undefined ||
sp.css("animation") !== undefined
);
})();
})();
Aby wygenerować gazetę, musimy załadować pięć obrazków, które ją tworzą. Brzmi to jak idealne miejsce, aby użyć obiektu jQuery?s Deferred, które zostało wprowadzone w wersji 1.5. Wszystko, co ma robić, to informować nas, gdy zdarzenia asynchroniczne zostaną zakończone. Jak widać, używamy go w funkcji loadImage(). Natomiast metoda then() znajdująca się w linii 58 zostaje wywołana tylko wtedy, gdy wszystkie pięć obrazków zostanie załadowane.
Wewnątrz pętli $.each, tworzymy canvas dla każdego elementu naszej gazety i dodajemy je do strony, po upływie czasu określonego w setTimeout().
Gdy już mamy elementy canvas na naszej stronie, możemy przystąpić do dalszej ich animacji.
CSS
Elementy canvas są traktowane jak każdy inny element. Oznacza to, że można spokojnie używać stylu i przekształcać je w taki sam sposób jak w przypadku zwykłego obrazu.
Gdy elementy canvas znajdują się już na stronie, użyjemy stylu jak poniżej:
canvas{ position:fixed; width:717px; height:526px;
top:50%; left:50%;
margin:-263px 0 0 -358px; opacity:0;
/* Skonfiguruj animację dla Firefoxa */ -moz-animation-duration:6s; -moz-animation-name:spin; -moz-animation-timing-function:linear;
/* Konfiguracja dla Chrome i Safari */ -webkit-animation-duration:6s; -webkit-animation-name:spin; -webkit-animation-timing-function:linear;}
Nie ma tu nic niezwykłego. Centrujemy elementy canvas na stronie i definiujemy różne właściwości animacji takie jak czas trwania, czy nazwa. ?Linear? spowoduje, iż nasza animacja będzie działać ze stałą prędkością. Wartość domyślna, czyli ?ease?, spowodowałaby coraz szybsze wyświetlanie się animacji.
Po tym musimy użyć deklaracji @keyframes (https://developer.mozilla.org/en/CSS/CSS_animations) aby określić, jak nasz element będzie wyglądał w różnych kluczowych punktach animacji:
@-moz-keyframes spin{
0%{
opacity:0.2;
-moz-transform:scale(0.2) rotate(0deg);
}
15%{
opacity:1;
margin:-263px 0 0 -358px;
-moz-transform:scale(1) rotate(1090deg);
}
90%{
opacity:1;
top:50%;
-moz-transform:scale(1) rotate(1090deg);
}
100%{
top:500%;
opacity:1;
-moz-transform:scale(1) rotate(1090deg);
}
}
Gdy elementy canvas znajdują się już na stronie, zaczynamy od pozycji 0%. Wartość krycia jest tutaj ustalona na 0.2. Animacja szybko przechodzi do 15%, 90% i 100%. Wówczas na chwilę zatrzymuje się na ekranie i potem spada szybko poniżej dolnej krawędzi okna (osiągnęliśmy to dzięki ustawieniu wartości top na 500%).
Ważnym jest, aby określić wszystkie właściwości, które chcemy, w każdym punkcie procentowym naszej animacji. Jednym z przykładów jest tutaj deklaracja -moz-transform:scale(1) rotate(1090deg), która jest powielana aż trzykrotnie. Bez tego Chrome i Safar (ale Firefox nie) powrócą do poziomu domyślnego.
Jako, że funkcja ta nadal jest uważana przez producentów przeglądarek jako eksperymentalna, musimy napisać jeszcze ten sam kod, tylko dla webkit:
@-webkit-keyframes spin{
0%{
opacity:0.2;
-webkit-transform:scale(0.2) rotate(0deg);
}
15%{
opacity:1;
margin:-263px 0 0 -358px;
-webkit-transform:scale(1) rotate(1090deg);
}
90%{
opacity:1;
top:50%;
-webkit-transform:scale(1) rotate(1090deg);
}
100%{
top:500%;
opacity:1;
-webkit-transform:scale(1) rotate(1090deg);
}
}
Omówiliśmy tutaj kluczowe elementy dla pliku CSS. A oto, jak powinien wyglądać cały plik CSS:
html{
background-color:#333;
}
body{
color:#fcfcfc;
font:14px/1.3 'Segoe UI Light',Arial, sans-serif;
}
#fin{
font:70px 'Anton',Arial,Helvetica;
text-align:center;
padding-top:300px;
text-transform:uppercase;
display:none;
}
#fontPreload{
font-family:'Anton';
visibility:hidden;
position:absolute;
}
canvas{
position:fixed;
width:717px;
height:526px;
top:50%;
left:50%;
margin:-263px 0 0 -358px;
opacity:0;
/* konfiguracja animacji dla Firefox */
-moz-animation-duration:6s;
-moz-animation-name:spin;
-moz-animation-timing-function:linear;
/* konfiguracja dla Chrome i Safari */
-webkit-animation-duration:6s;
-webkit-animation-name:spin;
-webkit-animation-timing-function:linear;
}
@-moz-keyframes spin{
0%{
opacity:0.2;
-moz-transform:scale(0.2) rotate(0deg);
}
15%{
opacity:1;
margin:-263px 0 0 -358px;
-moz-transform:scale(1) rotate(1090deg);
}
90%{
opacity:1;
top:50%;
-moz-transform:scale(1) rotate(1090deg);
}
100%{
top:500%;
opacity:1;
-moz-transform:scale(1) rotate(1090deg);
}
}
@-webkit-keyframes spin{
0%{
opacity:0.2;
-webkit-transform:scale(0.2) rotate(0deg);
}
15%{
opacity:1;
margin:-263px 0 0 -358px;
-webkit-transform:scale(1) rotate(1090deg);
}
90%{
opacity:1;
top:50%;
-webkit-transform:scale(1) rotate(1090deg);
}
100%{
top:500%;
opacity:1;
-webkit-transform:scale(1) rotate(1090deg);
}
}
footer{
display:block;
background-color:#212121;
box-shadow: 0 -1px 2px #111;
position:fixed;
width:100%;
height:70px;
bottom:0;
left:0;
z-index: 100000;
}
footer h2{
font-size:20px;
font-weight:normal;
left:50%;
margin-left:-400px;
padding:22px 0;
position:absolute;
width:400px;
color:#eee;
}
W takiej postaci, nasz efekt wirującej gazety jest gotowy!
Wniosek
Jak każdy dramat kryminalny z lat 30 ubiegłego wieku, tak też nasz tutorial musi dobiec końca. Mam nadzieję, że mieliście tyle samo zabawy podczas jego czytania, jak ja podczas jego tworzenia. Jeśli masz jakieś myśli lub sugestie, to skorzystaj z sekcji komentarzy.