LINUX.ORG.RU

Подскажите про программное создание анимаций

 ,


1

1

Хотелось бы произвести короткую 2D анимацию (gif/apng/webm), иллюстрирующую механизм действия, ну или «алгоритм». Требуемые изобразительные средства - это прямоугольники, текст, линии.

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

Я знаю, что в стандарте SVG была какая-то анимация, что в HTML/CSS/JS есть анимации. Понятно, что можно взять drawing api любого языка и отрисовать кадр за кадром обыкновенными drawRect().

Но чтобы оценить пригодность (и эффективность!) этих подходов, это нужно всё самому перепробовать, во-первых. Во-вторых, это самоочевидные направления, наверняка есть что-то еще.

У кого есть личный опыт, поделитесь, если не сложно.

Ответ на: комментарий от xaizek

Спасибо. Судя по quickstart, подход у manim - императивный скрипт, сцена с объектами (в стиле ООП). Автоматически формирует анимацию процесса перехода из одного состояния в другое: self.play(ReplacementTransform(square, circle)), хоть мне вот эта часть и не нужна, но круто. Поддерживается вывод в видео-файл. Продвинутая система.

anonymous ()

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

import os, cairo, subprocess as sp
from math import *

# params
project_name = 'bouncing_ball'
width, height, frames, fps = 800, 600, 500, 60

# surface init
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
c = cairo.Context(surface)
# move origin to lower left corner; scale coordinates to [0..1] range
c.translate(0, height)
c.scale(max(width, height), -max(width, height))

# output init: lossless qtrle in mov container
ffmpeg_cmd = f'''ffmpeg -f rawvideo -video_size {width}x{height} 
                -pixel_format bgra -framerate {fps} -i - 
                -c:v qtrle {project_name}.mov -y
              '''.strip().split()
# run encoding subprocess
ffmpeg = sp.Popen(ffmpeg_cmd, stdin=sp.PIPE)

for frame in range(frames):
    # clear surface
    c.set_source_rgb(0, 0, 0)
    c.paint()
    # compute ball position
    ball_radius = 0.05
    x = frame / (frames - 1)
    y = height/width * exp(-x*1.5) * abs(cos(x*3*exp(x*1.3))) + ball_radius*1.03
    # draw ball
    c.arc(x, y, ball_radius, 0, 2*pi)
    c.set_source_rgba(0, 0.7, 1, 1)
    c.fill()
    # draw flare
    flare_radius = 0.005
    c.arc(x - 0.02, y + 0.02, flare_radius, 0, 2*pi)
    c.set_source_rgba(1, 1, 1, 1)
    c.fill()
    # encode a frame
    ffmpeg.stdin.write(surface.get_data())

$ python bouncing_ball.py && ffplay bouncing_ball.mov

зашакаленный имгуром результат

anonymous ()
Ответ на: комментарий от anonymous

п.

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

anonymous ()