はじめに
以下で紹介するプラグインと同様の動作を実現します。
Cocoonの標準通知とは別に、独自の通知エリアに、複数のメッセージを切り替えながら、1文字ずつ消えていくアニメーションで表示します。
この記事では、この方法について説明します。
完成イメージ
本ページに完成イメージを反映させます。
実装手順
以下の手順で実装します。
// テンプレート(通知エリア)の直後に追加
add_action('cocoon_part_after__tmp/notice', function () {
$pacman_url = 'パックマン画像URL';
$ghost_url = 'お化け画像URL';
?>
<div class="pacman-marquee">
<div class="pacman-marquee__message">
<img src="<?= esc_url($ghost_url); ?>" class="pacman-marquee__ghost" alt="ghost" />
</div>
<img src="<?= esc_url($pacman_url); ?>" alt="pacman" class="pacman-marquee__pacman" />
</div>
<?php
});
// フロント用JS・CSSを追加
add_action('wp_enqueue_scripts', function () {
ob_start();
?>
.pacman-marquee {
align-items: center;
background-color: #333;
display: flex;
height: 40px;
overflow: hidden;
position: relative;
}
.pacman-marquee__message {
align-items: center;
color: #fff;
display: flex;
font-size: 14px;
position: absolute;
white-space: nowrap;
}
.pacman-marquee__ghost {
margin-right: 5px;
}
.pacman-marquee__pacman {
position: absolute;
}
.pacman-marquee__char.eaten {
opacity: 0;
}
<?php
$handle = 'pacman-marquee';
wp_register_style($handle, false);
wp_enqueue_style($handle);
wp_add_inline_style($handle, ob_get_clean());
ob_start();
?>
jQuery(function ($) {
// 表示するメッセージ配列
const messages = [
"メッセージ1",
"メッセージ2",
"メッセージ3",
];
// パックマンが文字を食べるスピード(ミリ秒)
const EAT_INTERVAL = 250;
// DOM要素取得
const $textEl = $(".pacman-marquee__message");
const $pacman = $(".pacman-marquee__pacman");
const $container = $(".pacman-marquee");
// 現在表示中のメッセージインデックス
let currentIndex = 0;
/**
* パックマンのCSSスタイルを一括で適用
*
* @param {Object} styles 適用するCSSプロパティと値のオブジェクト
* @returns {void}
*/
function setPacmanStyle(styles) {
$pacman.css(styles);
}
/**
* パックマンの位置と表示状態をコンテナの右外側にリセットする
*
* @returns {void}
*/
function resetPacman() {
setPacmanStyle({
transition: 'none',
opacity: '1',
left: $container.width() + 50 + "px",
display: 'none'
});
}
/**
* 指定されたインデックスのメッセージを初期化しスライド表示
*
* @param {number} index 表示するメッセージのインデックス
* @returns {void}
*/
function showMessage(index) {
// 文字列を1文字ずつに分解してspan要素に変換
const spans = [...messages[index]].map(c => '<span class="pacman-marquee__char">' + c + '</span>').join('');
// 既存の文字要素のみ削除(お化け画像などはそのまま)
$textEl.find('.pacman-marquee__char').remove();
// 新しい文字列を追加
$textEl.append(spans);
// メッセージ文字列を画面右外から初期配置
$textEl.css({ transition: 'none', left: '100%' });
// パックマン位置もリセット
resetPacman();
// 少し遅らせて左端までスライド
setTimeout(() => {
$textEl.css({ transition: 'left 6s linear', left: '0%' });
}, 50);
}
/**
* メッセージのスライド完了後にパックマンを登場させ、文字を右から順に食べるアニメーションを開始
*
* @returns {void}
*/
function startAnimation() {
const $charSpans = $textEl.find('.pacman-marquee__char');
const containerLeft = $container[0].getBoundingClientRect().left;
// 最後の文字の右端座標を取得
const lastCharRight = $charSpans.last()[0].getBoundingClientRect().right;
const targetLeft = lastCharRight - containerLeft + 15;
// パックマンを右外から表示(位置リセット)
setPacmanStyle({
display: 'block',
transition: 'none',
left: $container.width() + 50 + "px",
opacity: '1'
});
// 少し遅れて最後の文字の右へ移動
setTimeout(() => {
setPacmanStyle({ transition: 'left 0.5s linear', left: targetLeft + "px" });
// 移動後、文字を1つずつ食べる処理を開始
$pacman.off('transitionend').on('transitionend', function (e) {
if (e.originalEvent.propertyName !== 'left') return;
$pacman.off('transitionend');
// 文字を逆順で処理(右→左に食べるため)
const reversedChars = $($charSpans.get().reverse());
let i = 0;
/**
* 次の文字の位置へ移動し、文字を透過処理しながら順に食していく再帰関数
*
* @returns {void}
*/
function eatNext() {
if (i >= reversedChars.length) {
// 全部食べ終えたら次のメッセージへ
resetPacman();
currentIndex = (currentIndex + 1) % messages.length;
showMessage(currentIndex);
return;
}
// 次の文字の位置を取得(左からの距離)
const $char = reversedChars.eq(i);
const left = $char[0].getBoundingClientRect().left - containerLeft;
// パックマンをその位置へ移動
setPacmanStyle({
transition: 'left ' + EAT_INTERVAL + 'ms linear',
left: left + "px"
});
// 文字を食べた演出(透明にする)
$char.addClass('eaten');
i++;
setTimeout(eatNext, EAT_INTERVAL);
}
eatNext();
});
}, 300);
}
// 最初のメッセージ表示
showMessage(currentIndex);
// テキストスライドが完了したらパックマン登場アニメーションを開始
$textEl.on('transitionend', e => {
if (e.originalEvent.propertyName === 'left') {
startAnimation();
}
});
});
<?php
wp_add_inline_script('jquery', ob_get_clean());
});
さいごに
今回紹介した方法を使えば、簡単に独自の通知メッセージをアニメーション付きで表示することができます。
視覚的な楽しさを加えることで、ユーザーの注目を集める効果も期待できます。
お知らせや重要な案内など、目立たせたい情報があるときにぜひ活用してみてください。


