Рисуем анимированную сцену с помощью css
Передохнем от верстки всяких пользовательских интерфейсов и просто порисуем на CSS. Рисовать будем такую вот сцену:
Смотреть на jsfiddle.
В статье я попробую описать пошаговое создание этой сцены.
Описанный код работает на webkit браузерах (Chrome, Safari, Opera последних версий). Для работы в других браузерах вместо префиксв -webkit нужно воспользоваться соответствующими префиксами (-moz, -ms, -o).
Создаем сцену и небо
.scene { position: relative; width: 800 px; height: 600 px; margin: 50 px auto; overflow: hidden; background-image: -webkit-linear-gradient (top, #011428, #032a54); } с помощью linear-gradient (top, #011428, #032a54) мы заполнили сцену градиентом от темноватого (#011428) до более светлого (#032a54) оттенка синего начиная сверху (top)
Рисуем сугробы. За основу возьмем элипсы которые можно создать из div’ов задав им border-radius: 50%
.ground { position: absolute; width: 770 px; height: 200 px; border-radius: 50%; background-color: #99a; }
Позиционируем 4 эллипса внизу сцены
.ground { width: 400 px; background-color: #f5f5f5; border-radius: 50%; width: 770 px; height: 200 px; position: absolute; bottom: 0; margin-bottom: -80 px; right: 140 px; background-color: #99a; } .ground.back-1 {left: 180 px;} .ground.front {margin-bottom: -124 px; left: -27 px;} .ground.front-2 {margin-bottom: -109 px; right: -508 px;}
Делаем сугробы объемными добавив к классу .ground внутренню тень
box-shadow: 0 0 100 px #457eb2 inset;
Рисуем луну и звезды
.stars { position: absolute; width: 100%; height: 100%; }
.star { position: absolute; border-radius: 50%; width: 1 px; height: 1 px; background-color: #ffffff; }
.star: nth-child (1) {top: 100 px; left: 685 px;} .star: nth-child (2) {top: 37 px; left: 537 px;} .star: nth-child (3) {top: 150 px; left: 350 px;} .star: nth-child (4) {top: 50 px; left: 320 px;} .star: nth-child (5) {top: 30 px; left: 755 px;} .star: nth-child (6) {top: 70 px; left: 483 px;} .star: nth-child (7) {top: 18 px; left: 80 px;}
Добавляем луне эффект свечения
box-shadow: 0 0 40 px #ffffaa; И звездам тоже: box-shadow: 0 0 10 px 2 px white;
Теперь приступаем к дому. Дом будет состоять из крыши, стены, окна и дымохода. Описываем все это версткой:
.house .wall { width: 100%; height: 200 px; position: absolute; bottom: 0; background-color: #180c00; background: repeating-linear-gradient (to bottom, #573808 0%,#3a1e12 15%); }
Делаем окошко. Это будет div с желтым фоном и с коричневой рамкой
.house .window { position: absolute; height: 70 px; width: 65 px; background-color: #cccc00; border: 5 px solid #3a1e12; bottom: 53 px; left: 110 px; box-shadow: 0 0 5 px black; }
Добавляем к нему еще раму и эффект свечения с помощью box-shadow
.house .window .frame: nth-child (2) { position: absolute; width: 100%; top: 30%; height: 7 px; background-color: #3a1e12; }
.house .window .light { width: 100%; height: 100%; background-color: #ffff00; opacity: 0.5; box-shadow: 0 0 100 px yellow; }
Создаем крышу. Это будет div бордер которого послужит кровлей.
.house .roof .roof-wall { position: absolute; width: 280 px; height: 280 px; background-color: #573808; left: 25 px; top:60 px; border: 5 px solid #3a1e12; box-shadow: 0 0 30 px black inset; }
Для создания эффекта вагонки снова воспользуемся повторяющимся градиентом, который повернем на 45 градусов
background: repeating-linear-gradient (45deg, #573808 0%,#573808 5%,#3a1e12 5%,#3a1e12 5%,#3a1e12 5%,#573808 5%,#3a1e12 6%)
Крыша готова, ставим ее на дом повернув на 45 градусов с помощью transform: rotate (45deg) и отрезав половину с помощью overflow: hidden у контейнера
.house .roof { width: 340 px; height: 170 px; right: -20 px; position: absolute; overflow: hidden; }
.house .roof .roof-wall { position: absolute; width: 280 px; height: 280 px; background-color: #573808; -webkit-transform: rotate (45deg); left: 25 px; top:60 px; border: 5 px solid #3a1e12; box-shadow: 0 0 30 px black inset; background: repeating-linear-gradient (45deg, #573808 0%,#573808 5%,#3a1e12 5%,#3a1e12 5%,#3a1e12 5%,#573808 5%,#3a1e12 6%); }
Приделываем трубу, нарисованную с помощью градиента
.house .chimney { position: absolute; height: 80 px; width: 30 px; top: 58 px; left: 20 px; background: linear-gradient (right, rgba (42,41,45,1) 0%, rgba (80,84,91,1) 36%, rgba (22,27,33,1) 100%); } И добавляем шероховатости бревнам, наложив на них пару повторяющихся коричневых градиентов переходящих в прозрачность
.house .wall .crack: nth-child (2) { opacity: 0.3; background: repeating-linear-gradient (-4deg, rgba (0,0,0,0) 0%, rgba (0,0,0,0) 2%, rgba (0,0,0,0) 2%,#3a1e12 2%,#3a1e12 2%,#573808 2%,#3a1e12 3%); } Ну вот, у нас получилась уже вполне миленькая картинка
Настало время оживить нашу статичную картинку анимациями. Для начала сделаем чтобы из дымохода появлялись клубы дыма.Пока что нарисуем одно облако дыма. Это будет полупрозрачный овал со светлым box-shadow ввокруг и радиальным градиентом.
С помощью ключевых кадров опишем траекторию движения и трансформацию этого облака. Оно будет постепенно увеличиваться и становиться прозрачным
@-webkit-keyframes smoke-move { 0% {top: 120 px; left: 20 px} 20% {top: 107 px; left: 25 px} 30% {top: 95 px; left: 35 px; opacity: 0.9} 40% {top: 80 px; left: 40 px; } 50% {top: 65 px; left: 50 px; } 60% {top: 50 px; left: 62 px; } 70% {top: 35 px; left: 75 px; } 80% {top: 25 px; left: 90 px; } 90% {top: 15 px; left: 117 px; } 100% {top: 7 px; left: 127 px; opacity: 0; width: 90 px; height: 60 px} } Теперь назначим только что описанную анимацию к нашему облаку, добавив к классу .smoke свойство
-webkit-animation: smoke-move 2.3s linear infinite
Отлично у нас уже есть рабочий дымоход, но в полноценном виде он должен непрерывно ипускать много клубов дыма, так что добавим еще нескколько штук в верстку.
.smoke-area .smoke: nth-child (3) { -webkit-animation: smoke-move 2.7s linear infinite }
.smoke-area .smoke: nth-child (4) { -webkit-animation: smoke-move 2.2s linear infinite }
.smoke-area .smoke: nth-child (5) { -webkit-animation: smoke-move 2.1s linear infinite }
.smoke-area .smoke: nth-child (6) { -webkit-animation: smoke-move 2s linear infinite }
.smoke-area .smoke: nth-child (7) { -webkit-animation: smoke-move 2.9s linear infinite } Теперь клубы дыма движутся по той-же траектории, но за различное время что дает видимость их случайного движения:
Через какое-то время цикл анимации движения облаков дыма начнет повторяться, но при достаточно большом количестве циклов этого будет не сильно заментно. Чтобы подобрать наибольший цикл движения в качестве времени анимации нужно указывать взаимно простые числа.
И в качестве изюминки добавим несколько падающих звездочек. Как и раньше начнем с одной, добавим ее как .meteor в div.meteors
.meteor { position: absolute; top: 50 px; left: 280 px; width: 300 px; height: 1 px; -webkit-transform: rotate (-45deg); background-image: -webkit-linear-gradient (left, white, rgba (255,255,255,0)); } Теперь нарисуем звездочку на конце этого хвоста:
.meteor: before { content: ' '; position: absolute; width: 4 px; height: 5 px; background-color: white; border-radius: 50%; box-shadow: 0 0 14 px 4 px white; margin-top: -2 px; } Опишем анимацию для метеора, будем его двигать меняя отступы создавая эффект полета под наклоном 45 градусов. Метеор будет падать и постепенно исчезать. @-webkit-keyframes meteor { 0% {margin-top: -300 px; margin-right: -300 px; opacity: 1} 8% {opacity: 0} 10% {margin-top: 300 px; margin-left: -600 px; opacity: 0} 100% {opacity: 0} } Запускаем метеор в полет: .meteor {top: 100 px; left: 480 px;-webkit-animation: meteor 10s linear infinite;} Нужно больше метеоров!