はじめに
最近、Youtube動画の演出で「化物語でよく見る閑話休題や黒駒演出取りいれるのはどうだろう」と思い、動画編集ソフト上で実現してみた。
場面転換としてなかなか優秀だなと思い、これからこの演出を使っていこうかなと思ったが...
「都度色を考えたり、カラーコードコピーしたりが面倒だ...!!」
というわけで、自分が楽するためにサクッと閑話休題演出を作ってくれる簡単なWebアプリを作ってみた。
なお、1時間ちょっとで作ったver0.5版なので、簡単な操作しかできないが、気が向いたらもう少しブラッシュアップする予定。
作った(作っている)モノ
(PC画面しか対応してなくてスマン)
化物語「風」扉絵メーカー
こんな感じのモノが出来る。下部のボタンでダウンロードできる。(ブラウザはChromeでしか動作確認していない)
UIはクソでスマン。後でもう少しマシにする。
出来ること
- 画面上のメインテキスト/サブテキストの編集(「化物語 桃駒」の部分とその下の英字)ができる(テキスト中身編集/位置移動回転)
- Select Themeの色アイコンをクリックで、簡単に色テーマを切り替えできる
- FontColor, BackgroundColor 欄に色コード(#333333やwhite など)を指定することで、好きなカラーに変更可能
- Toggle Frameで周辺の白枠表示/非表示コントロールが可能
- Downloadボタンで編集結果の画像をダウンロード可能
ソース
ソース本体
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script
src="https://code.jquery.com/jquery-3.6.0.js"
integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk="
crossorigin="anonymous"></script>
<script type="text/javascript" src="js/lib/fabric.min.js"></script>
<script type="text/javascript" src="js/lib/FileSaver.js"></script>
<script type="text/javascript" src="js/lib/canvas-toBlob.js"></script>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Noto+Serif+JP:wght@500&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Kotta+One&family=Noto+Serif+JP:wght@500&family=Quintessential&display=swap" rel="stylesheet">
<style>
#canvas{
display: block;
}
#meta-wrapper {
margin-left: auto;
margin-right: auto;
}
#wrapper {
width: 100%;
height: 100%;
}
.color-preset-changer {
width: 32px;
height: 32px;
border-radius: 16px;
margin: 8px;
display: inline-block;
}
</style>
<title>化物語「風」扉絵メーカー v0.5(プロトタイプ)</title>
</head>
<body>
<div style="display: block">
<div id="meta-wrapper">
<div id="wrapper">
<canvas id="canvas" width="" height=""></canvas>
</div>
</div>
<div id="current-color-wrapper">
<span class='setting-label'>FontColor: </span>
<input type="text" id="current-color-fontColor">
<span class='setting-label'>BackgroundColor: </span>
<input type="text" id="current-color-bgColor">
<button id="current-color-change-button">Change Color</button>
</div>
<div id="color-preset-wrapper"></div>
<div id="frame-toggle-wrapper">
<div class='setting-label'>Toggle Frame: </div>
<input type="checkbox" id="frame-toggle-check">
</div>
<div id="download-image-wrapper">
<button id="download-image">Download</button>
</div>
<input type="hidden" id="current-theme-holder">
</div>
<script>
const COLOR_PRISETS = ["#1f2a3b/#ffffff", "#443830/#ffffff", "#9b459b/#ffffff", "#e0684b/#ffffff", "#dd931b/#ffffff", "#c40c09/#ffffff", "#bfbdbe/#ffffff", "#7d002f/#ffffff", "#e16369/#ffffff", "#e2601b/#ffffff", "#d2bd6b/#ffffff", "#90b932/#ffffff", "#8190ab/#1a1212", "#eaeae8/#8190ab"]
const elCanvas = document.getElementById("canvas")
const elWrapper = document.getElementById("wrapper")
const baseWidth = elWrapper.offsetWidth * 0.8
const canvasWidth = baseWidth
const canvasHeight = baseWidth * 9 / 16
elCanvas.width = canvasWidth
elCanvas.height = canvasHeight
const canvas = new fabric.Canvas("canvas")
const [defaultBgColor, defaultFontColor] = COLOR_PRISETS[0].split("/")
const defaultFontFamily = "HGP明朝B, 'HGP明朝B', Noto Serif JP, 'Noto Serif JP', serif"
$("#current-theme-holder").attr("data-attr-bgcolor", defaultBgColor).attr("data-attr-fontcolor", defaultFontColor)
const bg = new fabric.Rect({
left: 0,
top: 0,
fill: defaultBgColor,
width: canvasWidth,
height: canvasHeight,
selectable: false,
})
const mainText = new fabric.IText("化物語 黒齣", {
fontWeight: 'normal',
left: canvasWidth / 2,
top: canvasHeight / 2 - 48,
fontFamily: defaultFontFamily,
charSpacing: 1000,
fill: defaultFontColor,
fontSize: 64,
originX: "center",
originY: "center",
selectable: true,
})
const subText = new fabric.IText("bakemonogatari kuro", {
fontWeight: 'normal',
left: canvasWidth / 2,
top: canvasHeight / 2 + 24,
fontFamily: "Kotta One, 'Kotta One', serif",
fontStyle: 'italic',
charSpacing: 10,
fill: defaultFontColor,
fontSize: 24,
originX: "center",
originY: "center",
selectable: true,
})
const rectangleWrap = new fabric.Rect({
left: 64,
top: 48,
fill: "transparent",
width: canvasWidth - 128,
height: canvasHeight - 96,
selectable: false,
stroke: "transparent",
strokeWidth: 4,
})
const calcFrameColor = color=> $("#frame-toggle-check").prop('checked') ? color : "transparent"
const changeTheme = (bgColor, fontColor)=> {
$("#current-theme-holder").attr("data-attr-bgcolor", bgColor).attr("data-attr-fontcolor", fontColor)
bg.set("fill", bgColor)
mainText.set("fill", fontColor)
subText.set("fill", fontColor)
rectangleWrap.set("stroke", calcFrameColor(fontColor))
canvas.renderAll()
}
$("#color-preset-wrapper").append("<div class='setting-label'>Select Theme: </div>")
const elColorPresetWrapper = COLOR_PRISETS.forEach(v=> {
const [bgColor, fontColor] = v.split("/")
const el =
$(`<div id='${v}' class='color-preset-changer' style='background-color: ${bgColor}' data-attr-bgcolor='${bgColor}' data-attr-fontcolor='${fontColor}'></div>`)
.on("click", event=> {
const bgColor = $(event.target).attr("data-attr-bgcolor")
const fontColor = $(event.target).attr("data-attr-fontcolor")
changeTheme(bgColor, fontColor)
})
$("#color-preset-wrapper").append(el)
})
$("#frame-toggle-check").on("click", event=> {
const fontColor = $("#current-theme-holder").attr("data-attr-fontcolor")
rectangleWrap.set("stroke", calcFrameColor(fontColor))
canvas.renderAll()
})
$("#current-color-change-button").on("click", event=> {
const fontColor = $("#current-color-fontColor").val()
const bgColor = $("#current-color-bgColor").val()
changeTheme(bgColor, fontColor)
})
$("#download-image").on("click", ()=> {
$("#canvas").get(0).toBlob(function(blob){
saveAs(blob, "monogatari-like-cut.png");
})
})
canvas.add(bg)
canvas.add(rectangleWrap)
canvas.add(mainText)
canvas.add(subText)
</script>
</body>
</html>
ソースざっくり説明
- Webフォントでそれっぽいフォントを使うことにしているよ
- 生Canvasではなくて、fabric.jsを使ってるよ
- ダウンロード処理にはFileSaver.jsとcanvas-toBlob.jsを使ってるよ
後は特記事項無しですね...