見出し画像

メインタブ表示|ココフォリアカスタムCSS

- TRPGをオンラインで遊ぶにあたり、オンラインセッションツール『ココフォリア』を使用することが多い
- 楽しく遊べればそれでいいんだけど、せっかくなら後で見返せるようにログを残しておきたい
- せっかくならログを見やすく&プレイ当時の印象が思い出せるような画面にしてみたい

元記事:OBSでココフォリアを録画するときのカスタムCSS

今回はチャットのメインタブのカスタムCSSです。

OBSでの使用イメージ

参考にさせていただきました

Made by 葉桜ヨウ
YouTube:https://www.youtube.com/channel/UCtEKNmkUAj02lI3TtY6U0SA
Twitter:https://twitter.com/you_hzkr

you-custom-css クレジット記載より

魔改造しています(CSS)

可読性担保のためOBSで座布団敷くのをおすすめします
/**************************
ccfolayer-chat-001 
**************************/

/**************************
https://ghgantz.github.io/customCss/ccfolia/chat.css 
から「ユーザ名を設定した色にしたい場合」を改変
**************************/

:root {
  /** 表示行数の上限 */
  --line-clamp: 3;
  /** ダイス結果の上下揃えの設定 */
  --is-top: auto; /* 上揃えの場合⇒0、下揃えの場合⇒auto */
  --is-bottom: 0; /* 上揃えの場合⇒auto、下揃えの場合⇒0 */
  /** ダイス結果背景 */
  --width: 500px; /** 結果の横幅 */
  --background-color: rgba(0, 0, 0, 0.6); /** 背景色 */
  --background-padding: 8px 18px 8px 18px; /** 外枠と文字の隙間 */
  --border-color: rgba(255, 255, 255, 1); /** 枠線の色 */
  --border-image: url(https://xxx/yyy.png); /** 枠線に画像を使用 */
  --border-slice: 0px; /** 枠線画像の太さ */
  --border-width: 0px; /** 枠線の幅 */
  --border-radius: 10px; /** 角の丸み */
  --border-shadow: 5px 5px 10px black; /** 読み方)X軸 Y軸 影の幅 色 */
  --result-space: 10px; /** ダイス結果同士の隙間 */
  /** アイコン画像の設定 */
  --icon-radius: 30%; /** 画像の丸み:0%⇒四角、50%⇒正円 */
  --icon-background-color: transparent; /** アイコン背景色:transparentで透明 */
  --icon-width: 70px; /** 画像の横幅 */
  --icon-height: 70px; /** 画像の高さ */
  --icon-margin-top: 0px; /** アイコン上のスペース */
  --icon-margin-bottom: 0px; /** アイコン下のスペース */
  --icon-margin-left: -20px; /** アイコン左のスペース */
  --icon-margin-right: 15px; /** アイコン右のスペース */
  /** ダイス結果の文字部分(デフォルト) */
  --font-size-result: 1.5rem;
  --font-color-result: rgba(255, 255, 255, 1);
  --font-shadow-result: 2px 2px 3px black; /** 読み方)X軸 Y軸 影の幅 色 */
  /** 成功時の青文字部分 */
  --font-size-success: 1.1rem;
  --font-color-success: rgba(134, 202, 255, 1);
  --font-shadow-success: 2px 2px 3px black; /** 読み方)X軸 Y軸 影の幅 色 */
  /** 失敗時の赤文字部分 */
  --font-size-fail: 1.1rem;
  --font-color-fail: rgba(255, 161, 161, 1);
  --font-shadow-fail: 2px 2px 3px black; /** 読み方)X軸 Y軸 影の幅 色 */
  /** ユーザ名の部分 */
  --font-size-user-name: 1.1rem;
  --font-color-user-name: rgba(255, 255, 255, 1);
  --font-shadow-user-name: 2px 2px 3px black; /** 読み方)X軸 Y軸 影の幅 色 */
  /** ダイスを振った時間を表示するか */
  --disp-dice-time: transparent; /** none⇒表示しない、transparent⇒表示する */
  --font-size-dice-time: 1rem;
  --font-color-dice-time: rgba(255, 255, 255, 0.6);
  --font-shadow-dice-time: 2px 2px 3px black; /** 読み方)X軸 Y軸 影の幅 色 */
}

/**************************
 OBS用のおまじない
**************************/

body {
  background-color: rgba(0, 0, 0, 0);
  margin: 0px auto;
  overflow: hidden;
}

/**************************
 非表示要素の設定
**************************/

/** ツールバー */
.MuiToolbar-regular,
/** ダイス結果 */
.MuiPaper-elevation1,
/** チャット入力欄の削除 */
.MuiPaper-root > form,
/** 背景の非表示 */
#root>div>div:nth-child(2),
/** 前景全体 */
#root>div>div:nth-child(3),
/** 監視モード注釈の削除 */
.MuiSnackbar-root,
/** 広告の削除 */
.MuiDialog-root {
  display: none !important;
}

/**************************
 元デザイン
**************************/

/** 右側全体 */
.MuiDrawer-root > .MuiPaper-root {
  /** チャットがアニメーションする幅を確保 */
  width: 100% !important;
}

/** ダイス結果間の境界線 */
hr {
  display: none !important;
}

/** ダイス結果 */
.MuiList-root > div > div > div {
  padding: var(--background-padding) !important;
  background: var(--background-color) !important;
  border: solid var(--border-width) var(--border-color) !important;
  border-radius: var(--border-radius) !important;
  border-image-source: var(--border-image) !important;
  border-image-slice: var(--border-slice) !important;
  background-repeat: no-repeat !important;
  background-position: center !important;
  background-size: cover !important;
  box-sizing: border-box !important;
  box-shadow: var(--border-shadow) !important;
  align-items: center !important;
  /** ダイス結果の横幅を設定 */
  width: var(--width) !important;
  height: auto !important;
  position: relative !important;
  top: 0 !important;
  /** ダイス結果同士の距離感を設定 */
  margin: var(--result-space) !important;
  /** 要素の高さを持ってる子要素に合わせる */
  height: auto !important;
  min-height: auto !important;
  /** ダイス結果の横幅を設定 */
  width: var(--width) !important;
  /** top,leftなどの影響を受けないようにする */
  position: relative !important;
  /* 他の要素のサイズで箱の要素の横幅が変わらないよう固定 */
  flex-shrink: 0 !important;
  /** 自動で設定されるtopをリセットする */
  top: 0 !important;
  /** ダイス結果をすべて非表示に。外出しした設定にimportantを付けることで設定した個数だけ表示する */
  display: none;
}

/** チャット欄アイコン入れ物 */
.MuiListItemAvatar-root {
  min-width: unset;
  margin-top: var(--icon-margin-top) !important;
  margin-bottom: var(--icon-margin-bottom) !important;
  margin-left: var(--icon-margin-left) !important;
  margin-right: var(--icon-margin-right) !important;
}
/** チャット欄アイコン背景 */
.MuiListItemAvatar-root > div {
  width: var(--icon-width) !important;
  height: var(--icon-height) !important;
  background: var(--icon-background-color) !important;
  border-radius: var(--icon-radius) !important;
}
/** チャット欄アイコン画像 */
.MuiListItemAvatar-root img {
  width: var(--icon-width) !important;
}

/** 右側背景 */
.MuiPaper-root {
  background-color: rgba(0, 0, 0, 0) !important;
}

/** ダイス結果のスクロールを発生させないよう高さを指定 */
.MuiList-root > div {
  height: 100% !important;
}
.MuiList-root > div > div {
  position: absolute !important;
  /** ダイス結果の上揃え、下揃えを設定 */
  top: var(--is-top) !important;
  bottom: var(--is-bottom) !important;
}

/* ダイス結果欄のテキストすべてを囲う要素 */
.MuiListItemText-root {
  /* ダイス結果が長すぎて四角をはみ出た場合に、はみ出し部分を表示しない */
  overflow: hidden !important;
}

/** ダイス結果テキスト(ユーザ名などを除く) */
p.MuiTypography-root {
  /** -webkit-line-clampを有効にするためのおまじない */
  display: -webkit-box !important;
  -webkit-box-orient: vertical !important;
  /* ダイス結果の上限行数を指定(超えると…表示になる) */
  -webkit-line-clamp: var(--line-clamp) !important;
  color: var(--font-color-result) !important;
  text-shadow: var(--font-shadow-result) !important;
  font-size: var(--font-size-result) !important;
}

/** 成功時の青文字部分 */
.MuiTypography-colorPrimary {
  color: var(--font-color-success) !important;
  text-shadow: var(--font-shadow-success) !important;
  font-size: var(--font-size-success) !important;
}

/* 失敗時の赤字部分 */
.MuiTypography-colorSecondary {
  color: var(--font-color-fail) !important;
  text-shadow: var(--font-shadow-fail) !important;
  font-size: var(--font-size-fail) !important;
}

/** ダイス結果(1D100)など */
.MuiTypography-colorTextSecondary {
  font-size: inherit !important;
  font-weight: inherit !important;
}

/* ユーザ名、ダイスを振った時間 */
.MuiListItemText-primary,
.MuiTypography-caption {
  /** ユーザ名を設定した色にしたい場合はここ(color)を削除する */
/*   color: var(--font-color-user-name) !important; */
  text-shadow: var(--font-shadow-user-name) !important;
  font-size: var(--font-size-user-name) !important;
}
/* ダイスを振った時間 */
span.MuiTypography-root.MuiTypography-caption {
  display: var(--disp-dice-time) !important;
  color: var(--font-color-dice-time) !important;
  text-shadow: var(--font-shadow-dice-time) !important;
  font-size: var(--font-size-dice-time) !important;
}

/**************************
アニメーション設定改変
**************************/

.MuiList-root>div>div>div {
  animation-name: fadeBottomToTopToLeft;
  animation-duration: 20s;
  animation-fill-mode:forwards;
  animation-iteration-count:1;
  animation-timing-function:ease;
  animation-delay: 0s;
  animation-direction:normal;
}

@keyframes fadeBottomToTopToLeft {
  0% {
    opacity: 0;
    transform: translateY(50px);
  }

  3% {
    opacity: 1;
    transform: translateX(0);
  }

  97% {
    opacity: 1;
    transform: translateX(0);
  }

  100% {
    opacity: 0;
    transform: translateX(-15px);
  }
}

/**************************
ccfolayer-chat-001 
見た目を上書き
**************************/

/* 表示個数の指定 */
.MuiList-root>div>div>div:nth-last-child(-n+5) {
  display: block !important;
  padding-top: 0px !important;
  padding-bottom: 0px !important;
}

/* 最後からn番目までのデザイン(ccfolayer-chat-001) */

/* 変数上書き */
:root {
  --background-color: rgba(0,0,0,0);
  --background-padding: 0;
  --border-radius: 0;
  --border-shadow: 0;
  --result-space: 0;
  --width: auto;
  --font-shadow-result: 0px 1px 5px rgba(0,0,0,1);
  --disp-dice-time: none;
  --icon-radius: 0%;
  --line-clamp: auto;
  --font-size-result: 1.25rem;
  --font-size-user-name: 1.25rem;
  --font-color-user-name: inherit;
  --font-shadow-user-name: 0px 1px 5px rgba(0,0,0,1); 
  --icon-margin-top: 0px;
  --icon-margin-bottom: 0px;
  --icon-margin-left: 0px;
  --icon-margin-right: 8px;
  --icon-width: 36px;
  --icon-height: 36px;
  --icon-radius: 50%;
}

/* チャット欄入れ物 */
.MuiList-root>div>div>div>div {
  padding: 0;
  position: relative;
}

/** チャット欄アイコン入れ物 */
.MuiListItemAvatar-root {
  min-width: unset;
  margin-top: var(--icon-margin-top) !important;
  margin-bottom: var(--icon-margin-bottom) !important;
  margin-left: var(--icon-margin-left) !important;
  margin-right: var(--icon-margin-right) !important;
}
/** チャット欄アイコン背景 */
.MuiListItemAvatar-root > div {
  position: relative;
  width: var(--icon-width) !important;
  height: var(--icon-height) !important;
  background: var(--icon-background-color) !important;
  display: flex;
  flex-direction: column;
}

/* アイコンが横長のときに画像を下に押しやる */
.MuiListItemAvatar-root > div::before {
  content: "";
  flex-shrink: 1;
  flex-grow: 1;  
}

/** チャット欄アイコン画像 */
.MuiListItemAvatar-root img {
  width: var(--icon-width) !important;
  flex-shrink: 0;
}

/* テキスト表示部*/
.MuiListItemText-root {
  z-index: -1 !important;
  overflow: visible !important;
}

/* 名前をアイコン裏の色に転用 */
.MuiListItemText-primary {
  position: absolute;
  top: 0;
  left: 0;
  display: block;
  z-index: -1;
  border-radius: var(--icon-radius);
  width: var(--icon-width);
  height: var(--icon-height);
}

.MuiListItemText-primary::before {
  width: var(--icon-width);
  height: var(--icon-height);
  content: "";
  display: block;
  background-color: currentcolor;
}

/* 最後から1番目だけデザインを上書き(ccfolayer-chat-001)*/

/* 変数追加 */
:root {
  --primary-icon-width: 360px;
  --primary-icon-height: 360px;
  --primary-icon-radius: 0%;
  --primary-chat-height: 180px;
  --primary-chat-margin-top: 16px;
  --primary-chat-font-size: 2rem;
}

/* 通常チャット位置をあわせる */
.MuiList-root>div>div>div:nth-last-child(-n+5) {
  padding-left: var(--primary-icon-width) !important;
}
.MuiList-root>div>div>div:nth-last-child(-n+1) {
  padding-left: 0 !important;
}

/* チャット欄入れ物 */
.MuiList-root>div>div>div:nth-last-child(-n+1) {
  height: var(--primary-chat-height) !important;
  margin-top: 8px !important;
}

/* チャット欄アイコン入れ物 */
.MuiList-root>div>div>div:nth-last-child(-n+1) .MuiListItemAvatar-root {
  margin-right: 0 !important;
  overflow: hidden;
  margin-top: calc(-1 * calc(var(--primary-icon-height) - var(--primary-chat-height)))  !important;
}

/** チャット欄アイコン背景 */
.MuiList-root>div>div>div:nth-last-child(-n+1) .MuiListItemAvatar-root > div {
  width: var(--primary-icon-width) !important;
  height: var(--primary-icon-height) !important;
  background: var(--icon-background-color) !important;
  border-radius: var(--primary-icon-radius) !important;
}

/** チャット欄アイコン画像 */
.MuiList-root>div>div>div:nth-last-child(-n+1) .MuiListItemAvatar-root img {
  width: var(--primary-icon-width) !important;
  filter: drop-shadow(0px 4px 4px rgba(0, 0, 0, 0.25));
}

/* 名前をアイコン裏の色に転用 */
.MuiList-root>div>div>div:nth-last-child(-n+1) .MuiListItemText-primary {
  position: relative;
  z-index: -1;
  border-radius: var(--primary-icon-radius);
  border: none;
  overflow: visible;
  margin-left: 0;
}

.MuiList-root>div>div>div:nth-last-child(-n+1) .MuiListItemText-primary::before {
  position: absolute;
  top: calc(-1*var(--primary-chat-margin-top));
  left: 0;
  width: var(--primary-icon-width);
  height: var(--primary-chat-height);
  content: "";
  display: block;
  background: linear-gradient(90deg, currentcolor 0%, rgba(0, 0, 0, 0) 100%);;
  flex-shrink: 0;
  transform: translateX(calc(-1*calc(var(--primary-icon-width) + var(--icon-width) + var(--icon-margin-right))));
  transform-origin: top left;
}

/* テキスト位置調整 */
.MuiList-root>div>div>div:nth-last-child(-n+1) .css-1xar93x {
  margin-top: var(--primary-chat-margin-top);
  margin-left: calc(var(--icon-width) + var(--icon-margin-right));
  height: calc(var(--primary-chat-height) - var(--primary-chat-margin-top)*2)
}

/* 名前テキスト調整 */
.MuiList-root>div>div>div:nth-last-child(-n+1) .MuiListItemText-primary {
  font-size: var(--primary-chat-font-size) !important;
}

/* 本文テキスト調整 */
.MuiList-root>div>div>div:nth-last-child(-n+1) p.MuiTypography-root {
  font-size: var(--primary-chat-font-size) !important;
  margin-top: .5em;
  overflow-y: clip;
  height: 3em;
}


/* 成功テキスト */
.css-1l6qhgm {
  font-size: inherit;
  color: #5f96ff;
  font-weight: bold;
}
/* 通常テキスト  */
.css-ucj12 {
    font-size: inherit;
    color: #fff;
    font-weight: bold;
}
/* 失敗テキスト */
.css-1j13mke {
  font-size: inherit;
  color: #ff4b56;
  font-weight: bold;
}

利用について

  • このCSSはココフォリアのアップデートでCSSのclassやDOM構造が変更されたら動かなくなりますが、緊急のサポートは行えません。

  • 利用報告・クレジット表記不要です。


実装メモ

  • メインのフキダシだと内容がスクロールするから便利だが、全身立ち絵のキャラクターのアイコンが設定依存で非表示になることを考えると…チャットメインタブ改造のが…見ていて楽しいかなという判断

    • 長文は2行までと割り切る(ボイスセッションメインのため)

  • 複数のPCに一度に判定させるときがあるので(新クトゥルフなら正気度チェックなど)、5個くらい前までのログを追えるようにしたい意図

  • 複数行かもなのでトリミングでの決め打ち対応も微妙

  • よって「尻から1個目はデカく表示し、尻から2〜5は小さく表示」をする必要があった。別ソースに分けてしまうほうがシンプルだが、下記の問題が発生した。

    • :nth-last-child(-n+5)的なやつで「後ろから2〜5番目…」みたいな書き方が出来なかった

    • (1番目だけdisplay:none;とかしてみたんだけど…)メインタブを追加した瞬間に1番目→2番目のアニメーションが入るため、ほとぼり冷めてからダイス振ったりするとDOM書き換わりにより直前の2個目がログ側にひょっこり表示されてしまった。

  • そのため、後ろから1番目のスタイルを上書きする形になった。上書き部分を省けば、雑談タブなどに転用可能と思われる。


日々のコーヒー代になります!