Tailwind CSSでコンテナークエリを使用する方法

こんにちは。エキサイトでデザイナーをしている齋藤です。

2025年1月23日にTailwind CSSのv4の安定版がリリースされました。新機能の一つにコンテナークエリーのサポートがあります。

今回はTailwind CSSでコンテナークエリを使用する方法をご紹介します。

コンテナークエリーとは?

コンテナークエリーとは、特定の親要素(コンテナー)のサイズに基づいたスタイリングを可能にする機能です。

メディアクエリーは画面サイズですが、コンテナークエリは特定の要素のサイズを基準とするため、より柔軟にレスポンシブ対応が可能です。

以下の記事で詳しく説明していますので、合わせてご覧ください。

tech.excite.co.jp

簡単におさらい

純粋なCSSでコンテナークエリーを使用する場合、実装のポイントは以下の通りです。

  • 基準とする要素にcontainer-typeを付与する
  • @container(...)とメディアクエリーと同じような形式でスタイリングする
  • container-nameを使用すると基準とする要素の名前を明示できる

完成形は以下の通りです。

<div class="parent">
    <div class="child">...</div>
</div>

<style>
    .parent {
        container-type: inline-size;
        container-name: parent;
    }
    
    .child {
        background-color: black;

        @container parent (max-width: 512px) {
            /* .parentの横幅が512px以下のときに背景色が赤になる */
            background-color: red;
        }
    }
</style>

Tailwind CSSでスタイリングする

基準とする要素に@containerを追加

基準とする要素に@containerを追加します。@containerにはcontainer-type: inline-size;が含まれます。

<div class="@container"></div>

@container/{name}の形式でcontainer-nameが使用できます。

<div class="@container/parent"></div>

@{size}:*の形式でスタイリング

基準を使用する要素では@{size}:*の形式でスタイリングします。

コンテナーサイズトークン一覧は以下で確認できます。

tailwindcss.com

例えば、「基準とする要素の横幅が512px以上の場合に背景色が赤になる」という条件の場合は以下のようになります。

<div class="@container">
    <div class="@lg:bg-red-500"></div>
</div>

max-widthを表現したい場合は@max-{size}:*の形式にします。 「基準とする要素の横幅が512px以下の場合に背景色が赤になる」という条件の場合は以下のようになります。

<div class="@container">
    <div class="@max-lg:bg-red-500"></div>
</div>

container-nameを使用している場合は@{size}/{name}:*の形式を使用します。

<div class="@container/parent">
    <div class="@lg/parent:bg-red-500"></div>
</div>

完成形

純粋なCSSと比較した完成形です。

純粋なCSS

<div class="parent">
    <div class="child">...</div>
</div>

<style>
    .parent {
        container-type: inline-size;
        container-name: parent;
        ...
    }
    
    .child {
        ...
        @container parent (max-width: 512px) {
            background-color: var(--red-500);
        }
    }
</style>

Tailwind CSS

<div class="@container/parent">
    <div class="@lg/parent:bg-red-500">...</div>
</div>

さいごに

今回はTailwind CSSでコンテナークエリを使用する方法をご紹介しました。

v4のコンテナークエリーのサポートで、表現の幅がより広まったと思います。

Tailwind CSSはHTMLに対してスタイルを直書きするため、HTMLから離れずに追うことができ、コンテナークエリーなどの複雑なスタイリングの理解もしやすいのではないかと思います。

Tailwind CSSを使用される方の一助となれば幸いです。

ご精読ありがとうございました。

参考文献

tailwindcss.com

Tailwind CSSのv3からv4でテーマ設定の方法がどう変わるか

こんにちは。エキサイトでデザイナーをしている齋藤です。

Tailwind CSSのメンテナーの一人のAdam Wathan氏は、日本時間の1月16日に自身のXにおいて、「Tailwind CSS v4.0安定版は来週リリース予定」と発表しました。

予定通りであれば、今週中にTailwind CSS v4が正式にリリースされるようです。

大きな変更点として、tailwind.config.jsが廃止され、CSSファイルで設定を行うようになることがあります。

tailwindcss.com

今回は、v3からv4でテーマ設定の方法がどう変わるかについて、代表的なスタイル要素を例にご紹介します。

免責

この記事でご紹介する内容は、2025年1月20日時点のTailwind CSS v4.0 Betaに準じており、安定版での動作を保証するものではありません。

Tailwind CSS v4ベータ版の準備

今回はベータ版にて検証をします。

まずは、Tailwind CSSとCLIのベータ版をインストールします。

npm install tailwindcss@next @tailwindcss/cli@next

次に、設定を書くCSSファイル(app.css)を作成し、Tailwind CSSをインポートします。

@import "tailwindcss";

最後に以下を実行すると、設定を書くCSSファイル(app.css)をもとに、最終的なCSSファイル(gen-output.css)が生成されます。

npx @tailwindcss/cli -i app.css -o gen-output.css

※ローカル環境でwatchしたい場合は、末尾に--watchを付けると差分を検知してリアルタイムにCSSを生成できます。

テーマ設定とは?

Tailwind CSSはカラーや角丸の値などの基本のデザイン要素が標準で定義されています。

これらのカスタマイズをテーマ設定と呼びます。

v3ではtailwind.config.jsにて設定しましたが、v4からはCSSファイルになります。

v3からv4でのテーマ設定方法

今回は以下のスタイル要素の設定方法がどう変わるかをご紹介します。

カラー

v3での設定方法

v3ではtheme.colorに定義をしました。

/** @type {import('tailwindcss').Config} */
module.exports = {
  theme: {
    color: {
      'black': '#020617',
    }
  }
}

v4での設定方法

v4ではプレフィックスcolorを付けて、CSS変数形式で定義します。

@import "tailwindcss";

@theme {
  --color-black: #020617;
}

結果

<!-- colorが#020617になる -->
<p class="text-black">...</p>

タイポグラフィ

v3での設定方法

v3ではtheme.fontSizeに定義をしました。

/** @type {import('tailwindcss').Config} */
module.exports = {
  theme: {
    fontSize: {
      'base': ["1rem", { fontWeight: "400", lineHeight: "1.8", letterSpacing: "0.02em" }],
    }
  }
}

v4での設定方法

v4ではプレフィックスtextを付けて、CSS変数形式で定義します。

ユーティリティクラスのtext-*にフォントサイズに加えて、font-weight、line-height、letter-spacingの値も含めたい場合は、--text-*に--font-weightの形式で続けると関連付けされます。

@import "tailwindcss";

@theme {
  --text-base: 1rem;
  --text-base--font-weight: 400;
  --text-base--line-height: 1.8;
  --text-base--letter-spacing: 0.02em;
}

結果

<!-- font-sizeが1rem、font-weightが400、line-heightが1.8、letter-spacingが0.02emになる -->
<p class="text-base">...</p>

角丸

v3での設定方法

v3ではtheme.borderRadiusに定義をしました。

/** @type {import('tailwindcss').Config} */
module.exports = {
  theme: {
    borderRadius: {
      lg: '1rem'
    }
  }
}

v4での設定方法

v4ではプレフィックスradiusを付けて、CSS変数形式で定義します。

@import "tailwindcss";

@theme {
  --radius-lg: 1rem;
}

結果

<!-- border-radiusが1remになる -->
<div class="rounded-lg">...</div>

ボックスシャドウ

v3での設定方法

v3ではtheme.boxShadowに定義をしました。

/** @type {import('tailwindcss').Config} */
module.exports = {
  theme: {
    boxShadow: {
      'sm': '0 1px 2px 0 rgb(0 0 0 / 0.03)',
    }
  }
}

v4での設定方法

v4ではプレフィックスshadowを付けて、CSS変数形式で定義します。

@import "tailwindcss";

@theme {
  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.03);
}

結果

<!-- box-shadowが0 1px 2px 0 rgb(0 0 0 / 0.03)になる -->
<p class="shadow-sm">...</p>

ブレイクポイント

v3での設定方法

v3ではtheme.screensに定義をしました。

/** @type {import('tailwindcss').Config} */
module.exports = {
  theme: {
    screens: {
      'sm': '480px',
    }
  }
}

v4での設定方法

v4ではプレフィックスbreakpointを付けて、CSS変数形式で定義します。

@import "tailwindcss";

@theme {
  --breakpoint-sm: 480px;
}

結果

<!-- 画面が480px以上のときにcolorがred-500になる -->
<p class="sm:text-red-500">...</p>

注意: v4からはmax-width指定はmax-*でclassとして指定が推奨されています

v3では 'sm': { max: '480px' },のように、ブレイクポイントをmax-widthで指定できました。

v4のCSSファイルでの設定でのmax-widthの指定をせずに、スタイリング時にmax-*の形式で指定することが推奨されます*1。

<!-- (width < {smの値})になる -->
<p class="max-sm:text-red-500"></p>

まとめ

今回は、v3からv4でテーマ設定の方法がどう変わるかについて、代表的なスタイル要素を例にご紹介しました。

v4からはJSを一切書かずにCSSファイルだけでテーマ設定が可能になることで、導入や運用のハードルが下がるかと思われます。

v4の詳しい変更内容は、公式ドキュメントをご覧ください。

tailwindcss.com

Tailwind CSSを使用される方の一助となれば幸いです。

ご精読ありがとうございました。

参考文献

Pangleメディエーションのエラーとその回避策

こんにちは。エキサイトでアプリエンジニアをしている岡島です。

今回はPangleのメディエーション時に起きたエラーと今回行った対処について共有していこうと思います。

環境

Flutter: 3.24.2
Dart: 3.5.2
CocoaPods: 1.15.2
gma_mediation_pangle: 1.1.0

発生した問題

Pangleのメディエーションを行い、pod installをすると下記エラーが出ました。

[!] The 'Pods-Runner' target has transitive dependencies that include statically linked binaries: 

このエラーは、CocoaPodsがターゲットに含まれる静的ライブラリの依存関係を正しく解決できない場合に発生するようです。

対応方法

Podfileに以下のコードを追記しました。

pre_install do |installer|
  Pod::Installer::Xcode::TargetValidator.send(:define_method, :verify_no_static_framework_transitive_dependencies) {}
end

このコードは、CocoaPodsの静的ライブラリに関する検証をスキップする一時的な回避策です。根本的な問題解決ではありませんが、ほかに対応できる術が見つからずこのように対応しました。

まとめ

今回のエラー対応では、Podfileにコードを追加することで一時的に問題を回避しました。しかし、この方法は根本的な解決策ではないため、ライブラリをアップデートするなど解決策が見つかれば早急に対応したいと思います。

この記事が、同じ問題に直面した方々の参考になれば幸いです。

参考資料

【Flutter】flutter_image_compressが対応する画像入出力形式について

こんにちは。エキサイトでアプリエンジニアをしている岡島です。

今回は、画像圧縮を行うライブラリであるflutter_image_compressの対応画像形式について調べたのでまとめていこうと思います。

環境

flutter_image_compress: 2.4.0

画像圧縮方法

flutter_image_compressを用いると下記コードのように、圧縮したい画像ファイルのpathと出力先のpathを指定し、画像品質をqualityで指定すると画像圧縮ができます。

final result = await FlutterImageCompress.compressAndGetFile(
    filePath, // 画像ファイルのパス
    targetPath, // 出力先のパス
    quality: 88, // 画像品質
  );

ファイルを圧縮してUint8Listを取得する関数やUint8List形式のデータを圧縮する関数も用意されているので、詳しくはライブラリのReadmeをご参照ください。

サポートされる画像形式

この記事ではiOSとAndroidのプラットフォームについて、サポートされている画像形式を見ていきます。

入力形式

出力形式

出力形式 iOS対応 Android対応
jpeg ✅ ✅
png ✅ ✅
heic ✅ ✅
webp ✅ ✅

heic形式はiOS 11以上、Android API 28以上でサポートされています。

出力形式の指定方法

enumでCompressFormatが用意されているので、CompressFormat.jpegのようにformatを指定します。 デフォルトではjpeg形式に設定されています。

final result = await FlutterImageCompress.compressAndGetFile(
    filePath,
    targetPath, 
    quality: 88,
    format: CompressFormat.png,  // 出力formatを指定
  );

最後に

今回はflutter_image_compressで対応しているファイル形式についてまとめてみました。 この記事が誰かのお役に立てれば幸いです。

コンテナークエリーを使用して親要素のサイズに応じたスタイリングをする方法

こんにちは。エキサイトでデザイナーをしている齋藤です。

今回は、コンテナークエリーを使用して親要素のサイズに応じたスタイリングをする方法をご紹介します。

コンテナークエリーとは?

コンテナークエリーとは、特定の親要素(コンテナー)のサイズに基づいたスタイリングを可能にする機能です。

メディアクエリーは画面サイズですが、コンテナークエリは特定の要素のサイズを基準とするため、より柔軟にレスポンシブ対応が可能です。

使い方

コンテナークエリを用いたスタイリングの例をお示しします。

HTML

HTMLの構造は以下の通りです。

<div class="parent">
  <div class="child"></div>
</div>

.parentの横幅に基づいて.childをスタイリングします。

CSS

基本のスタイルは以下の通りです。

.childは背景色が黒の128pxの正方形になるようにしています。

.parent {}

.child {
    aspect-ratio: 1/1;
    background: black;
    width: 128px;
}

コンテナークエリを有効にする

コンテナークエリを有効にするために、基準となる要素にcontainer-typeを付与する必要があります。

container-typeには3種類の値が存在します。

値 挙動
size インライン(横幅)およびブロック(縦幅)の両方の寸法が基準に使用されます
inline-size インライン(横幅)の寸法が基準に使用されます
normal 実質的にコンテナークエリーが無効になります

今回の例では、.parentの横幅に基づいて.childをスタイリングするため、inline-sizeを使用します。

.parentにcontainer-type: inline-size;を追加します。

.parent {
    container-type: inline-size;
}

コンテナークエリーを使用してスタイリングする

今回は、「.parentの横幅が512px以下のとき、.childの背景色が赤になる」を条件とします。

コンテナークエリーの@container記法(メディアクエリーの@mediaと同じ)でスタイリングすると、以下のようになります。

.child {
    ...

    @container (max-width: 512px) {
        background: red;
    }
}

結果

.parentの横幅が512px以下のとき、.childの背景色が赤に変化するようになりました。

.parentの横幅に応じて.childの背景色が変わる

基準としている親要素を明示する

先にお示しした例のままですと、基準としている親要素が分かりづらく、コンテナークエリーを有効にした要素が複数ある場合に混乱の要因になってしまいます。

.child {
 ...

    /* どの要素の横幅なのかが分からない */
    @container (max-width: 512px) {
        ...
    }
}

そこで、親要素にcontaner-nameを付与し、@container内で基準とする親要素を明示します。

以下のようにcontaner-nameを使用します。(その際、値は引用符で囲わないように注意してください)

.parent {
    ...

    container-name: parentElement;
}

.child {
    ...

    @container parentElement (max-width: 512px) {
        ...
    }
}

なお、container-nameを使用しない場合は、一番近いコンテナークエリーを有効にした要素が基準となります。

まとめ

今回は、コンテナークエリーを使用して親要素のサイズに応じたスタイリングをする方法をご紹介しました。

従来のメディアクエリーでは画面幅基準のみのレスポンシブ対応でしたが、コンテナークエリーを使用することでより柔軟にできるようになりました。

スタイリングされる方の一助となれば幸いです。

ご精読ありがとうございました。

【AI活用】VRoid Studio・copainter・CLIP STUDIOを使ってコミック制作してみた

はじめに

こんにちは、エキサイト株式会社デザイナーの山﨑です。

エキサイトホールディングス Advent Calendar 2024 18日目は、山﨑が担当させていただきます。

qiita.com

今回は、VRoid Studio・copainter・CLIP STUDIO PAINTを用いてのコミック制作ついて、記して行きたいと思います。

AIを用いたコミック制作にチャレンジするまでの経緯

エキサイトでは、ウーマンエキサイトをはじめ、多くのコミックコンテンツを発信しています。

しかし、コミック制作には手作業が多く、時間やコストがかかるという課題がありました。

そこで、「AIツールを活用すれば、よりコミック制作の効率化が図れるのではないか?」という発想から、この挑戦がスタートしました。

今回の検証ポイントはこのようになります:

  1. 手作業の削減はどの程度可能か?
  2. 制作時間はどのくらい短縮できるか?
  3. 商業レベルのクオリティに達するか?

自分で絵を描かずにVRoid Studio、copainter、CLIP STUDIO PAINTを組み合わせて、どれほどスムーズにコミックが作れるか実際にやってみました!

ツールの説明

コミック制作に使用した主なツールを簡単に紹介します:

VRoid Studio:3Dキャラクターを簡単に作成できるソフトウェア。

vroid.com

copainter:ラフから線画を起こし、下塗り・着彩を行うAIイラスト制作支援ツール。

www.copainter.ai

CLIP STUDIO PAINT:プロ仕様のイラスト、漫画制作ソフトウェア。

www.clipstudio.net

今回の流れ:

  1. CLIP STUDIO PAINTでセリフ入れ
  2. VRoid Studioでモデル制作
  3. copainterでモデルをコミック風イラストに変換
  4. CLIP STUDIO PAINTで背景や効果などの最終調整

セリフ入れ

まずは、CLIP STUDIO PAINTでコマ割りを作成し、セリフを入れていきます。(プロット〜ネーム部分は割愛させてください。)

モデル制作

登場人物は以下の3人です:

主人公(女性・黒髪ショート) 主人公の友達(女性・茶髪ロング) 主人公の彼氏(男性・茶髪ショート)

髪型・服装を見分けやすいデザインにしました。(似たような顔になることが多いので、髪色・髪型・洋服で差別化します。)

VRoid Studioでは、顔、髪型、衣装のセットが用意されており、簡単にモデルを作成できます。また、細かいカスタマイズも可能です。

さらに、VRoid用素材はBOOTH(pixivが運営するマーケットプレイス)からダウンロードして利用できます。

モデルにポーズを取らせる

VRoid Studioの強みは、モデルに表情やポーズを取らせた状態で写真を撮影できることです。 テンプレートモーションを使えば、自然な動きの瞬間をキャプチャすることができます。

このように、漫画のコマに沿ったポーズをモデルに取らせて写真を撮影していきます。

コミックイラスト化

撮影した画像をcopainterでコミックイラストに変換します。

copainterの「ペン入れ」から撮影した画像を入れ…

忠実度やその他の数値を調整すると…

コミックイラスト化できました。

このようにどんどんコミックイラスト変換して行きます。

泣き顔、頬を赤らめさせた表情にしたい場合は、画像の上に涙や頬に車線を加えるだけで、AIが自動で処理してくれます。

また、小物や背景は以下の方法で準備しました:

小物(財布など):CLIP STUDIO ASSETSから3Dモデルをダウンロード→スクショを撮影→copainterで出力。

背景:Adobe Stockから写真をダウンロード→copainterでコミックイラスト化。

イラストを合成

最終的に、作成したイラストをCLIP STUDIO PAINTでコマに組み込みます。 効果や文字入れを追加し、完成したのが以下の作品です:

検証結果

①手作業の削減はどの程度可能か? → 手作業の大部分である絵を描く必要がなくなるので大幅に削減できた。

ただし、セリフ入れや演出、モデルにポーズを取らせるスキルが必要になるため、完全な自動化は難しい。

②制作時間はどのくらい短縮できるか? → 約2~3時間で制作完了。従来なら8~10時間以上かかる作業を大幅に短縮できた。

③商業レベルのクオリティに達するか? → 出来上がりはかなり自然で、3Dモデルだと気付かれないほどのクオリティに仕上がった。

最後に

今回はモデルのポーズの取らせ方などは割愛してしまいましたが、今回の制作で、VRoid Studioやcopainterの可能性を実感しました!

最後に、エキサイトではデザイナー、フロントエンジニア、バックエンドエンジニア、アプリエンジニアを絶賛募集しております!

興味があればぜひ連絡よろしくお願いいたします!🙇

www.wantedly.com

Spring Bootにおいて、Controllerで全てのリクエストを受け取る方法

はじめに

こんにちは、新卒2年目の岡崎です。

エキサイトホールディングス Advent Calendar 2024の20日目を担当します。

他の記事はこちらから!

qiita.com

今回はSpring Bootにおいて、Controllerで全てのリクエストを受け取る方法を紹介します。

環境

  • gradle
------------------------------------------------------------
Gradle 8.11.1
------------------------------------------------------------

Build time:    2024-11-20 16:56:46 UTC
Revision:      481cb05a490e0ef9f8620f7873b83bd8a72e7c39

Kotlin:        2.0.20
Groovy:        3.0.22
Ant:           Apache Ant(TM) version 1.10.14 compiled on August 16 2023
Launcher JVM:  21.0.5 (Amazon.com Inc. 21.0.5+11-LTS)
Daemon JVM:    /Users/hiromi.okazaki/.sdkman/candidates/java/21.0.5-amzn (no JDK specified, using current Java home)
OS:            Mac OS X 14.7.1 aarch64
openjdk version "21.0.5" 2024-10-15 LTS
OpenJDK Runtime Environment Corretto-21.0.5.11.1 (build 21.0.5+11-LTS)
OpenJDK 64-Bit Server VM Corretto-21.0.5.11.1 (build 21.0.5+11-LTS, mixed mode, sharing)
  • Spring Boot
  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/

 :: Spring Boot ::                (v3.3.0)

実装

Spring Bootで全てのリクエストをControllerで受けとる場合、パスを/**とすれば実現できます。

    @RequestMapping("/**")
    public String getAllRequest() {
        return "hello world";
    }

@RequestMappingを使用すると、GETとPOSTの区別をつけず、リクエストを受け取ることができます。

また、GETのみ全てのリクエストを受け取りたい場合は、@GetMapping("/**")、POSTのみ全てのリクエストを受け取りたい場合は@PostMapping("/**")とすればそれぞれのリクエストを受け取ることができます。

特定のエンドポイントが存在する場合

特定のエンドポイントが存在する場合は、/**(ワイルドカード指定)よりも優先されます。

例えば、/sampleというエンドポイントが定義されている場合、リクエストは/**ではなく /sampleにルーティングされます。

最後に

本日はSpring Bootにおいて、Controllerで全てのリクエストを受け取る方法を紹介しました。どなたかの助けになれば幸いです。

小さなデザイナーチームで実践!レビュー依頼のワークフローを設計した話

こんにちは!SaaS・DX事業部デザイナーの鍜治本です。
前回、ブランチ機能を駆使してUIファイル管理している記事を書きました。

tech.excite.co.jp

事業部デザインチームでのUI更新方法が型化され、日々の作業が少し楽になった一方で、新たな課題が見えてきました。
それはレビュー依頼のやりとりです。この記事では、スラックのワークフロー機能を活用し、レビュー依頼を効率化した方法をご紹介します。

背景:レビュー依頼の課題

チームでUI更新の作業が分担できるようになった中、作業内容をレビューしてもらうにあたり課題が浮かび上がりました。

メンバーそれぞれのレビュー依頼

アナウンス手段が統一されていない

各メンバーがUI作成後にSlackで都度レビュー依頼を出しており、チャンネルは決まっているものの明確なルールは定義していませんでした。
「レビューの依頼はこのチャンネルでいいんでしたっけ…?」とメンバーに聞き、口頭で確認をとっている状態に…

依頼内容を作成するの負担が大きい

「修正なのか新規なのか」「どの箇所を見てほしいのか」など、依頼内容を毎回手書きで詳細に書くのが手間に感じる場面が多かったです。
また、プロトタイプを作成するとそれについても説明が必要に。レビュー依頼するたびに「依頼内容を説明」する必要があり、地味な負債となっていました。

これらの課題は特に、経験が浅いメンバーにとって心理的ハードルが高く、依頼が滞る原因にもなってしまいます。

解決策:ワークフロー機能を活用

この課題を解消するために、Slackのワークフロー機能を活用することに。
ワークフロー自体はデザイナー組織でも活用事例があるので、よければこちらもご覧ください。 tech.excite.co.jp

ワークフローを使えば、自己流になりがちなレビュー依頼も型化できます。
仕組み自体は簡単ですが、レビュー依頼は次のような流れにしました。

ワークフローの流れ

ワークフローの概要図
①ワークフローを立ち上げる
レビューを依頼したいメンバーがワークフローを起動。

②レビュー内容の入力
モーダルの内容に沿って、「レビューしてほしいリンク」「確認箇所」「その他備考」をフォームに記述して送信。

③該当チャンネルで通知
フォーム内容がレビュー担当者に通知され、次のアクションを促します。通知内容にはレビュー内容で記述されたリンクや、確認箇所が記載されています。

④レビュー担当者によるレビュー
レビュー担当者がボタンを押して、②レビュー内容の入力と同じくモーダルが立ち上げる。モーダルにはフォーム形式で「レビュー内容」「打合せ緊急度」を入力できるので、レビュー内容に合わせて記述&送信。

⑤レビュー依頼者への通知と共有
フォームが送信されると、レビュー依頼時のスレッドに④の内容が投稿される。

レビュー依頼者とレビュー担当者それぞれのフォーム

複数人がレビュー担当者としてレビューをする場合も、④のステップから開始でき、全て同じスレッドにまとめられます。

実際に使ってみて感じたこと

仕組み自体はシンプルですが、フォーム形式で入力できる点が大きなポイント。毎回のテキスト作成にかかる負担が軽減され、実際に自分以外のメンバーにも導入してもらっています。

ワークフローなので内容が統一され、担当者が確認しやすくなりました
元々、メンバーからも「レビューを投げる時に何を書けばいいか…?」という疑問があがっていたので、改めてレビューの流れを整頓できました。
特に、次の様なメリットがあったと感じています。

心理的ハードルを軽減できる

レビュー依頼やフィードバックのやりとり自体が簡単になり、依頼を投げるための準備といった仕込み作業を減らせました。これによって、本来のレビューに集中できるようになりますね。

必要な情報を押さえられる

依頼時に重要な要素となる「レビューで伝えるべき前情報」も必ず入力できます。新卒メンバーなど、レビュー依頼に慣れていない人もスムーズに依頼できるようになりました。

今後の展望

現在はSlack上で通知・内容確認し、具体的な修正などはミーティングをセットする流れとなっています。
ただ、これではレビュー内容と実タスクとの紐付きが弱く、後から見返した時の関連が分かりにい状態です。また、別タスクでも活かせる情報源でもあることから、レビューした内容自体にも価値がある考えています。

今後は、タスク管理をしているNotionと連携させて、もらったレビュー内容やフィードバックを関連づけたり、レビュー内容をチームのナレッジベースとして活用できないか調整してみます。

まとめ

今回の取り組みを通じて、チーム全体のレビュー依頼プロセスが出来上がったことで、メンバー同士でレビューする際の負担を減らせました。
小さな工夫でしたが、チームのコミュニケーションを円滑にできる環境作りになれたと思います。
皆さんも、ぜひワークフロー機能を試してみてください〜!

見逃さないために今からチェック!行きたい展示会2025

こんにちは!SaaS事業部デザイナーの澤田です! エキサイトホールディングス Advent Calendar 2024 の22日目を担当します。

エキサイトホールディングスの各社に所属するエンジニア・デザイナーが力を合わせてブログのバトンを回しているので、ぜひ他の記事も覗いてみてください😊

qiita.com

今回は来年見逃さないために絶対に行きたい展示会をご紹介します...!

デザインあ展neo

累計116万人を動員した「デザインあ展」が、装いも新たに「デザインあ展neo」として虎ノ門ヒルズ TOKYO NODEに登場します! 2025年4月18日から9月23日まで、歴代最長の会期で開催され、「みる」「かんがえる」「つくる・あそぶ」をテーマに、パーフェクトロン、プラプラックス、岡崎智弘らによる新作約35点を含む展示を通して、デザインの魅力を体感できる展示会となっているそうです。 360度スクリーンでの映像体験や、NHK『デザインあneo』でおなじみのコーナーも登場するそうで今からワクワク....!!

デザインあ展neo
デザインあ展neo

展示概要

会期:2025年4月18日 (金) ~ 9月23日 (火・祝) 入場料:未定 会場:TOKYO NODE GALLERY A/B/C (虎ノ門ヒルズ ステーションタワー 45F) 主催:TOKYO NODE、NHK、NHKエデュケーショナル、NHKプロモーション 総合ディレクター:佐藤 卓 映像ディレクター:中村 勇吾 音楽ディレクター:蓮沼 執太 展示構成作家:パーフェクトロン、プラプラックス、岡崎 智弘 exhibition-ah-neo.jp

ラーメンどんぶり展

展覧会を中心に、トークやワークショップなど、デザインの楽しさを体験できる多彩なプログラムを展開する21_21 DESIGN SIGHTでは、2025年3月7日から6月15日まで、企画展「ラーメンどんぶり展」を開催されます。日本のラーメン丼の90%を占める美濃焼に焦点を当て、その1300年の歴史や背景、職人たちの技、そしてラーメンと器の関係性を紐解く内容になっているそうです。 アーティストによるオリジナル丼の展示に加え、ラーメン屋台の紹介、「デザインの解剖」の手法を用いた考察など、多角的な視点からラーメンの魅力を探りラーメンの奥深さを発見する展覧会となっているそうです...!!

 ラーメンどんぶり展
ラーメンどんぶり展

展示概要

会期:2025年3月7日(金) - 6月15日(日) 会場:21_21 DESIGN SIGHTギャラリー1&2 開館時間:10:00 - 19:00(入場は18:30まで) 休館日:火曜日(4月29日、5月6日は開館) 入場料: 一般1,600 円、大学生800 円、高校生 500 円、中学生以下無料 ディレクター:佐藤 卓、橋本麻里

www.2121designsight.jp

美を疑え-資生堂クリエイティブ展-

化粧品メーカーである資生堂のクリエイティブ部門が独立して2022年1月に設立された資生堂クリエイティブ株式会社初の展覧会が開催されます。 コンテンツ内容はまだ公開されていませんが、どのような展示がされるのかプロダクト開発の裏側が知れるのでは...?と今からとても楽しみです...!

美を疑え-資生堂クリエイティブ展-
美を疑え-資生堂クリエイティブ展-

展示概要

会期:2025年1月11日(土) - 2025年1月26日(日) 会場:資生堂ギャラリー 開館時間:11:00 - 19:00(日曜日・祝日は18:00まで) 休館日:月曜日 入場料:無料

www.shiseidocreative.com

さいごに

いかがだったでしょうか!? 来年も見逃せない展示会がたくさんありいまからワクワクしています💓 もしおすすめの展示会があれば教えてください! 最後までお読みいただき、ありがとうございました

TerraformでECSコンテナとBedrockの間のPrivateLinkを確立する

こんにちは、エキサイト株式会社の平石です。

エキサイトホールディングス Advent Calendar 2024のシリーズ2, 19日目を担当いたします。

今回はAWS上のECSコンテナとBedrockの間のPrivateLinkを確立する方法をご紹介します。

AWSリソースの作成にはTerraformを使います。

はじめに

Amazon Bedrockとは

Amazon Bedrockは、AWS上で生成AIを利用できるようにするフルマネージドサービスです。
既存のモデルを容易に利用することもできますし、用途やデータに合わせてカスタマイズすることも可能です。

aws.amazon.com

PrivateLinkとは

Amazon BedrockはVPC上になく、ECSコンテナ環境で動作しているアプリケーションからBedrcokを利用する際にはNAT Gatewayを利用するなどしてインターネットを経由する必要があります。
しかし、インターネットを経由するとセキュリティの問題が生じます。

PrivateLinkは利用するAWSサービスがVPC上にあるかのように接続するための方法で、インターネットを経由しないプライベートな接続が可能になります。

PrivateLinkはVPCにアタッチするVPCエンドポイントというコンポーネントと接続先のAWSサービスを結びつけることで構築します。

環境

Terraform 1.10.3で動作確認をしています。

前提条件

AWSアカウントの作成、Terraformの環境構築、ECSコンテナのデプロイ、Bedrockのモデルへのアクセス許可は完了していることを前提としています。

実装

Security GroupとIAMポリシーを作成する

まずは、VPC エンドポイントにアタッチするSecurity Groupを作成します。

./vpc_endpoint/bedrock/main.tf

variable "vpc" {
  type = object({
    vpc_id             = string
    private_subnet_ids = list(string)
  })
}

variable "trusted_security_group_id" {
  type = string
}

module "security_group" {
  source      = "terraform-aws-modules/security-group/aws"
  version     = "5.1.0"
  name        = "bedrock-vpce-sg"
  description = "Security group for bedrock-vpce"
  vpc_id      = var.vpc.vpc_id
  ingress_with_source_security_group_id = [
    {
      from_port                = 443
      to_port                  = 443
      protocol                 = "tcp"
      source_security_group_id = var.trusted_security_group_id
    }
  ]
}

設定したSecurity GroupからのTCPプロトコルによる443ポートへの通信のみ許可します。 変数trusted_security_group_idには、ECSにアタッチしたSecurity GroupのIDを渡します。

次に、VPCエンドポイントにアタッチするポリシードキュメントを作成します。

./vpc_endpoint/bedrock/main.tf

variable "trusted_role_arns" {
  type = list(string)
}

........

data "aws_iam_policy_document" "bedrock_access_policy" {
  statement {
    actions = [
      "bedrock:InvokeModel",
      "bedrock:InvokeModelWithResponseStream",
    ]
    effect = "Allow"
    resources = [
      "arn:aws:bedrock:ap-northeast-1::foundation-model/anthropic.claude-*"
    ]
    principals {
      identifiers = var.trusted_role_arns
      type        = "AWS"
    }
  }
}

このポリシードキュメントでは、VPC エンドポイントにBedrockのInvokeModelとInvokeModelWithResponseStreamを許可します。
Bedrockのモデルにアクセスして、生成AIからのレスポンスを得るためにはこのポリシーを設定すれば十分でしょう。
今回は、AnthropicのClaudeというモデルにアクセスできるようにしています。

VPC エンドポイントを作成する

これまでに作成したSecurity Groupやポリシーを利用してVPCエンドポイントを作成します。

./vpc_endpoint/bedrock/main.tf

resource "aws_vpc_endpoint" "bedrock_vpc_endpoint" {
  service_name        = "com.amazonaws.ap-northeast-1.bedrock-runtime"  // ①
  vpc_id              = var.vpc.vpc_id
  vpc_endpoint_type   = "Interface"  // ②
  subnet_ids          = var.vpc.private_subnet_ids  
  policy              = data.aws_iam_policy_document.bedrock_claude_policy.json  // ③
  security_group_ids  = [module.security_group.security_group_id]  // ④
  private_dns_enabled = true  // ⑤

  tags = {
    Name = "bedrock-vpce"
  }
}

output "bedrock_vpc_endpoint_id" {
  value = aws_vpc_endpoint.bedrock_vpc_endpoint.id
}

①では、VPC エンドポイントでVPCとPrivateLinkを確立するサービスを設定します。今回は東京リージョン(ap-northeast-1)のBedrockを設定しています。

②では、VPC エンドポイントのタイプを設定します。VPC エンドポイントのタイプには主にGatewayとInterfaceがあります。
Gateway エンドポイントは無料で利用できますが、現在のところAmazon S3またはDynamoDBとの接続しかサポートされていません。 今回は、Bedrockとの接続を確立するためInterface エンドポイントに設定しています。

③, ④では、上で作成したSecurity Groupとポリシーをアタッチしています。

⑤では、指定したVPCにプライベートホストゾーンを関連付けるかどうかを設定します。
VPC内のサービスが自動でVPC エンドポイントを利用するために必要なため、trueに設定しましょう。

ECSタスクのロールを変更

次にECSタスクのロールにアタッチされているポリシーを変更します。

./ecs/xxxxx/main.tf

variable "bedrock_vpc_endpoint_id" {
  type = string
}


data "aws_iam_policy_document" "iam_policy_document" {
  statement {
    actions = [
      〜〜 略 〜〜
      "ec2:CreateNetworkInterface",
      "ec2:DescribeNetworkInterfaces",
      "ec2:DeleteNetworkInterface",
      "ec2:*VpcEndpoint*"
    ]
    resources = ["*"]
  }

  // BedrockへのアクセスをVPC エンドポイント経由のみに制限
  statement {
    effect = "Allow"
    actions = [
      "bedrock:InvokeModel",
      "bedrock:InvokeModelWithResponseStream"
    ]
    sid       = "AllowTask"
    resources = ["*"]
    condition {
      test     = "ForAnyValue:StringEquals"
      values   = [var.bedrock_vpc_endpoint_id]
      variable = "aws:SourceVpce"
    }
  }
}

前半部分では、ECSタスクからVPCエンドポイントを利用できるようなstatementを追加しています。

また、後半部分ではECSタスクからBedrockへのアクセスをVPC エンドポイント経由のみに制限し、意図せぬインターネットへのアクセスが発生しないようにしています。
ただし、このstatementはあくまでVPCエンドポイントからBedrockにアクセスできるようにしているだけなので、他に無条件でBedrockにアクセスを許可するようなstatementを記述している場合には削除しておきましょう。

作成した部品を組み合わせる

最後にこれまで記述したVPC エンドポイントを実際に作成します。

./main.tf

// Bedrockに接続するためのVPCエンドポイント
module "bedrock_vpc_endpoint" {
  source = "./vpc_endpoint/bedrock"
  vpc = {
    vpc_id             = <使用するVPCのIDを指定>
    name               = <使用するVPCの名前を指定>
    private_subnet_ids = <使用するVPC内のサブネットを指定(基本的にはECSが存在するサブネット)>
  }
  trusted_role_arns = [
    <ECS タスクロールのarn>
  ]
  trusted_security_group_id = <ECSに設定したSecurity GroupのID>
}

終わりに

今回はECSコンテナとBedrockの間のPrivateLinkを確立する方法をご紹介しました。

インターネットを経由しないことでセキュリティ強化につながるため、Bedrockを利用する場合には設定すると良いでしょう。

参考文献

【保存版】デザイナーのインプット場所まとめ〜インスピレーションを求めて〜

こんにちは!SaaS事業部デザイナーの澤田です! エキサイトホールディングス Advent Calendar 2024 の最終日、25日目を担当します!

ここまでエキサイトホールディングスの各社に所属するエンジニア・デザイナーが力を合わせてブログのバトンを回してきたので、ぜひ他の記事も覗いてみてください😊

qiita.com

デザイナーにとって、新しいデザインに触れ、知識をアップデートしていくことは、表現の幅を広げる上で非常に大切です。そこで今回は、今後の情報収集に役立つ、おすすめのデザインインプット場所をまとめました!

デザイン全般

Pinterest

Pinterest(ピンタレスト)は、画像や動画を収集・共有するサービスです。まるで自分の好きな写真や画像をコルクボードにピンで留めるように、気になる画像や動画を「ピン」として保存し、それをカテゴリーごとに整理して「ボード」にまとめ、他のユーザーと共有することができます。

Pinterestの画面
Pinterest

https://jp.pinterest.com/

Behance

Adobe(アドビ)社が運営する、クリエイターのためのオンラインプラットフォームです。世界中のクリエイターの作品を見ることができます。

Behanceのサービス画面
Behance

https://www.behance.net/

Design Inspiration

Pinterestと同じく様々なジャンルのデザインが掲載されています。カラーを指定して画像検索することができます!

Design Inspirationのサービス画面
Design Inspiration

https://www.designspiration.com/

Dribbble

デザイナーのためのオンラインコミュニティプラットフォームです。世界中のデザイナーの作品を閲覧することができます。

dribbbleのサービス画面
dribbble

https://dribbble.com/

UIデザイン

mobbin

iOSとAndroidのモバイルアプリのUI/UXデザインパターンを豊富に集めたライブラリサイトです。様々なアプリのスクリーンショットをカテゴリー別に見ることができます。

mobbinのサービスサイト
mobbin

https://mobbin.com/

UIポケット

こちらもmobbinと同様にウェブデザインやアプリデザインの参考になる、アプリのUIデザインギャラリーサイトです。

UI Pocketのサービス画面
UI Pocket

https://www.ui-pocket.com/web/apps

ABTEST

mobbinによって提供されてるUIのABテスト結果が一覧で見られるサイトです。

ABTESTのサービス画面
ABTEST

https://abtest.design/

Webデザイン

SANKOU!

Webデザイン制作の参考になる日本のWebサイト・LPを集めたギャラリー・リンク集です。

SANKOU!のサービス画面
SANKOU!

https://sankoudesign.com/

URAGAWA

国内トップクラスの制作プロダクション、事業会社のクリエイティブが「どの企業が作ったのか」も含めてわかるWEBデザインギャラリー、参考サイト集です。

URAGAWAのサービス画面
URAGAWA

https://mirai-works.co.jp/uragawa/

1GUU

クオリティの高いWebデザインを集めたWebデザイナーのためのギャラリー・サイトリンク集です。一覧のサムネで動きもわかるためアニメーションから探すことも可能です!

1GUUのサービス画面
1GUU

https://1guu.jp/

MUUUUU.ORG

同じくWebデザインのインスピレーションを得るためのギャラリーサイトです。

MUUUUU.ORGのサービス画面
MUUUUU.ORG

https://muuuuu.org/

Studio Showcase

STUDIOで制作されたWebサイトが集められたギャラリーサイトです。カテゴリー別で検索して探すこともできます。

Studio Showcaseのサービス画面
Studio Showcase

https://showcase.studio.design/ja

グラフィックデザイン

バナーデザインの参考になる、おしゃれで良質なバナーデザインをまとめたギャラリーサイトです。バナー広告から特集バナーまで、幅広いジャンルから収集できます!

BANNER LIBRARYのサービス画面
BANNER LIBRARY

https://design-library.jp/

Facebook広告集めました。

Facebook広告運用者、これから広告運用をする方のためのFacebook広告を集めたサイトです。

Facebook広告集めました。のサービス画面
Facebook広告集めました。

https://facebook.adsquare.jp/

その他

GOOD PORTFOLIO / ポートフォリオサイト

世界中のクリエイターデザインポートフォリオ集です。Web、UI/UX、グラフィック、イラストなど多ジャンルのポートフォリオが掲載されています。

GOOD PORTFOLIOのサービス画面
GOOD PORTFOLIO

https://goodportfol.io/

COCODA / デザイン

デザインの裏側をまとめた事例集です。日本を代表するデザイン組織から、200以上の事例が公開されています!

COCODAのサービス画面
COCODA

https://cocoda.design/teams

終わりに

今回は、私が日頃から参考にしているデザインインプットの場所をご紹介しました。 少しでも皆さんのデザインワークのお役に立てれば幸いです!今回ご紹介したサイト以外にも、おすすめのインプット場所があれば、ぜひ教えてください!😊 最後までお読みいただき、ありがとうございました

【Flutter】go_routerの基本とOSごとにテーマを分ける方法

こんにちは、エキサイトでアプリエンジニアをしている岡島です。エキサイトホールディングス Advent Calendar 2024の21日目を担当させていただきます。

今回はgo_routerを触ってみたので、go_routerについて共有していこうと思います。

環境

dependencies:
go_router: ^14.6.2

go_routerの特徴

go_routerは、ルーティングのライブラリであり、URLに基づいたナビゲーションのため、ディープリンクを扱いやすいなどの特徴があります。

pub.devのReadmeには次のような特徴があると書かれています。

  • テンプレート構文を使用したパス パラメーターとクエリ パラメーターの解析
  • 目的地(サブルート)の複数画面の表示
  • リダイレクトのサポート
  • ShellRouterによる複数のナビゲーターのサポート
  • MaterialとCupertinoアプリのサポート
  • Navigator APIの後方互換性

go_routerの基本

準備

基本的に必要となることは以下のとおりです。

  1. GoRouterの構成を宣言する
  2. MaterialApp.routerやCupertinoApp.routerを使用して準備をする

GoRouterの構成を宣言する

以下の例のようにそれぞれの画面を宣言していきます。

最低限必要なものはpathとbuilderです。

final router = GoRouter(
  routes: [
    GoRoute(
      path: '/',
      builder: (BuildContext context, GoRouterState state) {
        return const HomeScreen();
      },
    ),
    GoRoute(
      path: 'screen1',
      builder: (BuildContext context, GoRouterState state) {
        return const Screen1();
      },
    ),
  ],
);

はじめに開く画面を指定する場合はinitialLocationでパスを指定します。

final router = GoRouter(
  initialLocation: '/',
  routes: [
    // GoRoute()の宣言
  ],
);

他にもdebugLogDiagnostics: true, とするとログが出力されるようになります。

MaterialApp.routerやCupertinoApp.routerを使用して準備をする

アプリでgo_routerを利用するには、MaterialApp.routerやCupertinoApp.router 使用し、routerConfig に宣言したGoRouterの構成オブジェクトを設定します。

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp.router(
      routerConfig: router,
    );
  }
}

以上で準備が完了です。

画面遷移の方法

ここまでの準備で、go_routerを利用すると、画面遷移の時にcontext.go()を用いて遷移することができます。下のように書くと、TextButtonをタップしてScreen1に遷移することができます。

  return TextButton(
    child: const Text('Screen1'),
    onPressed: () => context.go('/screen1'),
  );

他にもNavigator.of(context).push()やNavigator.of(context).pop()の代わりにcontext.push()やcontext.pop()が利用できます。

go_routerではBuildContextのナビゲーションに拡張関数を定義しています。

extension GoRouterHelper on BuildContext 

この拡張関数のおかげで、context.go()やcontext.pop()というようにcontext.〇〇で遷移することができるようになっています。

名前付きルートを使用する

GoRouteに一意の名前をつけることができます。設定するには宣言時にnameのパラメータを追加するだけです。

GoRoute(
   name: 'myPage',
   path: /* ... */,
   builder: /* ... */,
 ),

遷移する時はgoNamedを用います。

TextButton(
  onPressed: () {
    context.goNamed('myPage');
  },
  child: const Text('myPageへ遷移'),
),

こうすることで以下のメリットがあります。

  • パスの変更に柔軟になる
    • nameを用いて遷移するので、パスの変更があっても一括で変更できます。複数の画面でパスを指定して遷移していた場合は、それぞれの箇所でパスを変更する必要があります。

OSごとにテーマを設定する方法

準備の段階で、MaterialApp.routerやCupertinoApp.routerを使用していましたが、PlatformApp.routerを用いるとMaterialやCupertinoデザインを区別することができます。

PlatformApp.routerを用いるにはflutter_platform_widgetsをインストールする必要があるのでご注意下さい。 https://pub.dev/packages/flutter_platform_widgets

AndroidはMaterial系のデザインに寄せてテーマを設定するなどということができます。

    return PlatformApp.router(
      routerConfig: router,
      material: (_, __) => MaterialAppRouterData(
        theme: ThemeData(
          primaryColor: Colors.red,
        ),
      ),
      cupertino: (_, __) => CupertinoAppRouterData(
        theme: const CupertinoThemeData(
          primaryColor: Colors.blue,
        ),
      ),
    );

最後に

go_routerを用いることで、URLベースのナビゲーションが可能とwebに似た操作ができるようになりました。またディープリンクに対応しやすくなるのも利点の一つかと思いました。

最後まで読んでいただきありがとうございました!

【AI着彩】copainterを用いてコミック着彩にチャレンジしてみた

はじめに

こんにちは、エキサイト株式会社デザイナーの山﨑です。

エキサイトホールディングス Advent Calendar 2024の24日目を担当します。

qiita.com

この記事では、「copainterを用いたコミック着彩」について取り組んだ内容をご紹介します。

copainterって何?

copainterは、ラフから線画の作成や下塗り・着彩を行うイラスト制作支援ツールです。
詳細はこちらからご確認ください:
公式サイト - copainter

また、copainterはイラストの絵柄をAIで再現・量産するツール「mimic」を提供しているRADIUS 5によって運営されています。
RADIUS 5

目的

今回は、女性向けWebメディア「ウーマンエキサイト」で公開しているコミックの着彩工程を、AIツールを活用して効率化できるか検証しました。

現状では、ウーマンエキサイトのコミック制作では以下の工程をイラストレーターに依頼しています:

  • ラフ作成
  • 線画作成
  • 着彩
  • セリフ入れ

もし、ラフと線画だけをイラストレーターに依頼し、着彩とセリフ入れを内製化できれば、コミックのリリーススピードを向上させ、より多くの作品を公開できると考えました。

着彩準備

線画と下塗り

copainterでの着彩には、通常、線画と下塗りを事前に用意する必要があります。

下塗りは、AIに着彩のベースとなる色を正確に指示する、いわば設計図のような役割を果たしています。

実験していた時には実装されていませんでしたが、最近copainterに下塗りを自動で行う機能が追加されました。 下塗りの作業が煩わしいと感じる方は、この新機能を活用することをお勧めします。

今回は以下の手順を取りました:

  1. 線画の準備

    • 完成済みの線画を用意。
  2. 下塗り

    • CLIP STUDIO PAINTを使用し、人物の肌・髪・服などに任意の色を塗り、下塗りを作成。(登場人物ごとにカラーパレットを作成しておくと便利です。)

下塗りはシンプルな操作で済むため、1枚あたり1~2分程度で作業が完了します。

着彩手順

準備が整ったら、いよいよ着彩に移ります。以下はcopainterでの着彩手順です:

  1. ログイン
    copainterの公式サイトにアクセスし、アカウントを作成またはログイン。右メニューから「着彩」へ

  1. 線画と下塗りのアップロード
    対象の画像をアップロード。

  1. 塗りモードを選択
    「AIの変化の強さ」「書き込み量」「モデル」選択し、「送信」ボタンをクリック。 (最初はデフォルトで出力することをオススメします。)

  1. 結果の確認と出力
    着彩が完了した画像を確認し、ダウンロード。

以下が実際の出力例です:

[出力結果]

この絵にセリフを足して、完成です。

使用感と課題

使用感

  • 簡単な操作
    線画と下塗りさえ用意すれば、誰でも出力できる。
  • 迅速な処理
    1〜3分程度で処理が完了。
  • 塗り精度の限界
    部分的な指定がうまく反映されない場合があり、手直しが必要なケースも。

実用性の検討

copainterを使用した場合、以下の作業時間が必要になります:

  • 下塗り:1分〜2分
  • AI着彩:3〜4分
  • 背景設定・セリフ入れなどの追加作業:6〜7分

これにより、1枚の仕上げに約15分かかる計算となり、1連載分(約120枚)の着彩・セリフ入れに必要な時間は30時間以上を要します。

さらに、登場人物の感情表現に合わせた背景設定(例:悲しい感情にブルーのグラデーション背景、喜びの感情にピンクや黄色の背景など)は、物語の文脈を理解しながら作業する必要があり、これは専門的なスキルを伴う作業といえます。

以上の理由から、効率化には課題が多く、現段階での実用化は見送るという結論に至りました。

おわりに

copainterは簡単な操作で高品質な着彩ができる優れたツールですが、現状では運用に課題が残る結果となりました。

今後も効率化の可能性を模索していきたいと思います。

エキサイトではデザイナーやエンジニアを積極採用中です!

興味のある方はぜひご連絡ください。

www.wantedly.com

Tailwind CSSで要素間の境界線をスタイリングするときはdivide-*が便利

こんにちは。エキサイトでデザイナーをしている齋藤です。

エキサイトホールディングス Advent Calendar 2024 シリーズ1の23日目を担当します。

qiita.com

今回は、TailwindCSSで要素間の境界線をスタイリングするときはdivide-*が便利というお話をします。

実現したいこと

今回実現したいUIは、以下のように行内セル間の垂直な境界線が破線になっているテーブルです。

行内セル間の垂直な境界線が破線になっているテーブル

HTML・CSS的に言い換えると、2つ目以降のtd要素の左側に破線の境界線を設けるということになります。

<table>
    ...
    <tbody>
        <tr>
            <!-- 2つ目以降の`td`要素の左側に破線の境界線を設ける -->
            <td></td>
            <td></td>
            <td></td>
        </tr>
        ...
    </tbody>
</table>

どうやってスタイリングするか

Tailwind CSSでスタイリングする場合、行内2つ目以降のtdタグに対してborder-leftを付与する力技もありますが、コードの見通しが悪くなってしまいます。

そこで有用なのが、divide-*シリーズです。

divide-*は子要素間に境界線を設けるユーティリティクラスです。

例えば、先にお示ししたテーブルの条件である「各行内のセル間に破線で黒色の垂直な境界線を設ける」を、divide-*を使用してスタイリングすると以下のようになります。(※行間の水平な境界線は割愛します)

<table>
    ...
    <tbody>
        <tr class="divide-x divide-dashed divide-black">
            <td></td>
            <td></td>
            <td></td>
        </tr>
        ...
    </tbody>
</table>
  1. divide-xで水平要素間に境界線を追加
  2. divide-dashedで境界線を破線に設定
  3. divide-blackで境界線色を黒色に設定

何が起きているか

divide-*の中身を見てみると何が起きているかが理解できます。

例えば、devide-xの場合、以下のようなCSSになっています。

.divide-x > * + * {
    border-right-width: 0px;
    border-left-width: 1px;
}
  • 親が .divide-x であること
  • .divide-x の直接の子要素であること
  • その要素の直前に、同じ .divide-x の直接の子要素があること

これらの条件に合致する要素に、border-right-width: 0px; border-left-width: 1px;が付与されるといった仕組みになっています。

まとめ

今回は、Tailwind CSSで要素間の境界線をスタイリングするときに便利なdivide-*をご紹介しました。

divide-*を使用すると、対象の要素それぞれにユーティリティクラスを付与する必要がなくなり、見通しのよいコードになる上、要素の追加もしやすくなると考えます。

Tailwind CSSを使用される方の一助となれば幸いです。

ご精読ありがとうございました。

第10回テクデザBeer Bashを開催しました

こんにちは、エキサイトでエンジニアをしている吉川です。エキサイトホールディングス Advent Calendar2024 の23日目の記事になります!

先日12/20(金)に社内イベントの「テクデザBeer Bash」を開催したので、運営視点でレポートを書いていきます。

テクデザBeer Bashとは

Beer Bashとはbeer(ビール)+ bash(にぎやかなパーティー)を合わせた造語で、真面目な部分を残しつつ、カジュアルな雰囲気で交流を行うイベントです。 年に3、4回社内カフェスペースで開催しており、同じチーム内の人はもちろん、業務ではあまり関わることがない他部署の人たちとも繋がる場になっています。

当日のコンテンツ

今回は以下の2つをメインコンテンツとし、後半はフリートークの時間にしました。 - 作って理解する動画配信の仕組み - Studioを使ったサイトづくり

作って理解する動画配信の仕組み

弊社が提供しているウェビナーPDCAクラウド「FanGrowth」では、録画した過去のウェビナーをアーカイブとして配信する機能があります。 www.fangrowth.biz

今回は動画のストリーミング配信機能の開発方法やデプロイ方法などを、担当エンジニアの方からデモを交えて発表いただきました。ストリーミングの概要は知っていても、具体的な実装は詳しくない社員も多く、勉強になったとの反響が多く寄せられました。

Studioを使ったサイトづくり

弊社が提供している予実管理クラウド「KUROTEN」の一部ページは、ノーコードのWeb制作プラットフォームであるStudioを使って開発・公開しています。 kuroten.biz

今回は担当デザイナーの方からStudioの良いところや、ページ公開にあたりどんな作業をされたのかを発表いただきました。 デザインツール連携のようなデザイナーならではの視点や、エンジニアを介さないことでよりスピーディな実装になった話をいただき、参加者からもStudioが便利そうだというお声をいただきました。

運営視点の振り返り

前回 実施した座席+バイキング形式が好評だったので、今回はよりレベルをあげて立食+バイキング形式で実施しました。 移動しやすい分多くの方と交流しやすくなり、より会を盛り上げることができました。また途中から参加する社員も入りやすい雰囲気にできたのも良かった点です。

また今までは夜19時ごろから開始していましたが、時間を早めて夕方17時ごろから開始したところ、ご家庭事情で夜参加が難しい方や遠方から出社されている方も参加しやすくなりました。こうした裾野を増やす施策は今後も積極的に行っていきたいです。

まとめ

最後まで読んでいただき、ありがとうございました。 テクデザBeer Bashは社内イベントではありますが、少しでもイベントの雰囲気が伝わっていたら幸いです。

今回も内定者の学生さんをご招待しており、参加後のアンケートでは大変満足したとご回答いただけました。今後も社員同士、社員と学生の交流を深めるイベントとしてBeerBashを盛り上げていきます!