アフィリエイト広告を利用しております。
参考サイトの記載がある場合はそちらの方がより詳しく記載説明がされているのでぜひそちらもご覧ください。
そのままコピペしても反映されないものもあります。サイトごとに変えないといけない箇所がありますので修正してください。

CSS HTML JavaScript

自動に削れるスクラッチ風文字が浮かび上がってくるデザイン

スクラッチ風に擦ると文字が浮かび上がってくるデザインの改良版です。
本コードでは要素が見えたら自動的にスクラッチが削れて見えるようにしております。

文字が見える!
document.addEventListener('DOMContentLoaded', () => {
  // 初期設定
  const canvas = document.getElementById("mask");
  const ctx = canvas.getContext("2d");
  const container = document.getElementById("container");

  // キャンバスのサイズをコンテナに合わせる
  canvas.width = container.offsetWidth;
  canvas.height = container.offsetHeight;

  // キャンバスを黒で塗りつぶし
  ctx.fillStyle = "#959595";
  ctx.fillRect(0, 0, canvas.width, canvas.height);

  // 削る範囲(1回のスクラッチ幅)
  const size = 35;  // 円形で削るため小さめに

  // 初期位置設定(画面左端からスタート)
  let x = 0;  // 左端から開始
  let y = canvas.height / 2;  // 画面中央からスタート
  let dx = 1.5;  // 横方向の移動速度
  let dy = -1.5;  // 縦方向の移動速度

  // 中央付近を削る範囲を設定
  const centralRange = 10; // 上下10pxの範囲で動かす

  // スムーズに動かすための変数
  let speed = 10;  // 動きの速さ(速すぎず遅すぎず)

  // 方向変更のフラグ
  let movingUp = true;

  // アニメーションの実行フラグ
  let isAnimating = false;

  // 自動スクラッチ削りの処理
  function animate() {
    // 背景を削る(透明化)
    ctx.globalCompositeOperation = "destination-out";
    ctx.beginPath();
    ctx.arc(x, y, size, 0, Math.PI * 2, false);  // 円形で削る
    ctx.fill();

    // 右に進みながら斜め上/下に動く
    x += dx;
    y += dy;

    // 上下の範囲を制限する
    let offset = Math.random() * 10;
    if (y <= canvas.height / 2 - centralRange) {
      y = canvas.height / 2 - centralRange - offset;  // 上限に達したら中央付近で止める
      movingUp = false;  // 下方向に切り替える
    } else if (y >= canvas.height / 2 + centralRange) {
      y = canvas.height / 2 + centralRange + offset;  // 下限に達したら中央付近で止める
      movingUp = true;  // 上方向に切り替える
    }

    // movingUp フラグに基づいて dy を決定
    if (movingUp) {
      dy = -1.5;  // 上方向
    } else {
      dy = 1.5;  // 下方向
    }

    // アニメーションを再帰的に呼び出す
    if (isAnimating) {
      setTimeout(animate, speed);  // 指定した速度で動く
    }
  }

  // IntersectionObserverの設定
  const observer = new IntersectionObserver(entries => {
    entries.forEach(entry => {
      if (entry.isIntersecting) {
        // キャンバスが表示されたらアニメーション開始
        isAnimating = true;
        animate();  // アニメーション開始
        observer.disconnect();  // 監視停止
      }
    });
  }, { threshold: 0.5 }); // 要素が50%表示されたら

  // キャンバスがビューポートに表示されたらアニメーションを開始
  observer.observe(canvas);
});
<div id="container">
  <div style="z-index: 1; position: relative;">文字が見える!</div>
  <canvas id="mask"></canvas>
</div>
#container {
	position: relative;
	width: 50%;
	height: 200px;
	font-size: 4.0rem;
	font-weight: 900;
	text-align: center;
	color: #000000;
	background: #FFFFFF;
	overflow: hidden;
	user-select: none;
	
	display: flex;
	justify-content: center;
	align-items: center;
    margin: 0 auto;
}

#mask {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	z-index: 2;
}

おすすめ記事

1
制作理由 ワードプレスのクラシックエディタを直接使っているといつも思うことがありました [Tab]キー押して空白入れて見やすくインデントしたい! この記事を書くまでは入れないか、スペースキーを押して誤 ...
2
制作理由 ワードプレスのクラシックエディタを直接使っているといつも思うことがありました コード追加ボタンを自由に追加出来たら便利じゃない? この記事を書くまでは、クリップボード貼り付けアプリ[Clib ...
3
アプリ制作するに至った理由 納品代行の仕事をしていて思ったことがあります 納品代行をしていると本当に様々なお客様から様々な商品が届きます その中でも特に注意しているのが、「見た目ほぼ同じだけど違う商品 ...

-CSS, HTML, JavaScript
-