Колесо фортуны в виде талисмана – удача в вашей жизни

На некоторых сайтах можно встретить колесо фортуны с призами. Работает так: нажимаете кнопку, колесо начинает крутиться, и на что показывает стрелка после остановки — это и есть ваш приз. Есть сервисы, которые предоставляют такое колесо как платную услугу, а мы сделаем своё и бесплатно:

❗️ В этом проекте довольно люто используется CSS 3. Мы о нём ещё не писали, но мы исправимся и напишем. Многие штуки в CSS-коде будут выглядеть непривычно, поэтому мы их объясним прямо в комментариях. Крепитесь.

Готовим страницу

Как обычно в наших проектах, на странице будет только разметка невидимых блоков — всё содержимое появится потом, из скрипта. Внутреннее устройство будет такое:

  • делаем главный блок deal-wheel, внутри которого будут находиться все элементы;
  • внутрь этого блока добавляем список spinner — это будут наши надписи на секторах;
  • туда же кладём блок с язычком барабана ticker, который укажет на приз и кнопку с классом btn-spin — она запустит колесо.

За остальное будет отвечать скрипт.

Колесо удачи Испытай удачу

Сразу добавим стили в отдельный файл style.css:

/* делаем везде так, чтобы свойства width и height задавали не размеры контента, а размеры блока */ * { box-sizing: border-box; } /* общие настройки страницы */ body { /* подключаем сетку */ display: grid; /* ставим всё по центру */ place-items: center; /* если что-то не помещается на своё место — скрываем то, что не поместилось */ overflow: hidden; }

Настраиваем общий блок

Задача общего блока — установить связи между элементами, распределить их внутри виртуальной сетки и настроить параметры отображения внутренних элементов.

Чтобы не перегружать код одними и теми же параметрами, будем использовать CSS-переменные. Они начинаются с двух дефисов и работают внутри того блока, в котором прописаны. Также эти переменные понадобятся нам при настройке анимации в скрипте.

Зачем нужны переменные в CSS

Добавим стили в файл style.css. Читайте комментарии, тут всё подробно объяснено:

/* общий блок для всех элементов */ .deal-wheel { /* задаём переменные блока, внутри которого всё будет рисоваться */ /* размеры колеса */ —size: clamp(250px, 80vmin, 700px); /* clamp — функция CSS, которая задаёт три размера: минимальное, предпочтительное и максимальное. В данном случае мы хотим, чтобы колесо было не меньше 250 пикселей, не больше 700 пикселей, но в идеале — 80% от безопасно малой высоты окна браузера */ /* настройки яркости и заливки фона секторов. Нам понадобится описать поведение градиента, это у нас делается через много переменных */ —lg-hs: 0 3%; —lg-stop: 50%; —lg: linear-gradient( hsl(var(—lg-hs) 0%) 0 var(—lg-stop), hsl(var(—lg-hs) 20%) var(—lg-stop) 100% ); /* добавляем позиционирование относительно других элементов */ position: relative; /* подключаем стандартную CSS-сетку */ display: grid; grid-gap: calc(var(—size) / 20); /* выравниваем содержимое блока по центру */ align-items: center; /* задаём имена областей внутри сетки — в CSS теперь можно прямо назвать эти области */ grid-template-areas: «spinner» «trigger»; /* устанавливаем размер шрифта */ font-size: calc(var(—size) / 21); } /* всё, что относится ко внутренним элементам главного блока, будет находиться в области сетки с названием spinner */ .deal-wheel > * { grid-area: spinner; } /* сам блок и кнопка будут находиться в области сетки с названием trigger и будут выровнены по центру */ .deal-wheel .btn-spin { grid-area: trigger; justify-self: center; }

Готовим переменные в скрипте

Так как на самой странице у нас только блоки, всё остальное содержимое будем делать и добавлять через скрипт script.js.

Первое, что нам понадобится, — завести все переменные, которые будем использовать в проекте. Начнём со списка призов. Обратите внимание, что цвета здесь указаны в системе HSL — hue, saturation, lightness (оттенок, насыщенность, яркость). Это не необходимость, можно было указать и в RGB, и в hex-значениях:

// надписи и цвета на секторах const prizes = [ { text: «Скидка 10%», color: «hsl(197 30% 43%)», }, { text: «Дизайн в подарок», color: «hsl(173 58% 39%)», }, { text: «Второй сайт бесплатно», color: «hsl(43 74% 66%)», }, { text: «Скидка 50%», color: «hsl(27 87% 67%)», }, { text: «Блог в подарок», color: «hsl(12 76% 61%)», }, { text: «Скидок нет», color: «hsl(350 60% 52%)», }, { text: «Таргет в подарок», color: «hsl(91 43% 54%)», }, { text: «Скидка 30% на всё», color: «hsl(140 36% 74%)», } ];

Теперь создадим переменные, через которые будем работать со всеми элементами на странице:

// создаём переменные для быстрого доступа ко всем объектам на странице — блоку в целом, колесу, кнопке и язычку const wheel = document.querySelector(«.deal-wheel»); const spinner = wheel.querySelector(«.spinner»); const trigger = wheel.querySelector(«.btn-spin»); const ticker = wheel.querySelector(«.ticker»);

Следующий шаг — переменные для разбивки блока на разноцветные секторы. Так как мы заранее не знаем, сколько у нас призов, то будем сразу всё высчитывать:

// на сколько секторов нарезаем круг const prizeSlice = 360 / prizes.length; // на какое расстояние смещаем сектора друг относительно друга const prizeOffset = Math.floor(180 / prizes.length); // прописываем CSS-классы, которые будем добавлять и убирать из стилей const spinClass = «is-spinning»; const selectedClass = «selected»; // получаем все значения параметров стилей у секторов const spinnerStyles = window.getComputedStyle(spinner);

Осталось добавить переменные, которые будут меняться в ходе работы скрипта:

// переменная для анимации⠀ let tickerAnim;⠀ // угол вращения let rotation = 0;⠀ // текущий сектор⠀ let currentSlice = 0;⠀ // переменная для текстовых подписей let prizeNodes;

Добавляем секторы и призы на экран

Теперь, когда у нас есть все нужные переменные, добавим призы в блок со списком «.spinner». Логика такая:

  1. Перебираем весь список с призами, один за одним, по очереди.
  2. Сразу считаем угол поворота для каждой надписи.
  3. Добавляем в конец списка HTML-код, чтобы у нас появился новый элемент маркированного списка.
  4. В этом же коде добавляем ему стиль для поворота на нужный угол.

// расставляем текст по секторам const createPrizeNodes = () => { // обрабатываем каждую подпись prizes.forEach(({ text, color, reaction }, i) => { // каждой из них назначаем свой угол поворота const rotation = ((prizeSlice * i) * -1) — prizeOffset; // добавляем код с размещением текста на страницу в конец блока spinner spinner.insertAdjacentHTML( «beforeend», // текст при этом уже оформлен нужными стилями `

  • ${text}
  • ` ); }); };
    Также сделаем разбивку по цветным секторам: просто добавим нужные параметры к стилю у класса «.spinner»:

    // рисуем разноцветные секторы const createConicGradient = () => { // устанавливаем нужное значение стиля у элемента spinner spinner.setAttribute( «style», `background: conic-gradient( from -90deg, ${prizes // получаем цвет текущего сектора .map(({ color }, i) => `${color} 0 ${(100 / prizes.length) * (prizes.length — i)}%`) .reverse() } );` ); };

    Теперь соберём всё вместе и сразу создадим объект с призами, чтобы потом было из чего выбирать:

    // создаём функцию, которая нарисует колесо в сборе const setupWheel = () => { // сначала секторы createConicGradient(); // потом текст createPrizeNodes(); // а потом мы получим список всех призов на странице, чтобы работать с ними как с объектами prizeNodes = wheel.querySelectorAll(«.prize»); }; // подготавливаем всё к первому запуску setupWheel();

    После запуска вам может показаться, что наш код не работает. Но на самом деле это не так: код работает как нужно, просто мы не добавили в стили новые параметры, которые использовали в коде — spinner и prize. Исправим это на следующем шаге.


    Сохраняем файлы и открываем страницу в браузере.

    Как сделать амулет удачи?

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

    Носитель может быть любым:

    1. дерево;
    2. камень;
    3. глина;
    4. металл;
    5. картон;
    6. плотная бумага.

    Если вы сделаете амулет из бумаги и картона (пентакль), то можно залить его расплавленным воском.

    Но также допускается заклеить артефакт скотчем, чтобы символ не стерлись и бумага не помялась. Активируется артефакт верой в его силу.

    Бывали случаи, когда нарисованный символ начинал работать сразу же после его изображения на простом листе бумаги.

    Исправляем внешний вид колеса

    Сейчас блок с колесом выглядит как прямоугольник, потому что зависит от содержимого с текстом. Чтобы это стало похоже на круг, добавим стили специально для секторов колеса:

    /* сектор колеса */ .spinner { /* добавляем относительное позиционирование */ position: relative; /* подключаем сетку */ display: grid; /* выравниваем всё по центру */ align-items: center; /* добавляем элемент в сетку */ grid-template-areas: «spinner»; /* устанавливаем размеры */ width: var(—size); height: var(—size); /* поворачиваем элемент */ transform: rotate(calc(var(—rotate, 25) * 1deg)); /* рисуем круглую обводку, а всё, что не поместится, — будет скрыто за кругом */ border-radius: 50% }; /* всё, что внутри этого блока, будет находиться в области сетки с названием spinner */ .spinner * { grid-area: spinner; }

    У нас появились нормальное деление круга на цветные секторы, но все надписи слиплись. Всё дело в относительном позиционировании. Так как мы ещё не задавали правила расстановки текста, каждый элемент получился на одном и том же месте. Чтобы их разнести по секторам, добавим стили для текста:

    /* текст на секторах */ .prize { /* включаем «гибкую» вёрстку */ display: flex; align-items: center; /* задаём отступы от краёв блока */ padding: 0 calc(var(—size) / 6) 0 calc(var(—size) / 20); /* устанавливаем размеры */ width: 50%; height: 50%; /* устанавливаем координаты, относительно которых будем вращать текст */ transform-origin: center right; /* поворачиваем текст */ transform: rotate(var(—rotate)); /* запрещаем пользователю выделять мышкой текст на секторах */ user-select: none; }

    Стало лучше, но кнопка теперь слишком мелкая. Нужно исправить.

    Мастер-класс по изготовлению амулета

    Чтобы изготовить талисман “Колесо Фортуны”, вам понадобятся бумага желтого или зеленого цвета, такие же фломастер и свеча, ножницы, а также пинцет, воск и карандаш. Если рисуете колесо на желтой бумаге, возьмите зелёный фломастер, и наоборот. Цвет свечи роли не играет. Останьтесь в одиночестве, предварительно потренировавшись в нанесении рисунка.

    1. Начните с изображения круга. Обведите монету, чашку или блюдце — размер не важен, но слишком большой амулет неудобно носить.
    2. Расплавьте воск. Осторожно нанесите изображение, сначала карандашом, подом обведите фломастером. Ни в коем случае не допускайте искажений рисунка. Пропорции важнее красоты. Именно поэтому мы посоветовали вам сначала потренироваться.
    3. Нанесите картинку с двух сторон. Вырежьте колесо. Окуните на минуту в расплавленный воск. Осторожно вытащите его пинцетом и дайте воску застыть. Амулет готов, осталось только зарядить его, и можно пользоваться.

    Кнопка запуска

    Сделаем текст на кнопке того же размера, что и надписи на секторах. Заодно пропишем внешний вид неактивной кнопки: пусть она будет полупрозрачной и с другим курсором. Тогда сразу будет понятно — кнопка работает, нажимать пока нельзя.

    /* кнопка запуска колеса */ .btn-spin { color: white; background: black; border: none; /* берём размер шрифта такой же, как в колесе */ font-size: inherit; /* добавляем отступы от текста внутри кнопки */ padding: 0.9rem 2rem 1rem; /* скругляем углы */ border-radius: 0.5rem; /* меняем внешний вид курсора над кнопкой на руку*/ cursor: pointer; } /* если кнопка нажата и неактивна */ .btn-spin:disabled { /* меняем внешний вид курсора */ cursor: progress; /* делаем кнопку полупрозрачной */ opacity: 0.25; }


    Так кнопка выглядит гораздо лучше.

    Кому подойдет оберег

    В отличие от некоторых славянских оберегов, Колесо Фортуны подойдет любому, кто верит в его магическую силу. Он защищает учащихся, бизнесменов, спортсменов, путешественников — тех, чья деятельность связана с риском, кто кроме собственных способностей нуждается в благосклонности судьбы.

    Кроме того, как можно скорее амулет необходимо приобрести тому, кто:

    • часто болеет или рискует здоровьем (например, на работе);
    • потерял работу и стабильный доход;
    • имеет проблемы с общением, не может устроить личную жизнь;
    • не уверен в себе, испытывает страх, думает о самоубийстве;
    • запутался в себе, не знает, что делать дальше.

    Оберег нужен и тем, у кого все хорошо — в качестве профилактики. Он приумножит хорошее, поможет достичь спокойствия, процветания, стабильности и гармонии.

    Добавляем язычок

    Язычок — это такой указатель на колесе, который всё время указывает на какой-то сектор. При вращении настоящего колеса фортуны металлический язычок касается столбиков на границе секторов и отклоняется в сторону. Так легко можно определить — перескочил язычок на новый сектор или скорости колеса не хватило и он остался на столбике, указывая на предыдущее значение.

    Пока просто нарисуем язычок, а механику добавим чуть позже:

    /* язычок */ .ticker { /* добавляем относительное позиционирование */ position: relative; /* устанавливаем размеры */ left: calc(var(—size) / -15); width: calc(var(—size) / 10); height: calc(var(—size) / 20); /* фон язычка */ background: var(—lg); /* делаем так, чтобы язычок был выше колеса */ z-index: 1; /* форма язычка */ clip-path: polygon(20% 0, 100% 50%, 20% 100%, 0% 50%); /* устанавливаем точку, относительно которой будет вращаться язычок при движении колеса */ transform-origin: center left; }

    Теперь всё на месте.

    Амулет Колесо Фортуны: значение

    Одним привлечением удачи символизм колеса не исчерпывается. Круглый амулет напомнит вам, что жизнь — это дорога без конца и края. Конец одного этапа — лишь начало следующего, не стоит отчаиваться и бросать начатое на полпути. Что толку от благосклонности судьбы, если вы не знаете, куда и зачем “идете”? Медитация на заветный оберег поможет вам, если вы чувствуете, что потеряли направление в жизни.

    Помимо колеса, талисман часто содержит определенный набор символов. По сути, он как бы говорит энергии: “Собирайся здесь!”. Удача и богатство придут в вашу жизнь вместе с позитивными магическими силами. Причем речь идет не только о деньгах или другом имуществе. Владелец Колеса Фортуны может стать более богатым духовно, достичь успехов в творчестве, личной жизни, науке и магии.

    На самом глубинном, сакральном уровне, о котором задумываются только мудрейшие из магов, амулет символизирует всю Вселенную. В древности люди считали, что земля имеет форму диска или колеса. В данном контексте её настоящий вид значения не имеет. Куда важнее мистическое значение — вы как будто носите на груди маленькую модель всей нашей планеты, на которой миллионы лет живут люди, познавая и радость, и боль.

    Задаём количество оборотов

    Если мы в жизни запустим такое колесо, то оно постепенно будет замедляться. За это отвечает сила трения и разные физические факторы. Чтобы нам реализовать такую же механику, мы заранее определим количество градусов, на которое повернётся колесо. Для этого добавим функцию, которая вернёт нам случайным образом некоторое число в зависимости от минимального и максимального параметра вращения:

    // функция запуска вращения с плавной остановкой const spinertia = (min, max) => { min = Math.ceil(min); max = Math.floor(max); return Math.floor(Math.random() * (max — min + 1)) + min; };

    Запускаем колесо

    Чтобы запустить колесо, нужно нажать на кнопку. Но так как мы в HTML-файле не прописывали обработчик нажатия, добавим такой обработчик в JS-файле. Читайте комментарии, чтобы разобраться подробнее, что происходит в этом блоке:

    // отслеживаем нажатие на кнопку trigger.addEventListener(«click», () => { // делаем её недоступной для нажатия trigger.disabled = true; // задаём начальное вращение колеса rotation = Math.floor(Math.random() * 360 + spinertia(2000, 5000)); // убираем прошлый приз prizeNodes.forEach((prize) => prize.classList.remove(selectedClass)); // добавляем колесу класс is-spinning, с помощью которого реализуем нужную отрисовку wheel.classList.add(spinClass); // через CSS говорим секторам, как им повернуться spinner.style.setProperty(«—rotate», rotation); // возвращаем язычок в горизонтальную позицию ticker.style.animation = «none»; // запускаем анимацию вращение runTickerAnimation(); });

    Рейтинг
    ( 1 оценка, среднее 4 из 5 )
    Понравилась статья? Поделиться с друзьями:
    Для любых предложений по сайту: [email protected]