【てがろぐ】画像を個数や画面サイズに応じてリサイズするようにしました
私のサイトのてがろぐはスクショ置き場として使っているのですが、気兼ねなくアップロードできる!とガンガン投稿していると、複数枚画像を添付した時の表示が気になってきました。
画像サイズにはmax-widthやmax-heightを指定していましたが、それでもたくさん並ぶと次の投稿が下の方に流れてしまうんですよね。
たくさんの画像を一つ一つ見たい時はタップ・拡大して見るので、一覧の時はかなり小さい表示になってても良いかなーと思い、画像をリサイズするようにしてみました。
CSSだけで実装するのは難しそうだったので、JavaScriptを使って画像サイズを制御する形にしています。
※コードはChatGPTを使用して作成しました。
仕様
画像の大きさについてですが、スマホ画面とパソコン画面で設定を変更しています。
具体的には、『画面のサイズが小さくなった(画像を囲んでいる要素の幅が小さくなった)ら、専用の画像サイズにリサイズする』という条件です。
スマホによって画面のサイズは違うので、どのスマホでも同じような見た目になるようには中々できません。スマホ側のフォントの表示サイズの設定でもレイアウトは変わってくると思います。
というわけで思い切って私のメインスマホ・フォントの表示に合わせる形で実装しました。一番使うのは私だと思うのでw
更に、『要素内に何個画像があるか』で分岐しています。1〜3個まではそのまま、4・5・6以上の場合は専用のサイズになるように設定しました。
ちなみに、正方形にリサイズするようにも指定しています。スマホゲームのスクショだと横長だったり縦長だったりして、普通に縮小すると見にくくなってしまうので。
コード
function resizeImages() {
const containers = document.querySelectorAll('.onelog_commentbox');
containers.forEach(container => {
const images = container.querySelectorAll('.embeddedimage');
const containerWidth = container.getBoundingClientRect().width;
const imageCount = images.length;
let maxSize;
let maxHeight;
// onelog_commentboxの幅が400px以下の場合に画像サイズを決定
if (containerWidth <= 400) {
if (imageCount === 4) {
maxSize = '85px'; // embeddedimageのmax-width
maxHeight = '85px'; // imagelinkのheight
} else if (imageCount === 5) {
maxSize = '70px';
maxHeight = '70px';
} else if (imageCount >= 6) {
maxSize = '55px';
maxHeight = '55px';
}
}
// onelog_commentboxの幅が400pxより大きい場合に画像サイズを決定
else {
if (imageCount === 4) {
maxSize = '225px';
maxHeight = ''; // imagelinkのheightを変更しない
} else if (imageCount === 5) {
maxSize = '180px';
maxHeight = '180px';
} else if (imageCount >= 6) {
maxSize = '150px';
maxHeight = '150px';
} else {
maxSize = '';
maxHeight = '';
}
}
// 画像の最大幅とimagelinkの高さを設定
images.forEach(img => {
const parentLink = img.closest('.imagelink');
img.style.maxWidth = maxSize; // 最大幅を設定
if (parentLink) {
parentLink.style.height = maxHeight; // imagelinkのheightを設定
}
});
});
}
// 初回ロード時とコンテナサイズ変更時に実行
window.addEventListener('load', resizeImages);
window.addEventListener('resize', resizeImages);
document.addEventListener('DOMContentLoaded', resizeImages);
HTMLの構造が、
<div class="onelog_commentbox">
<a class="imagelink" href="画像のアドレス"">
<img class="embeddedimage" src="画像のアドレス">
</a>
</div>
という形になっているので、スクリプト内でonelog_commentboxとembeddedimageを指定しています。
画像の高さはaタグのimagelinkで制御しているので、最大幅とは別に処理を行っています。その分処理が複雑になっていますね…
ちなみに、CSSはこのような形です。
.imagelink {
display: inline-block;
height: 200px;
}
.embeddedimage {
width: 100%;
max-width: 300px;
height: 100%;
object-fit: cover; /* 画像を親要素のサイズに合わせて拡大縮小(縦横比は維持) */
}
@media (max-width: 450px) {
.imagelink {
height: 100px;
}
.embeddedimage {
width: 100px;
}
}
CSSでも正方形になるように指定しているので、スマホ画面の場合、1枚のみの投稿でも最大で100px×100pxのサイズになります。それ以外の場合は最大で300px×200pxになるようにしています。(2024/9/23現在)
※CSS等画像サイズについては随時修正しているので、最新の状態とは異なる場合があります。
最後に
実際どの様になっているかは、てがろぐのページでご確認ください。パソコンからだとF12の開発者ツールを使えば画面サイズを調整できるので、どの様になっているか確認しやすいと思います。
最近はずっとてがろぐを弄り続けていましたが、そろそろ・今のところ満足する形にできたので、今度はゲームをプレイしてスクショをたくさん撮っていこうと思います✨
以下余談です。余談のほうが長いかも…?w
余談
てがろぐの管理画面から画像一覧を見ていると、画像にエラーが発生しているものがあることがわかりました。
今までもエラーに気付いてはいたのですが、特に問題になっていなかったのでスルーしていました。が、このエラーが発生していると、画像サイズが自動取得できずにHTMLに付与されなくなってしまうんですよね。
それによってスクリプトの実行結果が微妙に変わってしまっていたので、エラーが出ている画像を一覧化→pngからjpgに変換→該当の投稿文も修正…という作業をしました。
(今回のエラーはjpgファイルがpngファイルとして保存されていたのが原因でした)
2000個ほどあった画像のうち、750個ほどエラーがあったので、一つ一つ書き出すのは時間がかかると判断し、スプレッドシート・コマンドプロンプト・phpを駆使して一括で変更しました。
具体的な作業内容は、
- てがろぐの画像管理画面のソースコードから「画像にエラーがあります」と書いてある行をコピーしスプレッドシートに貼りつけ
- スプレッドシートの関数を使って、ソースコードから画像ファイル名部分を抜き出す
- テキストファイルに画像ファイル名を貼り付けて一覧化(filelist.txt)
- cmdを使って、filelist.txtに記載されている該当ファイルを専用のフォルダに移動させる
- ファイルの変換ソフトでpng→jpgに変換
- tegalog.xml内の記述のうち、filelist.txtに記載されているファイル名のpng部分をjpgに修正するphpを実行
細かい説明を省いたので、「なんでそんなことをしてるの?」と思われるかもしれませんが、まぁ備忘録なのでご了承ください😅
この作業でもChatGPTに大活躍してもらい、関数からコードから全て作ってもらいました。一応、その時のコードを置いておこうと思います。
関数・コード
スプレッドシートで使った関数
=IF(ISNUMBER(SEARCH("画像にエラーがあります", B2)), REGEXEXTRACT(B2, "\[PICT:([^]]+)\]"), "")
=ARRAYFORMULA(SUM(N(LEN(C2:C1000) > 0)))
コマンドプロンプトで使ったコード
for /f "tokens=*" %i in (C:\Desktop\filelist.txt) do move "C:\Desktop\tegalog\images\%i" "C:\Desktop\移動先\"
phpのコード
<?php
// ファイルリストを読み込む
$fileListPath = 'C:\Desktop\filelist.txt'; // 実際のファイルリストのパス
$logFilePath = 'C:\Desktop\tegalog.xml'; // 実際のログファイルのパス
$updatedLogFilePath = 'C:\Desktop\updated_logfile.xml'; // 出力ファイルのパス
// ファイルリストを配列に読み込む
$fileList = file($fileListPath, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$fileList = array_map('trim', $fileList); // トリムして余分な空白を削除
// ログの内容を読み込む
$logs = file_get_contents($logFilePath);
// PNGをJPGに置換
$updatedLogs = preg_replace_callback(
'/\[PICT:(.*?)\.png\]/',
function ($matches) use ($fileList) {
$filename = $matches[1] . '.png';
if (in_array($filename, $fileList)) {
return '[PICT:' . $matches[1] . '.jpg]';
}
return $matches[0]; // 変換しない場合はそのまま返す
},
$logs
);
// 更新されたログを新しいファイルに書き込む
file_put_contents($updatedLogFilePath, $updatedLogs);
echo "指定されたPNGの拡張子変更が完了しました。\n";
余談2
他にもサムネイル画像を作成する手順を半自動化しています。
phpファイルとデータベースを使って実装しているのですが…ここまで来ると完全にChatGPT頼りで、仕組みを殆ど理解できていません😥
一応↑な感じで動いています。データベース周りはもうちょっと勉強しないとなぁ〜