[デザイン]

レイアウト・余白:グリッド / 視線誘導 / 整列
1. まずレイアウトは“余白”で決まる
初心者が一番つまずくのは「余白」。
プロは 余白を増やす → 可読性UP → 品質UP が鉄則。

🔹基本ルール
内側の余白(padding)は 8px の倍数 にまとめる
(8, 16, 24, 32… → 8ptグリッド)
要素の間隔も 揃える(例:すべて16px に統一)
違う余白をむやみに使わない
近くにあるものをグルーピングする(近接の原則)

2. グリッド(Grid)の基礎
Figmaでのレイアウトを整える最強の機能がグリッド。
✔ グリッドを設定する方法(Frameを選択して)
右パネル → Layout Grid → +

よく使うグリッド
① カラムグリッド(列)

Web・アプリで最重要
例:12カラム、マージン16〜24、ガター16

用途:
レスポンシブデザイン
テキスト幅の統一
コンポーネントの左右位置を揃える

② スクエアグリッド(8px)
要素の配置 / 余白 / アイコンサイズの基準

③ 行グリッド(row)
リストUI、カード群などで役立つが使用頻度は低め

3. 整列(Alignment)の基礎
整列とは、要素を揃えること。
揃っているだけで プロ感が10倍。

✔ よく使う整列
左揃え(Left align)
中央揃え(Center)
右揃え(Right align)
垂直方向の中央揃え(Vertical center)
端揃え(Top/Bottom align)

Figmaショートカット
左揃え:Shift + A → Auto Layout
整列:右上の整列ボタン群

4. 視線誘導(情報の読みやすさ)
人は画面を 左上→右下 にスキャンします。

心地よい視線誘導の作り方
✔ ① 余白のメリハリをつける
見出しの上には大きな余白
見出し下の本文は小さな余白
→ グループ感が出る
✔ ② 文字幅(行幅)を最大化しない
1行60〜80文字が読みやすい

✔ ③ 情報の階層構造を作る
大見出し(24px)
セクションタイトル(18px)
本文(14–16px)

✔ ④ 視線をブロックごとに整理する
カードUI・セクション区切りが有効

5. Figmaでの実践テクニック
✔ Auto Layout(最重要)
整列&余白を全自動にする機能。
使い方:
要素を選択 → Shift+A
効果:
余白を “Padding” で統一
子要素間を “Spacing” で統一
ボタンやカードが自動で伸びる
レスポンシブが簡単になる
✔ Constraints(固定位置)

レイアウトが変わっても要素の位置を維持
例:右上に固定したいボタンなど

✔ Frame と Group の使い分け
Frame:レイアウト管理
Group:単なるまとめ(使う頻度は少なめ)

6. よくあるNG例

❌ 余白がバラバラ(8px, 11px, 13px…)
❌ 文字が左右で揃っていない
❌ 要素が“なんとなく”置かれている
❌ 情報の階層がなく全部同じ大きさ
❌ コンポーネントの幅が統一されていない

👆 このどれかが起きると「素人っぽさ」が出ます。

7. これさえ守れば “UIが安定する” ゴールデンルール
🟦 ① 8pxグリッド

余白・サイズは「8の倍数」

🟥 ② カラムグリッドを必ず使う

Webは12カラムが基本

🟩 ③ 整列を厳格にする

左揃え + 上揃え を基本にする

🟨 ④ Auto Layoutで全ての余白を管理

パディング・ギャップを統一するとプロ級になる

[iOS]アニメーションとトランジション

import SwiftUI

struct ContentView: View {
    @State private var isBig = false

    var body: some View {
        VStack(spacing: 20) {
            Text("アニメーションの基本")
                .font(.title)

            Circle()
                .fill(.blue)
                .frame(width: isBig ? 200 : 100,
                       height: isBig ? 200 : 100)
                .animation(.easeInOut(duration: 0.5), value: isBig)

            Button("サイズ変更") {
                isBig.toggle()
            }
        }
        .padding()
    }
}
import SwiftUI

struct ContentView: View {
    @State private var showBox = false

    var body: some View {
        VStack(spacing: 20) {
            Text("トランジションの基本")
                .font(.title)

            if showBox {
                Rectangle()
                    .fill(.green)
                    .frame(width: 200, height: 150)
                    .transition(.slide)         // ← これがトランジション
                    .animation(.easeInOut, value: showBox)
            }

            Button(showBox ? "消す" : "表示") {
                showBox.toggle()
            }
        }
        .padding()
    }
}
import SwiftUI

struct ContentView: View {
    @State private var showCard = false

    var body: some View {
        VStack(spacing: 20) {
            Text("アニメーション + トランジション")
                .font(.title)

            if showCard {
                RoundedRectangle(cornerRadius: 16)
                    .fill(.orange)
                    .frame(width: 250, height: 160)
                    .shadow(radius: 10)
                    .padding()
                    .transition(.opacity.combined(with: .scale))
                    .animation(.spring(response: 0.4, dampingFraction: 0.6), value: showCard)
            }

            Button(showCard ? "隠す" : "表示") {
                showCard.toggle()
            }
        }
        .padding()
    }
}

3Dアバターの構成要素

3Dアバター制作の基本要素である
メッシュ・テクスチャ・リグ・BlendShape を、
初心者向けだけど専門的に正しくわかりやすくまとめます。

🎨 ① メッシュ(Mesh)= 形・立体の表面のこと
メッシュ=3Dの形そのものです。
点(Vertex)
線(Edge)
面(Face)
これがたくさん集まって、
人間の顔・体・服の立体モデルが作られます。

例:顔の輪郭、鼻、目、唇、髪のボリュームなど。

👀 ポイント
VRMでもBlenderでも「見えている形」は全部メッシュ。

🎨 ② テクスチャ(Texture)= 色・模様の画像のこと
メッシュは“形”だけなので、まだ色がありません。
そこで使うのがテクスチャ。
モデルに貼り付けられた「画像(2D)」のことです。

肌の色
目の模様
服の柄
影の塗り(アニメ調)
シワや質感
すべて テクスチャ画像(PNG/JPEG) で表現されます。

📌 よくある例
VRMの「テクスチャ」というフォルダ内に
face.png
body.png
hair.png
などが入っています。

🦴 ③ リグ(Rig)= 操作するための“骨”の仕組み
メッシュを動かすために内部に入れるのが 骨(ボーン / Armature)。
首を曲げる
口を動かす
手を振る
体を回す

こういった動きは リグ(骨)をメッシュに紐づけることで実現します。

📌 VRM では「Humanoid(人型)の規格」が決まっているため、
UnityやThree.jsが自動で動かしやすいようになっています。

😀 ④ BlendShape(ブレンドシェイプ)= 形の変形(表情・口の動き)
メッシュを「別の形に変形させる仕組み」です。
例えば:
BlendShape名 変形の意味
A 口を「あ」の形に開く
I 「い」の形
O 「お」の形
Smile 口角を上げる
Blink まばたき
Angry 怒り表情

複数のBlendShapeを“混ぜる(Blend)”ことで表情が作れる → これが名前の由来。

📌 リップシンクでは
Viseme(発音記号) → BlendShape(口の形)
へ変換して口の動きを作ります。

⭐ 4つの違いを1行でまとめる
名称 一言で言うと
メッシュ 立体の形
テクスチャ その形に貼る色・模様(画像)
リグ(骨) 動かすための骨組み
BlendShape 表情や口の形の変形

全部セットで、
「しゃべって動く3Dアバター」 が成立します。

[TTS] WAV

TTS が出力する音声ファイルとして最も一般的な形式のひとつです。
特徴:
音質が劣化しない
サイズは MP3 より大きい
音声処理(AI、機械学習、編集)に使われやすい
多くの TTS エンジンのデフォルト出力

from openai import OpenAI

client = OpenAI(api_key="YOUR_API_KEY")

# TTSで音声(WAV)を生成
response = client.audio.speech.create(
    model="gpt-4o-mini-tts",
    voice="alloy",
    input="こんにちは、これはWAV形式のサンプルです。",
    format="wav"
)

# バイナリを保存
with open("sample.wav", "wb") as f:
    f.write(response.read())

print("sample.wav を作成しました")

Google cloud

from google.cloud import texttospeech

client = texttospeech.TextToSpeechClient()

input_text = texttospeech.SynthesisInput(text="こんにちは、WAVのサンプルです。")

voice = texttospeech.VoiceSelectionParams(
    language_code="ja-JP",
    name="ja-JP-Wavenet-B"
)

audio_config = texttospeech.AudioConfig(
    audio_encoding=texttospeech.AudioEncoding.LINEAR16  # WAV
)

response = client.synthesize_speech(
    input=input_text,
    voice=voice,
    audio_config=audio_config
)

with open("sample.wav", "wb") as out:
    out.write(response.audio_content)

WAV = 高音質の音声ファイル形式
TTS の標準出力としてよく使われる
Python の TTS では簡単に WAV を生成できる

[LLM] マルチモーダル

画像 → 理解 → テキスト回答 の最小構成

from openai import OpenAI
import base64

client = OpenAI()

# 画像ファイルを base64 化
with open("image.jpg", "rb") as f:
    img_base64 = base64.b64encode(f.read()).decode("utf-8")

# マルチモーダル(画像 + テキスト)問い合わせ
response = client.chat.completions.create(
    model="gpt-4o",   # または gpt-4o-mini
    messages=[
        {"role": "user", "content": [
            {"type": "text", "text": "この画像を説明してください。"},
            {
                "type": "image_url",
                "image_url": {
                    "url": f"data:image/jpeg;base64,{img_base64}"
                }
            }
        ]}
    ]
)

print(response.choices[0].message["content"])

何が起きているか?
1. 画像を base64 でエンコード
OpenAI API ではファイルアップロードせず、そのまま Base64 で画像を送れる。

2. messages に「画像 + テキスト」を混在させる
{“type”: “image_url”, …} を入れることでマルチモーダルの入力が可能になる。

3. gpt-4o が画像を理解し、テキストで返す
画像認識モデル + 言語モデルが統合されているため、追加設定不要。

[Android] Jetpack Compose Navigation

Jetpack Compose Navigation(複雑版サンプル)

ポイントは次の 4 つ:
NavHost + NavController
複数画面(Home → Detail → Settings)
パラメーター付きルート(Detail/{itemId})
戻る動作(popBackStack

MainActivity.kt
└─ HomeScreen
└─ DetailScreen
└─ SettingsScreen

package com.example.navigationdemo

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.material3.*
import androidx.compose.runtime.Composable
import androidx.navigation.NavType
import androidx.navigation.compose.*
import androidx.compose.foundation.layout.*
import androidx.compose.material3.Button
import androidx.compose.material3.Text

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            NavigationApp()
        }
    }
}

@Composable
fun NavigationApp() {
    val navController = rememberNavController()

    NavHost(
        navController = navController,
        startDestination = "home"
    ) {
        // ① Home
        composable("home") {
            HomeScreen(
                onSelectItem = { itemId ->
                    navController.navigate("detail/$itemId")
                },
                onOpenSettings = {
                    navController.navigate("settings")
                }
            )
        }

        // ② Detail(パラメータ付き)
        composable(
            route = "detail/{itemId}",
            arguments = listOf(
                navArgument("itemId") { type = NavType.IntType }
            )
        ) { backStackEntry ->
            val id = backStackEntry.arguments?.getInt("itemId")
            DetailScreen(
                itemId = id ?: 0,
                onBack = { navController.popBackStack() }
            )
        }

        // ③ Settings
        composable("settings") {
            SettingsScreen(
                onBack = { navController.popBackStack() }
            )
        }
    }
}

@Composable
fun HomeScreen(onSelectItem: (Int) -> Unit, onOpenSettings: () -> Unit) {
    Column(
        modifier = Modifier.fillMaxSize().padding(20.dp),
        verticalArrangement = Arrangement.spacedBy(16.dp)
    ) {
        Text("Home Screen", style = MaterialTheme.typography.headlineMedium)

        Button(onClick = { onSelectItem(10) }) {
            Text("Go to Detail (itemId = 10)")
        }

        Button(onClick = onOpenSettings) {
            Text("Go to Settings")
        }
    }
}

@Composable
fun DetailScreen(itemId: Int, onBack: () -> Unit) {
    Column(
        modifier = Modifier.fillMaxSize().padding(20.dp),
        verticalArrangement = Arrangement.spacedBy(16.dp)
    ) {
        Text("Detail Screen", style = MaterialTheme.typography.headlineMedium)
        Text("itemId = $itemId")

        Button(onClick = onBack) {
            Text("Back")
        }
    }
}

@Composable
fun SettingsScreen(onBack: () -> Unit) {
    Column(
        modifier = Modifier.fillMaxSize().padding(20.dp),
        verticalArrangement = Arrangement.spacedBy(16.dp)
    ) {
        Text("Settings Screen", style = MaterialTheme.typography.headlineMedium)

        Button(onClick = onBack) {
            Text("Back")
        }
    }
}

[TTS] pmcとは

「TTS の PMC」という言葉は、文脈によって指しているものが異なりますが、
主に以下の2つの意味で使われることが多い。

結論からいうと、TTS(Text-to-Speech)分野でよく出てくる PMC = Prosody Model / Prosody Modification / Prosody Modeling Component の略として使われることがある。

1. Prosody Modeling Component(韻律モデル・韻律制御モジュール)
TTS が自然に聞こえるためには、
イントネーション(抑揚)
音の強弱
音の高さ(F0)
話速(テンポ)
間の取り方(ポーズ)
といった 韻律(Prosody) が非常に重要

これらを制御する仕組みを Prosody Modeling Component (PMC) と呼ぶ

特に以下のような論文や TTS アーキテクチャで登場する用語です:
Tacotron 系
FastSpeech 系
Prosody Embedding
Duration / Pitch / Energy Predictor

2. Prosody Modification Control(韻律変更コントロール)
TTS に emotion や表現力を持たせるときに必要な操作で、
PMC = Prosody Modification Control(韻律変換コントロール)
という意味で使われることもあります。

例:
ピッチカーブを直接操作する
話速/音素長を変える
感情(怒り、喜び、悲しみ)を調整
商用TTSエンジンや研究用TTSで PMC という言葉を使うケースがあります。

TTS の PMC = Prosody(韻律)に関係するモジュールの総称
Prosody Modeling Component
Prosody Modification Control
などの略として使われることが多い

PMC の役割
抑揚
強弱
音の高さ
話速
ポーズ
感情表現

これらを予測したり制御するのが PMC の仕事

[LLM] LangChain Docs

1. Models(モデル)
LLM や Embedding、画像モデルなど 外部AIモデル を扱うためのモジュール。

含まれる内容
Large Language Models(OpenAI, Anthropic, Azure, HuggingFace など)
ChatModels(チャット用インターフェース)
Embeddings(ベクトル化)
Text-to-Speech / Speech-to-Text
Vision Models

学べること
「複雑な API 呼び出しを、統一的なインターフェースで扱える」

例えば OpenAI と HuggingFace のモデルを同じコードスタイルで使えるようになる。

from langchain_community.llms import HuggingFaceHub
llm = HuggingFaceHub(repo_id=”mistralai/Mistral-7B-Instruct-v0.2″)

2. Prompts(プロンプト)
LLM に渡す指示文を構築・生成・管理する部分。
できること
Prompt Templates(テンプレート化)
Few-shot の自動選択
パラメータ差し込み
出力フォーマット強制(JSON化など)

学べること
「プロンプトをコードとして管理する仕組み」
from langchain.prompts import PromptTemplate

prompt = PromptTemplate.from_template(“要約して: {text}”)
prompt.format(text=”これはテスト文です”)

3. Chains(チェーン)
LLM・ツール・データ処理を パイプラインとしてつなぐ仕組み。
代表例
LLMChain
SequentialChain(複数ステップ実行)
SimpleSequentialChain
学べること

LLM → 加工 → LLM という流れを組み立てる。

from langchain.chains import LLMChain
chain = LLMChain(llm=llm, prompt=prompt)
chain.run(“こんにちは”)

4. Agents(エージェント)
LLM が “自分でツールを選んで使う” 仕組み。
LangChain の最も特徴的な部分。
エージェントでできること
ツール使用(検索、計算、API呼び出し)
思考の分岐(ReAct)
マルチステップ問題解決
学べること
AI に “行動する力” を与える方法。

agent = initialize_agent(
tools=[search_tool, calculator],
llm=llm,
agent=”zero-shot-react-description”,
)
agent.run(“東京の天気を調べて摂氏で教えて”)

5. Retrieval(RAG:検索 + LLM)
外部データを読み込んで検索させる仕組み。
企業で一番使われるのがこれ。
主な機能

VectorStores(Chroma, Pinecone, Qdrant, FAISS)
Document loader(PDF, HTML, Notion, URL)
Retriever(検索器)
RAG チェーン全般

学べること

大量の社内文書を元に答えるチャットボットの実装方法。

from langchain.vectorstores import Chroma
db = Chroma.from_texts(texts, embeddings)
retriever = db.as_retriever()

[TTS] Flaskチャットに音声応答機能を統合

以下では OpenAI の TTS API(新しい audio API)を Flask チャットアプリで使う方法 を、
できるだけシンプルで実用的な構成で紹介します。

✅ 基本構成
Flaskでチャットアプリを作る場合、
Web画面でユーザーがテキスト入力
Flaskサーバーが OpenAI API に TTS リクエスト
得た音声バイナリ(mp3/wav)を返す
ブラウザ側で audio タグ / JS で再生
という流れになります。

📌 必要ライブラリ
pip install flask openai

🚀 サンプル:Flask + OpenAI TTS API
📁 app.py

from flask import Flask, request, send_file, jsonify
from openai import OpenAI
import os
import io

app = Flask(__name__)

# OpenAI API キー
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))

@app.route("/")
def index():
    return """
    <form action="/tts" method="post">
        <input name="text" placeholder="Enter text">
        <button type="submit">Generate</button>
    </form>
    """

@app.route("/tts", methods=["POST"])
def tts():
    text = request.form.get("text", "")

    # OpenAI TTS API 呼び出し
    response = client.audio.speech.create(
        model="gpt-4o-mini-tts",     # OpenAI TTSモデル
        voice="alloy",               # 声(例:alloy / verse / shimmer など)
        input=text,
        format="mp3"
    )

    # バイナリ取得
    audio_bytes = response.read()

    # メモリ内に保存して返す
    return send_file(
        io.BytesIO(audio_bytes),
        mimetype="audio/mpeg",
        download_name="speech.mp3"
    )

if __name__ == "__main__":
    app.run(debug=True)

📌 ブラウザで音声を自動再生するフロント(例)

index.html を返すなら:

<!DOCTYPE html>
<html>
<body>
    <h2>OpenAI TTS Demo</h2>
    <input id="txt" placeholder="Enter text">
    <button onclick="speak()">Speak</button>
    <audio id="audio" controls></audio>

    <script>
        async function speak() {
            const text = document.getElementById("txt").value;

            const formData = new FormData();
            formData.append("text", text);

            const res = await fetch("/tts", { method: "POST", body: formData });
            const blob = await res.blob();

            const url = URL.createObjectURL(blob);
            document.getElementById("audio").src = url;
        }
    </script>
</body>
</html>

🔊 レスポンス形式の選択

OpenAI公式では以下が使えます:

形式 MIMEタイプ 特徴
mp3 audio/mpeg 一般的・最小サイズ
aac audio/aac 高音質
wav audio/wav ロスレス(重い)
flac audio/flac 高品質