テキスト表示 - Siv3D/Reference-JP GitHub Wiki

メッセージボックス

# include <Siv3D.hpp>

void Main()
{
	Graphics::SetBackground(Color(248));

	const Font font(18);

	const Array<String> messages = 
	{
		L"かがくの ちからって すげー!\nSiv3D を つかうと みじかい コードで",
		L"えや もじを ひょうじしたり\nおんがくを ならしたり できるんだ!"
	};

	const Rect frame(20, 320, 600, 120);

	const int32 duration = 80;

	Stopwatch stopwatch(true);

	size_t messageIndex = 0;

	while (System::Update())
	{
		const String& message = messages[messageIndex];

		const int32 index = stopwatch.ms() / duration;

		const bool all = index >= message.length;

		if (Input::MouseL.clicked)
		{
			if (all)
			{
				++messageIndex;

				messageIndex %= messages.size();

				stopwatch.restart();
			}
			else
			{
				stopwatch.set(100000ms);
			}
		}

		frame.stretched(2).drawFrame(0, 2, Palette::Black);

		frame.stretched(-2).drawFrame(0, 2, Palette::Black);

		font(message.substr(0, index)).draw(frame.pos + Point(30, 20), Palette::Black, 1.2);

		if (all && stopwatch.ms() % 1000 < 500)
		{
			Triangle(frame.br - Point(30, 40), 20, 180_deg).draw(Palette::Black);
		}
	}
}

異なるサイズの文字のベースラインをそろえる

# include <Siv3D.hpp>

void Main()
{
	const Font fontS(12), fontM(24), fontL(36);

	while (System::Update())
	{
		fontS(L"Siv3D").draw(50, 100 - fontS.ascent);

		fontM(L"Siv3D").draw(150, 100 - fontM.ascent);

		fontL(L"Siv3D").draw(300, 100 - fontL.ascent);
	}
}

ボックス内にテキストを収める

# include <Siv3D.hpp>

void Main()
{
	const Font font(16);

	const String text = L"Lorem ipsum dolor sit amet, consectetur adipiscing elit,\
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.";

	Rect rect(50, 50, 100, 100);

	while (System::Update())
	{
		const int32 w = Max(Mouse::Pos().x - 50, 80);
		const int32 h = Max(Mouse::Pos().y - 50, font.height + 20);
		
		rect.setSize(w, h);

		rect.draw();

		Array<String> texts;

		size_t pos = 0;

		while (pos < text.length)
		{
			const size_t n = Max<size_t>(font.drawableCharacters(text, w - 20), 1);

			texts.push_back(text.substr(pos, n));

			pos += n;
		}

		for (size_t i = 0; i < texts.size(); ++i)
		{
			const int32 y = static_cast<int32>(rect.y + 10 + i * font.height);

			const bool overflow = (i + 1 < texts.size())
				&& (y + font.height * 2 + 10 > rect.y + rect.h);

			if (overflow)
			{
				if (texts[i].length > 2)
				{
					texts[i].resize(texts[i].length - (texts[i].length > 2 ? 2 : 1));
				}

				texts[i].append(L"...");
			}

			font(texts[i]).draw(rect.x + 10, y, Palette::Black);

			if (overflow)
			{
				break;
			}
		}	
	}
}

文字を点滅させる

# include <Siv3D.hpp>

void Main()
{
	const Font font(40, Typeface::Bold);

	const String text = L"Siv3D";

	const int32 cycle = 1200;

	while (System::Update())
	{
		const int32 t = Time::GetMillisec();

		if (t % cycle < (cycle / 2))
		{
			font(text).draw(100, 100);
		}

		const double a1 = (cycle - t % cycle) / static_cast<double>(cycle);

		font(text).draw(100, 200, AlphaF(a1));

		const double a2 = Sin(t % cycle / static_cast<double>(cycle) * TwoPi) * 0.3 + 0.7;

		font(text).draw(100, 300, AlphaF(a2));
	}
}

文字を揺らす

# include <Siv3D.hpp>

void Main()
{
	Graphics::SetBackground(Palette::Black);

	const Font font(8, L" ", FontStyle::BitmapBold);
	const String message = L"In this world, it's\nC++ or BE C++ed.";
	const Rect frame(100, 100, 220, 115);

	Array<Point> offsets(100, Point(0, 0));
	Stopwatch stopwatch(true);
	int32 previous = 0;

	while (System::Update())
	{
		if (Input::MouseL.clicked)
		{
			stopwatch.restart();

			previous = 0;
		}

		if (stopwatch.ms() - previous > 30)
		{
			previous = stopwatch.ms();

			for (auto& offset : offsets)
			{
				offset = RandomPoint(1, 2);
			}
		}

		RoundRect(frame, 15).draw(Palette::White);

		const auto animation = [&](KineticTypography& k)
		{
			k.pos += offsets[k.index % offsets.size()];
		};

		const int32 index = stopwatch.ms() / 80;

		font(message.substr(0, index)).drawKinetic(frame.pos + Point(15, 15), animation, Palette::Black, 1.4);
	}
}

文字を短時間だけ出す

# include <Siv3D.hpp>

struct TextEffect : IEffect
{
	const Font m_font;

	const int32 m_value;

	const Vec2 m_from;

	TextEffect(const Font& font, const int32 value, const Vec2& from)
		: m_font(font)
		, m_value(value)
		, m_from(from) {}

	bool update(const double t) override
	{
		// 1.0 秒で消える
		if (t >= 1.0)
		{
			return false;
		}

		const double alpha = 1.0 - t;

		m_font(m_value).drawCenter(m_from + Vec2(0, -40 * t), HSV(60 - m_value).toColorF(alpha));

		return true;
	}
};

void Main()
{
	const Font font(24, Typeface::Black);

	const int32 duration = 1500;

	Circle circle(Window::Center(), 50);

	int32 combo = 0;

	Effect effect;

	Stopwatch stopwatch(true);

	while (System::Update())
	{
		const int32 ms = stopwatch.ms();

		if (ms < duration)
		{
			circle.r = 50 * (duration - ms) / static_cast<double>(duration);
		}

		if (ms >= duration || circle.leftClicked)
		{
			if (circle.leftClicked)
			{
				effect.add<TextEffect>(font, ++combo, circle.center);
			}
			else
			{
				combo = 0;
			}

			stopwatch.restart();

			circle.set(RandomVec2(Window::ClientRect().stretched(-40)), 50);
		}

		circle.draw();

		effect.update();
	}
}

文字を右揃えする

# include <Siv3D.hpp>

void Main()
{
	const Font font(24);

	const Array<String> texts =
	{
		L"a",
		L"ab",
		L"abcd",
		L"abcdefgh",
		L"abcdefghijkl",
	};

	const int32 right = 280;

	while (System::Update())
	{
		int32 i = 0;

		for (const auto& text : texts)
		{
			const int32 w = font(text).region().w;

			font(text).draw(right - w, 100 + i * font.height);

			++i;
		}
	}
}

文字を少しずつ大きくする

# include <Siv3D.hpp>

void Main()
{
	const Font font(80, Typeface::Bold, FontStyle::Outline);
	font.changeOutlineStyle({ HSV(40, 0.8, 1.0), Alpha(0), 4.0 });

	while (System::Update())
	{
		const double s = 0.2 + Time::GetMillisec() % 3000 / 1000.0;

		Graphics2D::SetTransform(Mat3x2::Scale(s, Window::Center()));

		const double alpha = Saturate(2.0 - s * 0.8);

		font(L"CLEARED!").drawCenter(Window::Center(), AlphaF(alpha));
	}
}

文字に光彩をつける

# include <Siv3D.hpp>

class GlowText
{
private:

	Font m_font;

	String m_text;

	Texture m_texture;

	Point m_offset = { 0,0 };

public:

	GlowText() = default;

	GlowText(const Font& font, const String& text, int32 blur, double gamma = 2.0)
		: m_font(font)
		, m_text(text)
		, m_offset(blur + 4, blur + 4)
	{
		const Size region = font(text).region().stretched(blur + 4).size;
		
		Image image(region, Color(0, 0));

		font(text).write(image, m_offset, Palette::White);

		image.gaussianBlur(blur, blur).gammaCorrect(gamma);

		for (auto& pixel : image)
		{
			pixel.a = pixel.r;

			pixel.r = pixel.g = pixel.b = 255;
		}

		m_texture = Texture(image);
	}

	const Texture& getGlowTexture() const
	{
		return m_texture;
	}

	RectF draw(const Vec2& pos, const Color& glow = Palette::White, const Color& text = Palette::White) const
	{
		m_texture.draw(pos, glow);

		return m_font(m_text).draw(pos + m_offset, text);
	}

	RectF drawCenter(double y, const Color& glow = Palette::White, const Color& text = Palette::White) const
	{
		return drawCenter(Vec2(Window::Width() / 2, y), glow, text);
	}

	RectF drawCenter(const Vec2& pos, const Color& glow = Palette::White, const Color& text = Palette::White) const
	{
		return draw(pos - m_texture.size / 2, glow, text);
	}

	RectF region(const Vec2& pos = Vec2(0, 0)) const
	{
		return RectF(pos, m_texture.size).stretched(-m_offset);
	}

	RectF regionCenter(double y) const
	{
		return regionCenter(Vec2(Window::Width() / 2, y));
	}

	RectF regionCenter(const Vec2& pos) const
	{
		return region(pos - m_texture.size / 2);
	}
};

void Main()
{
	const Font font(20, Typeface::Medium);

	const Array<GlowText> texts =
	{
		GlowText(font, L"CONTINUE", 10),
		GlowText(font, L"NEW GAME", 10),
		GlowText(font, L"CONFIG", 10),
		GlowText(font, L"EXIT", 10)
	};

	while (System::Update())
	{
		int32 i = 0;

		for (const auto& text : texts)
		{
			const bool mouseOver = text.regionCenter(260 + i * 50).mouseOver;

			text.drawCenter(260 + i * 50, 
				AlphaF(mouseOver ? 1.0 : 0.0),
				AlphaF(mouseOver ? 1.0 : 0.9));

			++i;
		}
	}
}

文字を上から登場させる

# include <Siv3D.hpp>

void Main()
{
	const Font font(18);

	const String message = L"Lorem ipsum dolor sit amet, consectetur\n\
adipiscing elit, sed do eiusmod tempor\n\
incididunt ut labore et dolore magna aliqua. ";

	Stopwatch stopwatch(true);

	while (System::Update())
	{
		if (Input::MouseL.clicked)
		{
			stopwatch.restart();
		}

		const double index = stopwatch.ms() / 80.0;

		const auto animation = [=](KineticTypography& k)
		{
			const double t = index - k.index;

			k.col.a = AlphaF(Saturate(t / 6)).toColor().a;

			k.pos.y -= EaseIn<Easing::Quad>(Saturate(1 - t / 4)) * 20.0;
		};

		font(message).drawKinetic(40, 100, animation, Palette::White, 1.2);
	}
}

文字の間隔を広げる

# include <Siv3D.hpp>

void Main()
{
	const Font font(20);

	while (System::Update())
	{
		for (auto i : step(10))
		{
			auto ty = [=](KineticTypography& k)
			{
				k.pos.x += k.index * (i * 2);
			};

			font(L"The quick brown fox").drawKinetic(20, 20 + 40 * i, ty);
		}
	}
}
⚠️ **GitHub.com Fallback** ⚠️