Вращение 2D объекта по окружности
Ты скорее всего знаешь что во всех современных движках, таких как Unity вращение осуществляется с помощью функции, но нам интересно, как можно написать алгоритм
вращения своими руками.
Если проще то наш алгоритм работает так.
Мы представляем окружность, где:
- Центр это точка, вокруг которой мы вращаем объект.
- Радиус — расстояние от центра до вращаемого объекта.
Давайте взглянем на рисунок ниже:
Дано: длинна радиуса, координаты точки вращения, угол АОВ, АВ перпендикулярен оси ОХ.
Задача: Задать вращение точки А на 360 градусов с помощью формулы.
Рассмотрим: треугольник ОАВ:
угол ОВА — прямой => треугольник ОАВ — прямоугольный треугольник;
тогда:
гипотенуза = радиусу окружности с центром в точке О
угол поворота = от 1 до 360 градусов
тогда чтобы найти катеты ОВ и АВ нужно:
АВ = радиус * cos(угла поворота),
ОВ = $inline$радиус * sin(угла поворота)$inline$
Теперь когда мы знаем размеры катетов
мы составим формулу:
для координаты по x:$inline$позиция по x = радиус * cos(угла поворота) + начальная позиция по x$inline$,
и для координаты по y: $inline$позиция по y = радиус * sin(угла поворота) + начальная позиция по y$inline$
Давайте попробуем применить формулы:
import pygame, math #colors black = (0, 0, 0) size = (500, 500) screen = pygame.display.set_mode(size) a = b = 200 clock = pygame.time.Clock() FPS = 60 for i in range(1, 361, 3): clock.tick(FPS) angle = i * 3.14 / 180 a = 100 * math.cos(angle) + 300 b = 100 * math.sin(angle) + 300 screen.fill(black) pygame.draw.circle(screen, (122, 0, 0), (int (a), int (b)), 6) pygame.display.update()
Не сложно догадаться что делает этот код, а именно вращает наш кружок по оси, но почему лишь один раз?
Давайте вспомним уроки геометрии в седьмом классе: градусная мера угла не может превышает 360 градусов.
А если попробуем обнулять угол вращения, когда тот будет больше 360 градусов, давайте посмотрим что из этого выйдет:
import pygame, math #colors red = (122 , 0, 0) green = (0, 122, 0) black = (0, 0, 0) size = (500, 500) screen = pygame.display.set_mode(size) a = b = 200 i = 0 clock = pygame.time.Clock() FPS = 60 while True: clock.tick(FPS) for event in pygame.event.get(): if event.type == pygame.QUIT: quit() screen.fill(black) pygame.draw.circle(screen, red, (int (a), int (b)), 6) if i 360 градусов нет, а кружок прошел свой путь
Этот код позволяет вращать кружок по оси бесконечно.
Однако у этой формулы есть один недостаток: можно вращать объекты только на 1 оборот. Это значит что нам нужна другая формула.

Давайте улучшим нашу формулу:
Дано:
треугольник ОАВ — прямоугольный
катет 1 = x1 — начальная координата X
катет 2 = y1 — начальная координата y
Задача:
улучшить формулу так, что-бы можно было вращать точку А на неизвестный угол.
Решение:
Из предыдущей задачи мы знаем что:
$inline$$inline$xPos = (lineLong * cos(a)) + StartPosX$inline$$inline$. => $inline$cos(a) = xPos — startPosX: (lineLong )$inline$
И теперь мы можем вывести формулу по нахождению угла a
$inline$yPos = (lineLong * sin(a)) + StartPosY$inline$ => $$display$$a = arccos((xPos — startPosX): lineLong)$$display$$.
А сейчас обновим нашу формулу и получим: $$display$$xPos = (lineLong * cos(a +b)) + startPosX$$display$$
Теперь у нас есть формула которая позволяет бесконечно вращать точку по окружности: $$display$$xPos = (lineLong * cos(a +arccos((xPos — startPosX): lineLong))) + startPosX$$display$$
Давайте напишем код, который будет вращать наш объект по нажатию на клавишу.
import pygame, math #colors black = (0, 0, 0) green = (0, 122, 0) size = (600, 600) screen = pygame.display.set_mode(size) a = b = 500 i = 0 clock = pygame.time.Clock() FPS = 60 while True: clock.tick(FPS) for event in pygame.event.get(): if event.type == pygame.QUIT: quit() keys = pygame.key.get_pressed() if keys[pygame.K_RIGHT]: angle = i * 3.14 / 180 l = math.acos((a - 400) / math.sqrt(500 ** 2 - 400 **2)) int(l) a = (100 * math.cos(angle + l)) + 400 b = (100 * math.sin(angle + l)) + 400 i -= 3 elif keys[pygame.K_LEFT]: angle = i * 3.14 / 180 l = math.acos((a - 400) / math.sqrt(500 ** 2 - 400 **2)) int(l) a = (100 * math.cos(angle + l)) + 400 # 400 - начальная точка по х и по у b = (100 * math.sin(angle + l)) + 400 i += 3 screen.fill(black) pygame.draw.circle(screen, green, (int (a), int (b)), 6) pygame.display.update()
Примерно таком образом решается эта задача.
Надеюсь, ты смог извлечь полезную информацию из моего поста, желаю удачно применить полученные знания на практике
Создание вращающегося логотипа с помощью ImageMagick и FFMPEG
Статья может заинтересовать тех, кто хочет слегка оживить оформление своего видеоканала, а также тех, кто только начал работать с указанными в заголовке инструментами. Уверенные же пользователи, рассчитываю, дополнят мой материал.
Задумался, как можно оживить логотип, который накладываю на видеоролики неких спортивных мероприятий. Возникла идея сделать поворачивающийся вокруг своей вертикальной оси каждые секунд 20 логотип. В результате хотелось получить нечто подобное:
Для выполнения задачи понадобится система с установленными imagemagick и ffmpeg. Для формирования команд утилите imagemagick будет использоваться bash. Что повлечет за собой использование утилиты bc, т.к. математика в bash довольно простая и тригонометрические функции вычислить затруднительно.
С помощью python, например, тоже самое сделать еще проще, в нем-то синус и косинус вычисляются.
Для создания видео создадим N кадров, за которые логотип сделает полный оборот, затем превратим их в видеофайл.
По сути, вращение — это последовательное сжатие и расширение изображения по одному из измерений. Если мы хотим получить эффект равномерного вращения вокруг вертикальной оси — ширина изображения будет изменяться кратно значению функций синус или косинус.
Начальное состояние для нас — это видимый в полный размер логотип, поэтому для изменения ширины изображения будем умножать его ширину на косинус (его значение в нуле как раз равно единице).
Вращение изображения для данных целей можно поделить на 4 этапа:
— изображение сужается;
— расширяется, но к зрителю повернуто обратной стороной;
— сужается обратной стороной к зрителю;
— расширяется до исходных размеров.
Сформируем базовый набор кадров построим для вращения на 0-90 градусов, а кадры для остальных 270 получим немного их преобразовывая. Цикл, соответственно, будет не от 0 до 360 градусов, а от 0 до 90.
Пропишем путь к нашему логотипу, чтобы потом обращаться к нему коротким $logo:
logo=../../logo/Moto_Gymkhana_transparent.png
Для удобства введем переменные равные ширине и высоте логотипа, так будет проще подправить скрипт под другую картинку:
width=842 height=595
Заведем переменную, равную количеству кадров, за которые логотип совершит четверть оборота. Она понадобится один раз — для вычисления шага, с которым должен вычисляться угол поворота.
Frames=15
В цикле понадобится:
— вычислить, какова будет ширина изображения при его повороте на заданный переменной «n» угол;
— создать пустой холст размером, скажем 850×600;
— добавить в его центр сжатое по ширине изображение.
for (( n=0; n
Разберем код по частям.
Вычислить ширину изображения под данным углом:
oWidth=$(printf %.$2f $(echo "$width*(c($n*4*a(1)/180))+1" | bc -l))
Удобнее будет разбирать этот кусок справа налево:
"| bc -l" указывает, что вычисляться это будет утилитой bc.
Т.к. косинус в утилите «bc» принимает на вход значения в радианах, а числа пи в bash нет — используем следующее выражение:
c($n*4*a(1)/180) — где
«c» — косинус,
$n — угол в градусах узменяющийся в цикле;
a(1) — арктангенс единицы, равный пи/4. Поэтому 4*a(1) это способ записать число пи. На 180 делим чтобы перейти от радиан к градусам.
Таким образом, "$width*(c($n*4*a(1)/180))" — ширина умноженная на косинус угла «n».
"+1" после этого выражения для того, чтобы ширина изображения не принимала значения 0. Попытку сделать изображение нулевой ширины не поймет ImageMagick.
$(printf %.$2f $(echo "$width*(c($n*4*a(1)/180))+1" | bc -l)) — вычислить значение ширины для данного угла и вывести, округлив до целого.
convert -size 850x600 xc:transparent -background none \ \( -alpha set -channel A -evaluate add -60% $logo -geometry $oWidth\ x$height\! \)\ -gravity center -composite ./tmp/$n.png
convert -size 850x600 xc:transparent -background none — создать прозрачный холст размером 640x360 без заднего фона.
Последующая часть команды взята в экранированные "\" скобки чтобы она выполнялась изолированно. Это важно, иначе изменение размера коснется и холста.
-alpha set — включить канал прозрачности.
-channel A -evaluate add -60% — добавить к значению канала А всех пикселей изображения "-60%".
$logo- путь к изображению.
-geometry $oWidth\ x$height\! — изменить размер изображения.
"-geometry AxB" изменит размеры изображения, но сохранит соотношение сторон. Т.е. если мы попытаемся убавить ширину — высота изображения тоже уменьшится чтобы сохранить соотношение «ширина х высота», а выше и ниже появятся пустые области.
"-geometry AxB\!" не бедут пытаться сохранить соотношение «ширина х высота», а изменит их независимо друг от друга.
-gravity center — разместить посередине.
-composite — объединить изображения.
./tmp/$n.png — сохранить файл в папку «tmp», назвав текущим значением переменной «n».
Вид с угла в 54 градуса:

Из этого эталонного набора изображений создадим 4 кадра будущей анимации.
Пусть логотип вращается по часовой стрелке если смотреть сверху. Для придания объема изображению добавим «тень» сдвинутую вправо или влево в зависимости от того, куда на кадре вращается изображение. И отразим изображение слева-направо на кадрах, где логотип повернут к зрителю задней стороной. «Тень» на этих же кадрах будет добавлена не под исходное изображение, а поверх него, чтобы создать эффект оборотной стороны логотипа.
Рассмотрим подробно выражение для первой четверти поворота. Остальные будут понятны по аналогии. Лишь акцентирую внимание на отличиях от первого:
convert tmp/$n.png \ \( +clone -background '#cccf' -shadow 100x8+$shadowShift-3 \)\ -background none -compose Src_Over -layers merge \ -gravity center tmp/logo$(expr $(( 1000+n ))).png
convert tmp/$n.png — взять за основу исходное изображение.
\( +clone -background '#cccf' -shadow 100x8+$shadowShift-3 \) — склонировать и создать тень изображения.
Цвет заданный опцией background задаст цвет тени.
Насколько тень непрозрачна (в процентах) и размыта задается параметром «100x5».
Сдвиг тени относительно оригинального изображения задается как +x+y. В нашем случае сдвиг по вертикали постоянен (3 пикселя вверх), а сдвиг по горизонтали задается переменной shadowShift.
Значение этой переменной вычислим аналогично сжатию исходного кадра по вертикали. Только возьмем синус угла, а не косинус, т.к. сдвиг при нулевом угле должен быть ноль.
shadowShift=$(printf %.$2f $(echo «15*(s($n*4*a(1)/180))+1» | bc -l))
Для первой и второй четверти тень должна быть сдвинута вправо, поэтому значение shadowShift берем со знаком «плюс», для третьей и четвертой — со знаком «минус».
-background none -compose Dst_Over -layers merge -gravity center -depth 8 tmp/logo$(expr $(( 1000+n ))).png
Тут важная опция это -compose. Она задает какое из изображений будет расположено сверху.
Для первой четверти поворота, сверху располагается сам логотип, поэтому Dst_Over. Для второй и третьей четверти будет прописано Src_Over (тень сверху).
-layers merge -gravity center — совместить слои, расположить посередине.
tmp/logo$(expr $(( 1000+n ))).png — сохранить под именем logo + «1000+значение n» в папку tmp.
имя такое чтобы имена кадров сразу отсортировались в алфавитном порядке и их было удобно отдать на обработку ffmpeg'у.
Для кадров второй четверти поворота будет «1800-n», для третьей «2000+n», для четвертой «2800-n».
Для второй и третьей четвертей появится опция -flop — отразить изображение слева-направо. Из-за этого, кстати, понадобится изменить знак смещения тени на противоположный.
Код для всех четырех четвертей поворота:
convert tmp/$n.png \( +clone -background '#cccf' -shadow 100x8+$shadowShift-3 \) \ -background none -compose Dst_Over -layers merge -gravity center -depth 8 tmp/logo$(expr $(( 1000+n ))).png convert tmp/$n.png \( +clone -background '#cccf' -shadow 100x8-$shadowShift-3 \) \ -background none -compose Src_Over -layers merge -gravity center -flop tmp/logo$(expr $(( 1800-n ))).png convert tmp/$n.png \( +clone -background '#cccf' -shadow 100x8+$shadowShift-3 \) \ -background none -compose Src_Over -layers merge -gravity center -flop tmp/logo$(expr $(( 2000+n ))).png convert tmp/$n.png \( +clone -background '#cccf' -shadow 100x8-$shadowShift-3 \) \ -background none -compose Dst_Over -layers merge -gravity center tmp/logo$(expr $(( 2800-n ))).png
В результате из исходного кадра получены 4 с небольшими отличиями:

Теперь дело за малым, собрать из этих изображений видео:
ffmpeg -pattern_type glob -i 'tmp/logo*.png' -pix_fmt argb -vcodec qtrle -r 30 rotatingLogo.mov
-pattern_type glob — позволяет задать маску имени кадра в привычном по консоли виде
-i 'tmp/logo*.png' — взять как исходные данные изображения из папки tmp чье имя начинается с «logo»
-pix_fmt argb — задать формат изображения с прозрачностью. «a» в ARGB — это как раз альфа-канал
-vcodec qtrle — задать кодек для видео поддерживающий прозрачность. Из известных мне это «qtrle» и «png»
-r 30 — задать частоту итогового видео 30 кадров в секунду.
rotating_logo.mov — сохранить под именем «rotatingLogo.mov»
Теперь можем выполнить команду
ffplay rotatingLogo.mov
и посмотреть на результат:
Получившееся видео длинной всего в пару секунд, т.ч. совместим множество таких кусков вместе.
Для этого используем тот же ffmpeg.
Чтобы логотип вращался не постоянно, а эпизодически создадим кусок видео с неподвижным логотипом. Для статьи пусть будет длительностью в 3 секунды, чтобы не приходилось долго ждать вращения при просмотре:
ffmpeg -loop 1 -pattern_type glob -i 'tmp/logo1000.png' -pix_fmt argb -vcodec qtrle -r 30 -t 3 stillLogo.mov
В этой команде появилась опция "-loop 1" — указывающая ffmpeg повторять входную последовательность изображений (в данном случае одно единственное), и опция "-t 3" указывающая, что продолжительность итогового видео 3 секунды.
Чтобы склеить видео с неподвижным и вращающимся логотипом, создадим файл со списком файлов, которые нужно склеить. В данном случае 20 экземпляров наших файлов:
for (( i=0; i> list.txt echo file 'rotatingLogo.mov' >> list.txt done
Подадим этот файл на вход фильтру concat с указанием копировать кодеки, а не перекодировать (-c copy).
ffmpeg -f concat -i list.txt -c copy logoWithRotation.mov
Осталось наложить получившийся логотип на видео.
Логотип довольно большой, т.ч. при наложении отмасштабируем его, уменьшив в три раза.
ffmpeg -i video.mov -i logoWithRotation.mov \ -filter_complex "[1:0]scale=iw/2:ih/2[logo];[0:0][logo]overlay=shortest=1:x=20:y=500" \ -vcodec libx264 -crf 18 overlay.mov
ffmpeg -i video.mov -i logoWithRotation.mov — взять на вход два видео.
-filter_complex — использовать filter_complex которому мы указываем, следующее:
[1:0]scale=iw/3:ih/3[logo] — взять поток 0 из второго видео (1 отсчет идет с нуля) и уменьшить значения ширины (iw — input width) и высоты (ih — input height) втрое. Передать дальше под именем «logo».
[0:0][logo]overlay=shortest=1:x=20:y=0 — взять поток 0 из первого видео и поток «logo» и наложить их друг на друга.
«shortest=1» — говорит, прекратить по достижении конца любого из потоков.
x=20:y=500 — указывает где располагать левый верхний угол накладываемого видео.
-vcodec libx264 -crf 18 — использовать кодек H264. Значение после crf указывает насколько сильно сжимать. 0 — вообще без сжатия.
overlay.mov — сохранить под этим именем.
ffplay overlay.mov
Рисунки и анимация для статьи созданы с помощью тех же инструментов. В порядке появления в статье:
ffmpeg -i rotatingLogo.mov -filter_complex "[0:0]scale=iw/3:ih/3" rotatingLogo.gif montage tmp/54.png -geometry 300x200 result.png montage -mode concatenate -tile 2x2 tmp/logo1054.png tmp/logo1746.png tmp/logo2054.png tmp/logo2746.png -geometry 300x200 result.png ffmpeg -i logoWithRotation.mov -t 5.5 -filter_complex "[0:0]scale=iw/3:ih/3" logoWithRotation.gif
Итоговый скрипт для создания вращающегося логотипа:
logo=../../logo/Moto_Gymkhana_transparent.png Frames=15 width=842 height=595 mkdir tmp for (( n=0; n> list.txt echo file 'rotatingLogo.mov' >> list.txt done ffmpeg -f concat -i list.txt -c copy logoWithRotation.mov
Наложение на файл video.mov с уменьшением логотипа в три раза:
ffmpeg -i video.mov -i logoWithRotation.mov -filter_complex "[1:0]scale=iw/3:ih/3[logo];[0:0][logo]overlay=shortest=1:x=20:y=500" -vcodec libx264 -crf 18 overlay.mov
Как сделать движение картинки снизу вверх, при наведении на неё
Мне нужно чтобы была картинка которая немного выходила из низа экрана, и при наведении на неё она сдвигалась по 3-5 пикселей вверх, тем самым создавав анимацию. Сейчас у меня получилось это:
import pygame, ctypes, time from pygame.locals import * user32 = ctypes.windll.user32 w = user32.GetSystemMetrics(0) h = user32.GetSystemMetrics(1) hc = int(h/2) wc = int(w/2) pygame.init() game_display = pygame.display.set_mode((w, h), pygame.RESIZABLE) kartinka = pygame.image.load("assets/kartinka.png") kartinkar = pygame.transform.scale(kartinka, (160, 240)) pygame.display.update() speedCard = 5 while True: InGameSPP_MOUSE_POS = pygame.mouse.get_pos() InGameSPP_MOUSE_POS_XW = InGameSPP_MOUSE_POS[0] InGameSPP_MOUSE_POS_YH = InGameSPP_MOUSE_POS[1] for event in pygame.event.get(): if event.type == QUIT: pygame.quit() quit() game_display.blit(kartinkar, ((w-1080)-175, h-(188-125))) if (InGameSPP_MOUSE_POS_XW in range(int((w-1080)-175), int((w-1080)-175+160))) and (InGameSPP_MOUSE_POS_YH in range(h-(188-125), h-(188-125)+120)): # InHands0Card print("1") newposcard0 = h-(188-125) runwhilecard0 = True while runwhilecard0 == True: time.sleep(0.05) newposcard0 -= speedCard # print(newposcard0) if newposcard0
вот, именно такой результат как тут у меня в программе происходит. Приведённый код выше ^ не работает(
2D трансформации. Вращение — CSS: Transform (трансформация объектов)
Вращение объекта на странице — без преувеличения одна из самых полезных функций при разработке анимаций и не только. Этот эффект, будучи простым в понимании, содержит некоторые хитрости, о которых не стоит забывать во время разработки шаблона.
Вращение объекта достигается путём использования функции rotate() свойства transform . В отличие от функции перемещения, вращение не может быть описано пикселями, процентами и другими привычными единицами измерения. Для вращения объекта используются специальные «угловые» единицы, среди которых:
- deg — Градусы. Знакомая многим единица измерения, по которой можно указать, на какой угол повернуть объект относительно его начального положения .
- grad — Градианы. Отличительной особенностью такой единицы является количество град на один квадрант — 100. То есть полный круг описывается в 400 град.
- rad — Радианы. Мера, при которой за одну единицу принимается угол дуги, длина которой равна радиусу окружности.
- turn — Оборот. Количество оборотов окружности, где единица равна одному полному обороту.
Не пугайтесь этих единиц, если вы с ними не знакомы. Для большинства действий нет необходимости использовать их все, при этом в каждой единице есть свои плюсы, которые помогут выразительнее использовать функцию rotate() . Для удобства, в этом курсе мы будем использовать только привычные градусы.
Важно: для вращения объекта по часовой стрелке используются положительные значения функции rotate()
Взгляните на наложение элементов. Изменив положение в пространстве, они не стали занимать «особое» положение в потоке документов. Для потока с этими элементами ничего и не случалось. То место, в котором они находились до трансформации всё так же зарезервировано и не занимается другими элементами. Это же пространство так же не изменяется вне зависимости от значений свойства transform . Такое поведение обеспечивает корректность отображения страницы браузерами на случай, если они не поддерживают свойство transform .
Как и с перемещением, функция rotate() не является единственной функцией для поворота элемента. Существует еще несколько:
- rotateX()
- rotateY()
- rotateZ()
Про rotateZ() и похожие функции будет подробнее рассказано в темах, посвящённых 3D трансформациям. Работа двух других функций в двумерной области может поначалу запутать. Как это вращать объект только по одной оси? Ответ на этот вопрос будет ближе к концу урока. А сейчас стоит понять, как именно вращаются элементы и можно ли управлять точкой, вокруг которой и произойдёт вращение.
Точка вращения
Если вы попробуете вращать любой HTML-элемент на странице, то cможете заметить, что браузер за точку вращения устанавливает центр элемента. Именно вокруг этой точки и происходит всё вращение. Это позволяет не выходить объекту за пределы своего изначального положения и является самым интуитивным способом. Скорее всего, мысленно, вы сможете перевернуть объект на 90 градусов по часовой стрелке и, еще до трансформации, определить конечный результат преобразования.
В следующих примерах ось вращения будет обозначена тёмной точкой в квадрате. Следите за тем, как вращается элемент, но не поддавайтесь гипнозу 🙂
Используя CSS мы можем произвольно изменять точку, вокруг которой будет происходить вращение. Для этого используется свойство transform-origin , оно может принимать от одного до трёх значений одновременно. Третье значение отвечает за ось z, и к ней мы вернёмся во время изучения 3D трансформаций. Поведение при указании одного или двух значений следующее:
- Одно значение: устанавливается точка по оси x. Значение по оси y будет равняться center
- Два значения: устанавливаются точки по оси x и по оси y
В качестве значений могут выступать проценты или специальные ключевые слова top, right, bottom, left, center. Добавим для квадрата из примера выше в качестве точки вращения левый верхний угол. Этого можно добиться двумя способами:
- transform-origin: left top
- transform-origin: 0% 0%
При использовании процентных значений можно добиться интересных эффектов, так как можно не привязываться к конкретному краю объекта, а разместить точку в любом месте самого объекта.
Обратите внимание на последний пример. В нём точка вращения вынесена за пределы самого объекта. Таким образом создается эффект, что объект перемещается не по определённой точке вращения, а вокруг неё. Попробуйте изменять значения, чтобы убедиться в понимании точки вращения объекта.
Вращение по одной оси
В самом начале урока говорилось о том, что существуют еще две функции для вращения 2D объектов:
Как можно вращать двумерный объект по одной из осей? Добавим вращение по оси x на 360 градусов c точкой вращения по центру
Для большей наглядности на объекте используется градиент. Во время изучения трехмерных объектов станет понятнее, что происходит с двумерным объектом. Он действительно крутится только по одной оси. В данном случае наклоняясь вперёд и проходя под осью x. Это похоже на качели, которые раскручивают «солнышком», только мы не видим глубину объекта. Вращение по оси y работает по тому же принципу, только визуально объект будет вращаться вокруг вертикальной оси.
У двумерных объектов нет глубины, и именно поэтому визуально происходит скорее деформация объекта, чем его вращение. Такой принцип можно использовать при создании небольших анимаций. Например, используя :hover на кнопке можно изменить угол её положения относительно пользователя. Похожим приёмом можно добиться эффекта трехмерности в двумерной плоскости. Подробнее об анимации будет в следующих курсах, но этот пример уже можно взять на вооружение для создания простых анимаций интерфейсов.
Дополнительное задание
Используя последний пример с кнопкой, попробуйте изученные свойства трансформации, чтобы увидеть, как будет вести себя объект при наведении. Скорость трансформации можно изменить в свойстве transition .
Полезные ссылки
Открыть доступ
Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно
- 130 курсов, 2000+ часов теории
- 1000 практических заданий в браузере
- 360 000 студентов
Наши выпускники работают в компаниях: