5
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【エレファント】無難なUIに飽きた人へ。Flutter ハジけ UI 実践録【やかまし】

5
Last updated at Posted at 2025-12-16

この記事は株式会社ドットログによる
コンストラク体操日記 Advent Calendar 2025 の 16 日目 の記事です。
折り返した‼️

はじめに

コーディングエージェントが、要件さえ与えればそこそこ実装してくれる時代。
ハッカソンもアイデア勝負みを増してきてしまっている昨今。
しかし、「こだわりを持ったプロダクトを作りたい」。
そんなことを考え、私はふと思い立ったのです。

「ハジけ UI をつくれば良いのではないか?」

AI時代だからこそ、人間のクリエイティビティと「遊び心」が差別化のポイントになる。
無難で機能的なUIは誰でも作れるようになった今、目立つこと、楽しいこと、ハジけることが重要なのではないでしょうか。

今回の記事では、ドットログ社内ハッカソンで私が作成した「席ガチャ」というアプリをもとに、「ハジけ UI 」への試行錯誤を共有させていただきます。

こんな人におすすめ

  • 無難な UI を作るのは飽きた
  • Flutter で簡単に使える装飾系パッケージを知りたい
  • とにかくハジケたい

前提 「ハジけ」 とは

まず、考えることをやめてください。
定義ばかり気にしないでください。
感じてください。

すげーやかましい像、エレファントやかまし。

── 以上です。

.
..
...
....
.....
......
.....
....
...
..
.

それでも、「ハジけ」が分からな人は以下に2枚「ハジけ」の参考画像を置いておくので、感じておいてください。

image.png

うん。ハジけてますね〜〜〜

image.png

おー。ハジけですね〜〜

「席ガチャ」 とは

まずは、アプリの完成形をお示ししたいと思います。

「人数」と「席の配置」を選択するだけで、ランダムにその席に座っている人を1人指名する飲み会特化型ルーレットアプリです。
名前入力・ユーザー登録などの事前準備を不要とし、その場のスマートフォン1台ですぐに利用できることを目的としています。

アプリの特徴:

  • 席の配置を視覚的に選択 - 居酒屋のテーブル配置に合わせて選べる
  • 派手な演出 - ルーレット中のネオン効果、結果発表時の紙吹雪と効果音
  • パチンコ風のやかましさ - 縁取り文字、派手な色使い、ティック音

それでは、どうやって「ハジけUI」を実現したのか、5つの要素に分けて紹介します。


ハジけ要素 1: ネオン効果で光る席

まず最初の工夫は、席が光って見える演出です。

Simulator Screenshot - iPhone 16 - 2025-12-15 at 21.04.47.png

どうやって光らせたか

Flutterの標準機能であるBoxShadowを使い、複数層の影を重ねることでネオンサインのような光を表現しました。


Class NeonSeat extends StatelessWidget { 

  const NeonSeat({
    required this.isActive,
    super.key,
  });
  final bool isActive;

  @override
  Widget build(BuildContext context) {
    // 色の定義
    final baseColor = isActive ? AppColors.secondaryLight : AppColors.primaryLight;
    final glowColor = isActive ? AppColors.yellow : AppColors.primaryDark;

    return Container(
      width: 65,
      height: 65,
      decoration: BoxDecoration(
        shape: BoxShape.circle,
        // 【重要】光の表現:複数の影を重ねる
        boxShadow: [
          // 1層目:輪郭周りの強い光
          BoxShadow(
            color: baseColor.withValues(alpha: 0.6),
            blurRadius: 10, // ぼかし具合
            spreadRadius: 2, // 広がり具合
          ),
          // 2層目:広範囲に広がるぼんやりした光
          BoxShadow(
            color: glowColor.withValues(alpha: 0.4),
            blurRadius: 25,
            spreadRadius: 4,
          ),
          // 当選時だけさらに強い光を追加
          if (isActive)
            BoxShadow(
              color: AppColors.white.withValues(alpha: 0.8),
              blurRadius: 40,
              spreadRadius: 1,
            ),
        ],
        // 物理的な円の線
        border: Border.all(
          color: baseColor,
          width: 2.5, // 線の太さ
        ),
        color: AppColors.black.withValues(alpha: 0.3), // 円の内側の背景色
      ),
      child: Icon(
        Icons.chair_outlined, // 椅子のアイコン
        color: baseColor,
        size: 32,
        // アイコン自体も少し光らせる(テキストの影を利用するテクニック)
        shadows: [
          Shadow(
            color: glowColor,
            blurRadius: 9,
          ),
        ],
      ),
    );
  }
}

ポイント:

  • 影を3層重ねることで、ネオンの「内側の光」「外側のぼやけた光」「当選時の激しい光」を表現
  • blurRadius(ぼかし)とspreadRadius(広がり)を調整するだけで、特別なパッケージ不要
  • 通常時は紫色、当選時は黄色+白色の光に切り替わり、視覚的に分かりやすい

ハジけ要素 2: 太字&縁取り文字

次は、パチンコ台の数字表示のような、目立つ文字です。

Simulator Screenshot - iPhone 16 - 2025-12-15 at 21.04.17.png

画像の「2」とかがそれです。

Flutter標準では文字に縁取りをつけることができません。そこで、bordered_textパッケージを使用しました。

BorderedText(
  strokeColor: Theme.of(context).colorScheme.secondary,  // 金色の縁取り
  child: Text(
    '$count',
    style: TextStyle(
      fontSize: 64,
      fontWeight: FontWeight.bold,
      color: Theme.of(context).colorScheme.primary,  // 赤い文字
    ),
  ),
)

ポイント:

  • BorderedTextで文字を囲むだけで、簡単に縁取り文字を実現
  • 金色の縁取り+赤い文字という派手な組み合わせで、パチンコ台のような「ハジけた」印象に
  • 文字サイズを64、太字にすることで存在感を出す

ハジけ要素 3: やかましい効果音

ハジけUIには、音も重要な要素です。

このアプリでは、何かを選択するたび、何かを押すたび、とにかく音が鳴ります。
演出時にも音がとにかく鳴ります。
音が鳴れば鳴るほどハジけるからです。

audioplayersを使って、ルーレット中のティック音、開始音、結果発表音など、多彩な効果音を実装しました。

実装ステップ

1. AudioServiceクラスを作成

Riverpodで音声再生を一元管理するサービスクラスを作ります。

@riverpod
AudioService audioService(Ref ref) => AudioService();

class AudioService {
  // 効果音再生メソッドたち
  Future<void> playTickSound() async { ... }
  Future<void> playStartSound() async { ... }
  Future<void> playRandomResultSound() async { ... }
}

2. ランダム結果音の実装

当選時の音は3種類からランダムに選択します。毎回違う音が鳴るので飽きません。
(演出時にでる文字も数パターンからランダムになっています)

Future<void> playRandomResultSound() async {
  // 3種類の音声ファイルからランダムに選択
  final soundFiles = [
    Assets.sounds.yahhoo,    // 「やっほー!」
    Assets.sounds.yeah,      // 「イェー!」
    Assets.sounds.pachinko,  // パチンコ風音
  ];

  // 低遅延プレイヤーを作成
  final player = await _createPlayer();

  // ランダムに選んだ音を再生
  await player.play(
    AssetSource(
      soundFiles[Random().nextInt(soundFiles.length)]
        .replaceFirst('assets/', ''),
    ),
  );
}

3. 低遅延モードの設定(重要!)

音がすぐに鳴るように、低遅延モードを設定します。これがないと音の再生がもっさりします。

Future<AudioPlayer> _createPlayer() async {
  final player = AudioPlayer();

  // 再生終了後に自動的にリソースを解放
  await player.setReleaseMode(ReleaseMode.release);

  // 【重要】低遅延モードを設定
  await player.setPlayerMode(PlayerMode.lowLatency);

  return player;
}

ポイント

  • 低遅延モードがないと、ボタンを押してから音が鳴るまでラグがある → 設定必須
  • Riverpodで一元管理することで、どこからでも簡単に音を鳴らせる
  • ランダム選択で毎回違う演出を楽しめる
  • 効果音はフリー素材サイトでサクッと用意

ハジけ要素 4: 紙吹雪(Confetti)

当選時の紙吹雪は、ハジけUIの代表格です。

パッケージ: confetti

画面いっぱいに紙吹雪が舞い散る演出を実装しました。

Simulator Screen Recording - iPhone 16 - 2025-12-16 at 00.17.18.gif

このパッケージは Web ページで簡単にどういう動きをするのか確認できて素敵。

// 紙吹雪(画面上部中央から)
ConfettiWidget(
  confettiController: centerConfetti,
  blastDirection: pi / 2,  // 下向き(真下に落ちる)
  emissionFrequency: 0.01,
  numberOfParticles: 50,
  gravity: 0.3,
  colors: const [
    AppColors.confettiRed,
    AppColors.confettiAmber,
    AppColors.confettiYellow,
    AppColors.confettiBlue,
    AppColors.confettiGreen,
  ],
),

実装のポイント:

  • 3方向から紙吹雪 - 中央から下向き、左から右斜め下、右から左斜め下の3カ所から発射
  • 星型の紙吹雪 - 左右からは星型のカスタム紙吹雪が飛ぶ(Pathで自作)
  • カラフルな5色の紙吹雪が画面を彩る

星型紙吹雪の実装:

// 星型を描画する関数
Path _drawStar(Size size) {
  const numberOfPoints = 5;
  final halfWidth = size.width / 2;
  final externalRadius = halfWidth;
  final internalRadius = halfWidth / 2.5;
  final path = Path();
  // ... 座標計算で5点星を描画
  return path;
}

カスタム形状の紙吹雪も、createParticlePathパラメータで自由に作成できます。


ハジけ要素 5: パチンコ風文字の画像

「START」や「selected!」などの文字も、パチンコ台のような派手なデザインにしたい。
しかし、コードで実装するのは大変そう...

sekigacha.png

パチ文字メーカーを使用

そこで、パチ文字メーカーというWebサービスを活用しました。

🔗 パチ文字メーカー

このサービスを使えば、ブラウザ上で簡単にパチンコ風の文字画像を作成できます。

ポイント:

  • 実装難しそうな素材は割り切って画像要素をふんだんに使った
  • アプリアイコン, AppBar, 既定のボタンの文字などに一貫して使用することで一体感

デザインツールを使わなくても、Webサービスで手軽にパチンコ風の画像が作れます。

okemaru.png


その他の工夫: 背景画像とテーマ

全体の雰囲気を統一するため、共通の背景画像を使用しています。

DecoratedBox(
  decoration: BoxDecoration(
    image: DecorationImage(
      image: Assets.bg.provider(),
      fit: BoxFit.cover,  // 画面全体に広がる
    ),
  ),
  child: Scaffold(...),
)

BackgroundScaffoldというウィジェットを作成し、アプリ全体で背景画像を共有。
居酒屋の雰囲気を演出しています。


まとめ: 使用したパッケージ・ツール一覧

要素 パッケージ・ツール 難易度
ネオン効果 Flutter標準(BoxShadow)
縁取り文字(コード) bordered_text: ^2.0.0
効果音 audioplayers: ^6.1.0 ⭐⭐
紙吹雪 confetti: ^0.7.0 ⭐⭐
パチンコ風画像 パチ文字メーカー(Webサービス)
アニメーション Flutter標準(AnimationController) ⭐⭐

すべてのパッケージ・ツールが簡単に使えて、かつ強力です。特別な知識がなくても、ハジけUIは実現できます。


さらに ハジけるために

今後リリースまでに追加したい要素としては、以下があります。

触覚フィードバック機能

スマホのバイブレーション機能を使って、ルーレット中の臨場感をさらに高めたいと考えています。
HapticFeedback class を使うと良さそう。

ルーレット中ずっと震えるやかましいアプリにする予定です。

音声の強化

音の演出にはさらにこだわってみたいと考えています。
flutter_soloud とか面白そう。


おわりに

「ハジけUI」は、アプリに個性と楽しさを与えてくれます。
Flutterなら、パッケージを駆使しつつ、アイデア次第で簡単に実現できるのが魅力です。

AI時代だからこそ、人間の「遊び心」が光る、のかもしれない。
年末、皆さんも今年一番ハジけたUIを作る際に参考にしていただけると幸いです。

さあ、あなたもハジけましょう!

image.png

5
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?