Золотая спираль

Февраль 07, 2011 ||  css ||  комментарии

В веб разработке мы постоянно имеем дело с блоками, «строительными кирпичами» веба. Несмотря на кажущуюся простоту этого элемента, у которого есть два принципиальных параметра, высота и ширина, выбор не является тривиальным делом. Но у нас есть золотое сечение, приблизительно 1:1.618, проверенное столетиями в архитектуре, книгоиздании, а теперь еще и в твитере.

Математическая уникальность

golden spiral

Золотая пропорция уникальна тем что если удалить из нее квадратную область то оставшийся прямоугольник опять будет иметь золотую пропорцию. Соответственно это можно продолжать дальше с оставшимся прямоугольником, а это значит что золотой прямоугольник можно использовать для создания рекурсивных фигур. В этой статье мы покажем как построить золотую спираль только на HTML и CSS.

<div id="container">
    <div class="cicle">
        <div>
            <div>
                <div>
                    <div class="cicle">
                        <div>
                            <div>
                                <div>
                                    <div class="cicle">
                                        <div>
                                            <div>
                                                <div></div>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

Каждый четвертый div имеет класс cycle, то есть спираль будет замыкаться каждые четыре цикла.

Золотая пропорция

Начнем с того что сделаем прямоугольник с золотой пропорцией, 288 × 1.618 = 466

#container > div {
    width: 932px;
    height: 576px;
}

Дальше нужно для всех вложенных блоков повторить пропорцию но при этом уменьшая. Логично это сделать процентами.

golden spiral

Приблизительное значение, 38.2%, получается из формулы – (100 × 1 − phi) ÷ phi. Итого, имеем:

.cycle,
.cycle > div > div {
    height: 38.2%;
    width: 100%; 
}

.cycle > div,
.cycle > div > div > div {
    width: 38.2%;
    height: 100%; 
}

То есть — каждый второй и каждый четвертый блок после первого .cycle мы делаем вертикальным, сам .cycle и каждый третий просто масштабируем.

Теперь покрасим как то блоки чтобы их можно было различать.

#container div {
    background-color: rgba(255,255,255,0.15);
}

На данный момент вот что получилось:

JS Bin

Уже выглядит довольно прикольно, но теперь, чтобы создать спираль, надо выровнять прямоугольники правильным образом. А именно так, что каждый следущий прямоугольник «закручивался» относительно предыдущего. Для это, при помощи абсолютного позиционирования прилепим их к определенной стороне родителя.

.cycle {
    position: absolute;
    top: 0; 
}
    .cycle > div {
        position: absolute;
        right: 0; 
    }
        .cycle > div > div {
            position: absolute;
            bottom: 0; 
        }
            .cycle > div > div > div {
                position: absolute;
                left: 0; 
            }

JS Bin

Скругление углов

Спиральная форма уже начинает прорисовываться, но теперь нужно срезать углы для полного ажура. Нас спасет border-radius. Но, нам неизвестны точно размеры сторон всех прямоугольников, поскольку мы выставляли их ширину процентами. Спецификация говорит что можно использовать проценты при задании размеров радиуса скругления, но, к сожалению это не работает как положено во всех браузерах. К счастью, оказывается, что если задать радиус скругления намного больше чем высота или ширина, то реальным радиусом станет меньшая сторона прямоугольника.

.cycle {
    -webkit-border-radius: 0px;
    -moz-border-radius: 0px;
    border-radius: 0px;
    -webkit-border-top-left-radius: 10000px;
    -moz-border-radius-topleft: 10000px;
    border-top-left-radius: 10000px; 
}
    .cycle > div {
        -webkit-border-radius: 0px;
        -moz-border-radius: 0px;
        border-radius: 0px;
        -webkit-border-top-right-radius: 10000px;
        -moz-border-radius-topright: 10000px;
        border-top-right-radius: 10000px; 
    }
        .cycle > div > div {
            -webkit-border-radius: 0px;
            -moz-border-radius: 0px;
            border-radius: 0px;
            -webkit-border-bottom-right-radius: 10000px;
            -moz-border-radius-bottomright: 10000px;
            border-bottom-right-radius: 10000px; 
        }
            .cycle > div > div > div {
                -webkit-border-radius: 0px;
                -moz-border-radius: 0px;
                border-radius: 0px;
                -webkit-border-bottom-left-radius: 10000px;
                -moz-border-radius-bottomleft: 10000px;
                border-bottom-left-radius: 10000px; 
            }

JS Bin В финальном примере добавлен скрипт для масштабирования в полную доступную ширину браузера, но скрипт не является моим интересом так что оставляю без комментариев.

JS Bin

comments powered by Disqus