タイトルが上手くまとめられなかったのですが…そのままの内容です!
写真の上に被っているテキストだけ色が変わっているデザインのコーディングを
依頼されたことがあって(最終的には別のデザインになりましたが)、
もしアニメーション付けるならどうコーディングするかな?と考えた結果のサンプルです。
mix-blend-mode を併用することで、アニメーションによるテキストの色の変化がより印象的に。
目次
完成形デモ
ベースの構成
作りはこんな感じ。
[HTML]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <div class="visual"> <div class="mask normal"> <p class="txt"> <span class="line">This world is but a</span> <span class="line"><span class="large">CANVAS</span> to our</span> <span class="line"><span class="large">IMAGINATIONS</span>.</span> </p> </div> <div class="mask burn"> <p class="txt"> <span class="line">This world is but a</span> <span class="line"><span class="large">CANVAS</span> to our</span> <span class="line"><span class="large">IMAGINATIONS</span>.</span> </p> </div> </div><!-- /visual --> |
[CSS]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | .visual { background: url({path}/visual.jpg) no-repeat right top; margin: auto; position: relative; width: 862px; height: 460px; } .visual .mask { position: absolute; top: 0; bottom: 0; left: 0; right: 0; } .visual .txt { font-size: 0; line-height: 1; position: absolute; top: 85px; left: 40px; } .visual .line { display: block; font-family: "Josefin Sans"; /* google fonts を使用しています */ font-size: 80px; font-weight: bold; } .visual .line + .line { margin-top: 15px; } .visual .letter { display: inline-block; padding-top: 5px; } .visual .large { font-size: 100px; } |
[css/clip-path] 写真に被っているテキストの色を変える
まず、全く同じテキスト要素を2つ作って position: absolute で同じ位置に重ねて配置しておきます。
次に、背景写真の大きさに合わせて css で clip-path を設定します。
表示させたいエリアを囲むように座標を取得して、clip-path に順番に指定していきます。
それぞれ color も指定しましょう。
[CSS]
1 2 3 4 5 6 7 8 9 10 11 | .visual .mask.normal { color: #00cce1; -webkit-clip-path: polygon(0 0, 262px 0, 262px 460px, 0 460px); clip-path: polygon(0 0, 262px 0, 262px 460px, 0 460px); } .visual .mask.burn { color: #004156; -webkit-clip-path: polygon(262px 0, 862px 0, 862px 460px, 262px 460px); clip-path: polygon(262px 0, 862px 0, 862px 460px, 262px 460px); } |
[css/mix-blend-mode] 写真に被っているテキストの色を「焼きこみカラー」に
今回は .mask.burn を焼きこみカラーにしたいので、css の mix-blend-mode を利用して以下のように指定します。
[CSS]
1 2 3 | .mask.burn { mix-blend-mode: color-burn; } |
他にも乗算(multiply)、覆い焼きカラー(color-dodge)、スクリーン(screen)、オーバーレイ(overlay)など、Photoshop でおなじみのブレンドモードを指定できます。
全種類はこちら:mix-blend-mode-CSSリファレンス
[css/animation] [jQuery] テキストを1文字ずつスライドインで表示
1)別々に動かすために、まずテキストを1文字ずつ span で分割
直接HTMLをいじって分けることもできますがスマートではないので、js で処理。
このとき、今回のサンプルの英文のように単語の間に空白が入っていると消えてしまうので、文字コード
を入れましょう。
[JS]
1 2 3 4 5 6 | $('.visual .line').children().addBack().contents().each(function(){ if (this.nodeType == 3) { var $this = $(this); $this.replaceWith($this.text().replace(/(\S)/g, '<span class="letter">$&</span>')); } }); |
参考サイト:1文字ずつ文字色を変える、文字単位でのCSS適用方法
2)文字が順番に表示されるように animation の開始時間をずらす
こちらもひたすら css に nth-child で指定していくこともできますがスマートではないので、js で処理。
[JS]
1 2 3 4 5 6 | $('.visual .letter').each(function () { var letters = $(this).closest('.txt').find('.letter'); var index = $(letters).index(this); var time = index * 0.03; // ずらす間隔 $(this).css('animation-delay', time + 's'); }); |
3)上記の処理完了後にアニメーション開始させたいので、以下のように記述。
[JS]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | $(function(){ /* separate text */ $('.visual .line').children().addBack().contents().each(function(){ if (this.nodeType == 3) { var $this = $(this); $this.replaceWith($this.text().replace(/(\S)/g, '<span class="letter">$&</span>')); } }); /* animation delay */ $('.visual .letter').each(function () { var letters = $(this).closest('.txt').find('.letter'); var index = $(letters).index(this); var time = index * 0.03; $(this).css('animation-delay', time + 's'); }); }); $(window).on('load', function(){ $('.visual').addClass('is-visible'); }); |
4)最後に文字が出てくるアニメーションを css で設定
[CSS]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | /* 初期は非表示 */ .visual .line, .visual .letter { opacity: 0; } /* is-visible になったらアニメーション開始 */ .visual.is-visible .line { opacity: 1; } .visual.is-visible .letter { animation: slideIn .8s cubic-bezier(0,1.2,.13,1.5) forwards; } /* 文字が左から出てくるアニメーション(お好みの動きでどうぞ) */ @keyframes slideIn { 0% { opacity: 0; transform: translate3d(-100px,0,0); } 100% { opacity: 1; transform: translate3d(0,0,0); } } |
非対応ブラウザ用の調整
今回ご紹介しているような表現を取り入れたくても、対応ブラウザが気になって躊躇している方も多いと思います。
でも全体のクオリティをIEとかに合わせて下げなきゃいけないなんてもったいない…。
ということで「対応ブラウザではよりリッチな演出が楽しめる」という見方でデザインの幅を広げちゃいましょう。
もちろん非対応ブラウザでもデザインに致命的な欠陥が出ないということが前提ですが。
さて、今回使用している clip-path と mix-blend-mode はどちらもIE・Edge非対応です。
そのままでもデザイン的に見苦しくはないので許容としてもよさそうですが、少しイメージを近づけられるよう透過で調整しておきます。
1)js でユーザーエージェントを判定
userAgentでブラウザ&デバイス判別
こちらのコードを利用させて頂きました。
スクリプトファイルを読み込めばユーザーエージェントを判定して html にクラスを追加してくれます。
2)css で微調整
[CSS]
1 2 3 4 5 6 7 8 9 10 11 | /* IE・Edge用調整 */ .ie .visual .mask.normal, .edge .visual .mask.normal { color: #004480; opacity: 0.7; } .ie .visual .mask.burn, .edge .visual .mask.burn { display: none; } |
完成形デモ
これにて完成!
デモページ
サンプルソース一式はこちら
サンプルソース一式