曇りガラスに文字を書くSVGアニメーション

SVGフィルターとマスクを使った、曇りガラスに指で文字を書いたような印象的なヒーローセクション

<html style="max-height: 100%;"><head><script id="js-section"> </script><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><style id="basic-style"></style><style id="root-style">:root{--pic-image-data:none;}</style><style id="out-style">body, html { margin: 0; padding: 0; height: 100%; overflow: hidden; background: #0b0f16; } svg { width: 100vw; height: 100vh; display: block; } /* フォント設定 */ .subtitle { font-family: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif; font-size: 24px; letter-spacing: 0.24em; text-transform: uppercase; font-weight: 600; fill: rgba(255, 255, 255, 1); filter: drop-shadow(0 2px 6px rgba(0, 0, 0, 0.2)); } /* アニメーション */ .letter { stroke-dasharray: 100; stroke-dashoffset: 100; opacity: 0; } .letter:nth-of-type(1) { animation: drawLetter 0.8s ease-out forwards; animation-delay: 1.5s; } .letter:nth-of-type(2) { animation: drawLetter 0.6s ease-out forwards; animation-delay: 2.3s; } .letter:nth-of-type(3) { animation: drawLetter 0.6s ease-out forwards; animation-delay: 2.9s; } .letter:nth-of-type(4) { animation: drawLetter 0.3s ease-out forwards; animation-delay: 3.5s; } .letter:nth-of-type(5) { animation: drawLetter 0.5s ease-out forwards; animation-delay: 3.8s; } .letter:nth-of-type(6) { animation: drawLetter 0.6s ease-out forwards; animation-delay: 4.3s; } .letter:nth-of-type(7) { animation: drawLetter 0.4s ease-out forwards; animation-delay: 4.9s; } .letter:nth-of-type(8) { animation: drawLetter 0.5s ease-out forwards; animation-delay: 5.3s; } .letter:nth-of-type(9) { animation: drawLetter 0.5s ease-out forwards; animation-delay: 5.8s; } .letter:nth-of-type(10) { animation: drawLetter 0.5s ease-out forwards; animation-delay: 6.3s; } .letter:nth-of-type(11) { animation: drawLetter 0.4s ease-out forwards; animation-delay: 6.8s; } .letter:nth-of-type(12) { animation: drawLetter 0.4s ease-out forwards; animation-delay: 7.2s; } .letter:nth-of-type(13) { animation: drawLetter 0.4s ease-out forwards; animation-delay: 7.6s; } @keyframes drawLetter { from { opacity: 0; } to { stroke-dashoffset: 0; opacity: 1; } } .fade-in { opacity: 0; animation: fadeIn 0.5s ease-out forwards; animation-delay: 2s; } @keyframes fadeIn { to { opacity: 1; } } </style><style id="pic-style">html { max-height: 100%; }</style></head><body id="svg-section" style="width: 900px; height: 507px; transform-origin: left top; transform: scale(1); overflow: auto; margin: 0; padding: 0;"><svg viewBox="0 0 1920 1080" preserveAspectRatio="xMidYMid slice"> <defs> <!-- 曇りガラスフィルター --> <filter id="fogFilter"> <feGaussianBlur in="SourceGraphic" stdDeviation="12" result="blur"></feGaussianBlur> <feComponentTransfer> <feFuncR type="linear" slope="1.25"></feFuncR> <feFuncG type="linear" slope="1.25"></feFuncG> <feFuncB type="linear" slope="1.25"></feFuncB> </feComponentTransfer> </filter> <!-- ガラスの影 --> <filter id="glassShadow"> <feDropShadow dx="0" dy="28" stdDeviation="35" flood-color="rgba(0,0,0,0.18)"></feDropShadow> </filter> <!-- 文字ハイライト用フィルター --> <filter id="brightFilter"> <feColorMatrix type="saturate" values="1.2"></feColorMatrix> <feComponentTransfer> <feFuncR type="linear" slope="0.7"></feFuncR> <feFuncG type="linear" slope="0.7"></feFuncG> <feFuncB type="linear" slope="0.7"></feFuncB> </feComponentTransfer> </filter> <!-- 文字パス定義 --> <g id="textPaths" transform="translate(50, 0)"> <path class="letter" d="M 120 190 Q 60 190 60 225 Q 60 260 120 260 Q 155 260 165 250" pathLength="100"></path> <path class="letter" d="M 210 190 L 210 260 L 275 260" pathLength="100"></path> <path class="letter" d="M 305 260 L 360 190 L 415 260" pathLength="100"></path> <path class="letter" d="M 325 235 L 395 235" pathLength="100"></path> <path class="letter" d="M 445 260 L 445 190" pathLength="100"></path> <path class="letter" d="M 445 190 Q 445 190 490 190 Q 525 190 525 212 Q 525 234 490 234 L 445 234" pathLength="100"></path> <path class="letter" d="M 485 234 L 525 260" pathLength="100"></path> <path class="letter" d="M 575 190 L 575 260" pathLength="100"></path> <path class="letter" d="M 610 190 L 695 190" pathLength="100"></path> <path class="letter" d="M 652 190 L 652 260" pathLength="100"></path> <path class="letter" d="M 730 190 L 775 220" pathLength="100"></path> <path class="letter" d="M 820 190 L 775 220" pathLength="100"></path> <path class="letter" d="M 775 220 L 775 260" pathLength="100"></path> </g> <!-- マスク定義 --> <mask id="glassMask"> <rect width="100%" height="100%" fill="black"></rect> <g transform="translate(470, 280)"> <rect x="0" y="0" width="980" height="520" rx="28" fill="white"></rect> <g stroke="black" stroke-width="32" fill="none" stroke-linecap="round" stroke-linejoin="round"> <use href="#textPaths"></use> </g> </g> </mask> <!-- 文字ハイライト用マスク --> <mask id="textHighlightMask"> <rect width="100%" height="100%" fill="black"></rect> <g transform="translate(470, 280)"> <g stroke="white" stroke-width="32" fill="none" stroke-linecap="round" stroke-linejoin="round"> <use href="#textPaths"></use> </g> </g> </mask> </defs> <!-- 1. クリアな背景画像 --> <image href="https://ai-education.pa-tu.work/img/ice-6538605_1920.jpg" width="100%" height="100%" preserveAspectRatio="xMidYMid slice"></image> <!-- 2. 曇りガラス層 --> <g transform="translate(470, 280)" filter="url(#glassShadow)"> <rect width="980" height="520" rx="28" fill="rgba(0,0,0,0.01)"></rect> </g> <image href="https://ai-education.pa-tu.work/img/ice-6538605_1920.jpg" width="100%" height="100%" preserveAspectRatio="xMidYMid slice" filter="url(#fogFilter)" mask="url(#glassMask)"></image> <!-- 文字部分のハイライト --> <image href="https://ai-education.pa-tu.work/img/ice-6538605_1920.jpg" width="100%" height="100%" preserveAspectRatio="xMidYMid slice" filter="url(#brightFilter)" mask="url(#textHighlightMask)"></image> <!-- 3. ガラスの質感オーバーレイ --> <g transform="translate(470, 280)" pointer-events="none"> <rect width="980" height="520" rx="28" fill="none" stroke="rgba(255,255,255,0.28)" stroke-width="1"></rect> <rect width="980" height="520" rx="28" fill="rgba(255,255,255,0.05)"></rect> <!-- サブタイトル --> <text class="subtitle" x="490" y="355" text-anchor="middle"> <tspan x="490" dy="0">Through the glass, beauty transcends</tspan> <tspan x="490" dy="34">Where light and clarity become one</tspan> </text> </g> </svg> <script id="js-section"> </script></body></html>