Используйте тригонометрические функции для рисования кривой графики и отображения анимации в CSS.

анимация CSS
Используйте тригонометрические функции для рисования кривой графики и отображения анимации в CSS.

недавно использовалcss-doodleРеализуйте некоторые эффекты CSS.

css-doodle — это библиотека на основе веб-компонентов. Позволяет нам быстро создавать страницы на основе макета CSS Grid для достижения различных эффектов CSS (может называться искусством CSS). Следующие несколько статей могут быть связаны с ним.

Конечно, главный герой этой статьи не css-doodle.

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

Эта статья познакомит вас с небольшой техникой рисования кривой графики с помощью тригонометрических функций в CSS.

Понять коробку-тень

Во-первых, для обзораbox-shadowэто свойство. Основное использование атрибута — создание тени на элементе.

Для получения дополнительной информации о тенях сначала ознакомьтесь с этой статьей:Уловки и детали CSS-теней, о которых вы не знали

Кратко упомянем первый трюк с тенями, который будет использован в этой статье:

Дублированное изображение/изображение проекта с тенью

Когда третий, четвертый параметр расширения blur radius и радиус box-shadow равны нулю, мы можем получить одинаковый размер элемента и тень:

div {
    width: 80px;
    height: 80px;
    border: 1px solid #333;
    box-sizing: border-box;
    box-shadow: 80px 80px 0 0 #000;
}

Получил следующий результат:

image

Теней может быть несколько

Второй трюк,box-shadowДопускается несколько теней, и их координаты полностью контролируются.

Да, мы можем определить несколько теней для такого элемента и использовать первый и второй параметры тени для управления ее координатами относительно элемента:

div {
    width: 80px;
    height: 80px;
    border: 1px solid #333;
    box-sizing: border-box;
    box-shadow: 
        80px 80px 0 0 #000,
        70px 70px 0 0 #000,
        ...
        60px 60px 0 0 #000;
}

Использование тригонометрических функций в теневых координатах

Продолжать.接下来,我们尝试在阴影的坐标中引入三角函数。

Почему треугольная функция, а не стандартное уравнение, эллиптическое стандартное уравнение или другая графическая функция? Конечно, это тоже возможно, только вот с функциями треугольникаcosилиsinМожно получить кривые, которые было бы трудно получить непосредственно с помощью CSS.

С сомнениями, давайте сначала спустимся вниз, предположив, что мы хотим реализовать такую ​​​​кривую:

image

Что можно сделать с помощью CSS?

Некоторые возможные способыclip-path, Или какой-нибудь хитрый, но бесполезный, используйтеtext-decorationволнистое подчеркивание вwavyили используйте наложение градиента.

Конечно, есть также способ использоватьbox-shadowи тригонометрические функции.

Тригонометрические функции

Кхм, краткий обзор тригонометрической функции внутри греха, потому что преобразование изображения кривой еще не полностью возвращено учителю.

image

Если у нас есть div 1x1, его множественные тени можно расположить как график функций синуса/косинуса, разве это не кривая?

Как использовать тригонометрические функции sin/cos в CSS

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

К счастью, некоторые предшественники помогли закончить эту работу:

Проще говоря, с помощьюРазложение Тейлора тригонометрических функций, используйте функцию Sass для имитации sin(), cos(), tan() тригонометрических функций:

image

Так как расширение бесконечно, получить очень точное значение при использовании функции Sass для симуляции невозможно, но для ежедневного рисования вполне достаточно (), tan():

@function fact($number) {
    $value: 1;
    @if $number>0 {
        @for $i from 1 through $number {
            $value: $value * $i;
        }
    }
    @return $value;
}

@function pow($number, $exp) {
    $value: 1;
    @if $exp>0 {
        @for $i from 1 through $exp {
            $value: $value * $number;
        }
    }
    @else if $exp < 0 {
        @for $i from 1 through -$exp {
            $value: $value / $number;
        }
    }
    @return $value;
}

@function rad($angle) {
    $unit: unit($angle);
    $unitless: $angle / ($angle * 0 + 1);
    @if $unit==deg {
        $unitless: $unitless / 180 * pi();
    }
    @return $unitless;
}

@function pi() {
    @return 3.14159265359;
}

@function sin($angle) {
    $sin: 0;
    $angle: rad($angle);
    // Iterate a bunch of times.
    @for $i from 0 through 20 {
        $sin: $sin + pow(-1, $i) * pow($angle, (2 * $i + 1)) / fact(2 * $i + 1);
    }
    @return $sin;
}

@function cos($angle) {
    $cos: 0;
    $angle: rad($angle);
    // Iterate a bunch of times.
    @for $i from 0 through 20 {
        $cos: $cos + pow(-1, $i) * pow($angle, 2 * $i) / fact(2 * $i);
    }
    @return $cos;
}

@function tan($angle) {
    @return sin($angle) / cos($angle);
}

Поскольку разложение Тейлора для sin и cos окончательно вычислено выше, используются только 20 слоев циклов, поэтому, когда входящее значение слишком велико, возникает большая ошибка. После тестирования входящее значение находится в пределах [-20, 20], а точность по-прежнему очень высока.

Взяв в качестве примера функцию sin, значение x находится между [-π, π], что может охватывать все диапазоны значений sin(x), поэтому диапазона [-20, 20] вполне достаточно, мы только Нужно постараться, чтобы входящее значение x попадало в диапазон этой области, чтобы не было слишком большой ошибки.

Ну, так много предзнаменований, затем используя приведенный выше тест функции sin, предполагая, что у нас есть такая структура:

<div></div>
div {
    width: 1px;
    height: 1px;
    background: #000;
    border-radius: 50%;
}

Давайте воспользуемся Sass для реализации 50-слойного цикла, конечно, где x-координата тени использует функцию sin:

@function shadowSet($vx, $vy) {
    $shadow : 0 0 0 0 #000;
    
    @for $i from 0 through 50 { 
        $x: sin($i / 8) * $vx;
        $y: $i * $vy;
        
        $shadow: $shadow, #{$x} #{$y} 0 0 rgba(0, 0, 0, 1);
    }
    
    @return $shadow;
}

div {
    width: 1px;
    height: 1px;
    background: #000;
    border-radius: 50%;
    box-shadow: shadowSet(4px, 1px);
}

надsin($i / 8), деление на 8 здесь должно сделать диапазон значений области действия, передаваемой всем sin(x), равным [0, 6,25].Когда область действия sin(x) равна [0, 2π], полная строка можно нарисовать одну кривую. Эту 8 можно регулировать по количеству петель.

Собственно, мы получаемbox-shadowследующим образом:

{
    box-shadow: 
	0 0 0 0 black, 0.4986989335px 1px 0 0 black, 0.989615837px 2px 0 0 black, 
	1.4650901163px 3px 0 0 black, 1.9177021544px 4px 0 0 black, 2.3403890918px 5px 0 0 black, 
	2.7265550401px 6px 0 0 black, 3.0701740089px 7px 0 0 black, 3.3658839392px 8px 0 0 black, 
	3.6090703764px 9px 0 0 black, 3.7959384774px 10px 0 0 black, 3.9235722281px 11px 0 0 black, 
	3.9899799464px 12px 0 0 black, 3.9941253622px 13px 0 0 black, 3.9359437875px 14px 0 0 black, 
	3.8163431264px 15px 0 0 black, 3.6371897073px 16px 0 0 black, 3.4012791593px 17px 0 0 black,
	3.1122927876px 18px 0 0 black, 2.7747401278px 19px 0 0 black, 2.3938885764px 20px 0 0 black,
	1.9756811944px 21px 0 0 black, 1.5266439682px 22px 0 0 black, 1.0537839735px 23px 0 0 black,
	0.5644800322px 24px 0 0 black, 0.0663675689px 25px 0 0 black, -0.4327805381px 26px 0 0 black,
	-0.9251752496px 27px 0 0 black, -1.4031329108px 28px 0 0 black, -1.8591951521px 29px 0 0 black,
	-2.286245275px 30px 0 0 black, -2.677619305px 31px 0 0 black, -3.0272099812px 32px 0 0 black,
	-3.3295620582px 33px 0 0 black, -3.5799574329px 34px 0 0 black, -3.7744887692px 35px 0 0 black,
	-3.9101204707px 36px 0 0 black, -3.9847360499px 37px 0 0 black, -3.9971711559px 38px 0 0 black,
	-3.9472317429px 39px 0 0 black, -3.8356970987px 40px 0 0 black, -3.6643076841px 41px 0 0 black,
	-3.4357379737px 42px 0 0 black, -3.1535547213px 43px 0 0 black, -2.8221613023px 44px 0 0 black,
	-2.446729px 45px 0 0 black, -2.03311631px 46px 0 0 black, -1.58777752px 47px 0 0 black,
	-1.1176619928px 48px 0 0 black, -0.630105724px 49px 0 0 black, -0.1327168662px 50px 0 0 black;
}

Фактически полученное изображение выглядит следующим образом:

image

CodePen Demo -- sass2sin Line

Цвет управления и начальное направление

Взгляните на этот метод, реализованный Sass выше.@function shadowSet($vx, $vy)$vx,$vyИспользуется для управления амплитудой и размытостью изображения, мы добавляем еще один, который управляет начальным направлением$direction, который управляет количеством теневых слоевcount, 控制颜色的color:

@function shadowSet($vx, $vy, $direction, $count, $color) {
    $shadow : 0 0 0 0 $color;
    
    @for $i from 0 through $count { 
        $x: sin($i / 8) * $vx * $direction;
        $y: $i * $vy;
        
        $shadow: $shadow, #{$x} #{$y} 0 0 $color;
    }
    
    @return $shadow;
}
.line {
    width: 1px;
    height: 1px;
    margin: 10vh auto;
    background: #000;
    border-radius: 50%;
    box-shadow: shadowSet(4px, 1px, 1, 50, #000);
}

.reverseline {
    width: 1px;
    height: 1px;
    margin: 10vh auto;
    background: #000;
    border-radius: 50%;
    box-shadow: shadowSet(8px, 2px, -1, 100, red);
}

image

контрольный цвет

Сделав еще один шаг, мы можем использовать различные цветовые функции Sass для изменения цвета:

@function shadowSetColor($vx, $vy, $direction, $count, $color) {
    $shadow : 0 0 0 0 $color;
    
    @for $i from 0 through $count { 
        
        $color: lighten($color, .5);
        
        $x: sin($i / 8) * $vx * $direction;
        $y: $i * $vy;
        
        $shadow: $shadow, #{$x} #{$y} 0 0 $color;
    }
    
    @return $shadow;
}

.colorline {
    width: 5px;
    height: 5px;
    margin: 10vh auto;
    background: green;
    border-radius: 50%;
    box-shadow: shadowSetColor(8px, 2px, -1, 100, green);
}

выше, с помощьюlightenЭта функция делает цвет светлее, изменяя его значение яркости, создавая новый цвет.

Конечно, есть много других цветовых функций в SASS:

  • adjust-hue(color,градусов): создать новый цвет, изменив значение оттенка цвета;
  • lighten(color,количество): изменив значение яркости цвета, сделайте цвет ярче и создайте новый цвет;
  • darken(color,количество): изменив значение яркости цвета, затемните цвет и создайте новый цвет;
  • saturate(color,количество): Создайте новый цвет, изменив значение насыщенности цвета, чтобы сделать цвет более насыщенным.
  • desaturate(color,количество): создайте новый цвет, изменив значение насыщенности цвета, чтобы сделать цвет менее насыщенным;

Чтобы узнать больше о цветовых функциях Sass, ознакомьтесь с этой статьей:Основы Sass — цветовые функции

Хорошо, посмотрите на эффект на этот раз:

image

CodePen Demo -- sass2sin Line

Использование в css-doodle

Хорошо, все предзнаменования выше должны использовать это в некоторых реальных творческих идеях.

В css-doodle используется функция веб-компонента. Когда вам нужны тригонометрические функции, вы можете напрямую использовать функцию Math, предоставляемую JavaScript, что более удобно.

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

Юань ЧуанПреподаватель, автор библиотеки css-doodle, использует рисование на чистом CSS, реализованное с использованием описанных выше методов, на своей фоновой доске на домашней странице Codepen:

bg-yuanchuan

Codepen Demo -- border-radius

Я также попытался использовать этот трюк и сделал пару:

Codepen Demo - CSS-Doodle Рыба 🐟 & Морские водоросли

наконец

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

1,Почему нужно использоватьbox-shadow, Не можете сложить div напрямую?

Да, использовать несколькоbox-shadowПросто потому, что это может быть помечено больше, div фиксируется. Более ровные, готовые подбрасывать, использовать множественные постепенные изменения.

2,Две приведенные выше демонстрации нарисованы на чистом CSS?

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

3.Какая польза?

Ну а работает ли это вопрос философский. По крайней мере, я думаю, что это все еще интересно.


Ну вот и конец этой статьи, надеюсь она вам поможет :)

Другие замечательные технические статьи по CSS собраны в моемGithub -- iCSS, продолжайте обновлять, добро пожаловать, нажмите звездочку, чтобы подписаться на коллекцию.

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