💨

Siv3D | モーショングラフィックスのサンプル集

2020/12/25に公開

1. 線のモーショングラフィックス

このサンプルでは、次の関数を使って簡単なモーショングラフィックスを作成します。

// OpenSiv3D v0.6.3

namespace s3d::MotionGraphics
{
	/// @brief モーショングラフィックスで線を描く
	/// @param begin 線の始点
	/// @param end 線の終点
	/// @param thickness 線の太さ
	/// @param t 経過時間 [0.0, 1.0]
	/// @param interval モーションの開始前と開始後の何も表示しない時間 [0.0, 1.0)
	inline void DrawLine(const Vec2& begin, const Vec2& end, double thickness, double t, double interval = 0.0)
	{
		const double s = (0.5 - interval);
		const Line line = Line{ begin, end }.stretched(thickness * 0.5);

		if (InRange(t, interval, 0.5))
		{
			t = (t - interval) / s;
			const double e = Min(EaseOutExpo(t) * 1.03, 1.0);
			Line{ line.begin, line.begin.lerp(line.end, e) }
			.draw(LineStyle::Uncapped, thickness);
		}
		else if (t < (1.0 - interval))
		{
			t = (t - 0.5) / s;
			const double e = Min(EaseOutExpo(t) * 1.03, 1.0);
			Line{ line.begin.lerp(line.end, e), line.end }
			.draw(LineStyle::Uncapped, thickness);
		}
	}
}

1.1 基本

#include <Siv3D.hpp> // OpenSiv3D v0.6.3

// ここに MotionGraphics::DrawLine() のコードをペースト

void Main()
{
	using MotionGraphics::DrawLine;
	Window::Resize(1280, 720);
	Scene::SetBackground(ColorF{ 0.4 });
	constexpr double period = 1.2;

	while (System::Update())
	{
		// 0.0 → 1.0 を period (秒) の周期で繰り返す
		const double t = Periodic::Sawtooth0_1(period);
		DrawLine({ 200, 360 }, { 1080, 360 }, 40, t);

		ClearPrint();
		Print << t;
	}
}

1.2 シンボル

#include <Siv3D.hpp> // OpenSiv3D v0.6.3

// ここに MotionGraphics::DrawLine() のコードをペースト

void Main()
{
	using MotionGraphics::DrawLine;
	Window::Resize(1280, 720);
	Scene::SetBackground(ColorF{ 0.4 });
	constexpr double period = 1.2;

	while (System::Update())
	{
		const double t = Periodic::Sawtooth0_1(period);

		DrawLine({ 440, 160 }, { 840, 160 }, 20, t);
		DrawLine({ 840, 160 }, { 840, 560 }, 20, t);
		DrawLine({ 840, 560 }, { 440, 560 }, 20, t);
		DrawLine({ 440, 560 }, { 440, 160 }, 20, t);

		DrawLine({ 740, 260 }, { 460, 260 }, 20, t);
		DrawLine({ 540, 260 }, { 540, 540 }, 20, t);
		DrawLine({ 540, 460 }, { 820, 460 }, 20, t);
		DrawLine({ 740, 460 }, { 740, 180 }, 20, t);
	}
}

1.3 放射

#include <Siv3D.hpp> // OpenSiv3D v0.6.3

// ここに MotionGraphics::DrawLine() のコードをペースト

void Main()
{
	using MotionGraphics::DrawLine;
	Window::Resize(1280, 720);
	Scene::SetBackground(ColorF(0.4));
	constexpr double period = 1.2;

	while (System::Update())
	{
		const double t = Periodic::Sawtooth0_1(period);

		for (auto i : step(6))
		{
			DrawLine(
				OffsetCircular{ Scene::Center(), 80, i * 60_deg },
				OffsetCircular{ Scene::Center(), 300, i * 60_deg }, 12, t);
		}
	}
}

1.4 すれ違う水平線

#include <Siv3D.hpp> // OpenSiv3D v0.6.3

// ここに MotionGraphics::DrawLine() のコードをペースト

void Main()
{
	using MotionGraphics::DrawLine;
	Window::Resize(1280, 720);
	Scene::SetBackground(ColorF{ 0.4 });
	constexpr double period = 1.2;

	while (System::Update())
	{
		const double t = Periodic::Sawtooth0_1(period);

		for (auto i : step(8))
		{
			DrawLine({ 0, 50 + i * 100 }, { 1280, 50 + i * 100 }, 10, t);
			DrawLine({ 1280, 50 + i * 100 + 50 }, { 0, 50 + i * 100 + 50 }, 10, t);
		}
	}
}

1.5 リズム

#include <Siv3D.hpp> // OpenSiv3D v0.6.3

// ここに MotionGraphics::DrawLine() のコードをペースト

void Main()
{
	using MotionGraphics::DrawLine;
	Window::Resize(1280, 720);
	Scene::SetBackground(ColorF{ 0.4 });
	constexpr double period = 1.2;

	while (System::Update())
	{
		const double t = Periodic::Sawtooth0_1(period);
		const double t2 = Periodic::Sawtooth0_1(period, Scene::Time() + (period * 0.5));

		for (auto i : step(12))
		{
			const double x = 60 + i * 120;
			DrawLine({ x, 360 }, { x, 360 - (i + 1) * 30 }, 10, t);
			DrawLine({ x, 360 }, { x, 360 + (i + 1) * 30 }, 10, t);

			const double x2 = 90 + i * 120;
			DrawLine({ x2, 360 }, { x2, 360 - (i + 1) * 10 }, 10, t2);
			DrawLine({ x2, 360 }, { x2, 360 + (i + 1) * 10 }, 10, t2);
		}
	}
}

1.6 正方形と回転

#include <Siv3D.hpp> // OpenSiv3D v0.6.3

// ここに MotionGraphics::DrawLine() のコードをペースト

void Main()
{
	using MotionGraphics::DrawLine;
	Window::Resize(1280, 720);
	Scene::SetBackground(ColorF{ 0.4 });
	constexpr double period = 1.2;

	while (System::Update())
	{
		const double gt = Scene::Time();
		const double t = Periodic::Sawtooth0_1(period);
		const double t2 = Periodic::Sawtooth0_1(period, Scene::Time() + (period * 0.5));

		for (auto i : step(20))
		{
			const double a2 = i * 3_deg + gt * 18_deg;

			for (auto k : step(4))
			{
				DrawLine(
					OffsetCircular{ Scene::Center(), i * 60.0, k * 90_deg + a2 },
					OffsetCircular{ Scene::Center(), i * 60.0, (k + (IsEven(i) ? 1 : -1)) * 90_deg + a2 },
					6, IsEven(i) ? t : t2);
			}
		}
	}
}

Discussion