【動的に貼り付く】スクロール時にCSS Shapesを使ってテキストをアニメーション表示させてみる

JavaScript ( jQuery )

こんにちは。
今回は画像にclip-pathを用いて形状を指定することにより、外形の凹凸に合わせたテキストの流れ込みをアニメーションで表示させたエフェクトを紹介します。
テキストの要素をShapesプロパティにより、凹凸の形に変形しながら移動・回り込みするさまが楽しいです。

CodePenではLoadingページをjQuery、その他はJavaScriptに書き換えて記述しています。

Shape(シェイプ)ってなに?

CSS Shapeとは、テキストなどのコンテンツ要素を色々な複雑な形状の領域に流しこんだり、回り込ませることができる使用の事です。(Shapeには3種類のプロパティがあります)

・shape-outside
フロート要素への回り込みの形状を指定する際に使用します。 一般的には、テキストを円、楕円、多角形のような図形の外側に回り込ませるなどのスタイルが用いられます。(※ float:left; 又は float:right; 必須)
https://developer.mozilla.org/en-US/docs/Web/CSS/shape-outsid

・shape-margin 
shape-outsideプロパティで指定するフロート要素への回り込みの形状に、マージンを指定する際に使用します。
https://developer.mozilla.org/en-US/docs/Web/CSS/shape-margin

・shape-image-threshold 
一部が透過されたPNGやGIFなどの画像ファイルから図形を抽出する場合、 その画像ファイルの各ピクセルがどの程度の不透明度なら図形部分として解釈するかをします。
不透明度が50%以上のすべてのピクセルが図形部分として解釈されます。
https://developer.mozilla.org/en-US/docs/Web/CSS/shape-image-threshold

たとえば、円、三角形、多角形、その他の形状でも、このプロパティを使って要素の外側にそってテキストを配置させれば、雑誌のようなレイアウトをWeb上でも表示させることができます。
過去のブログでも紹介していますので、ご覧ください。
blog ~「Polygonを使って文書のレイアウトをしませんか」

短編ですが、こんなWebページを作ってみました

DEMO http://ben1099url.starfree.jp/0070.html (完全にはresponsiv対応させてはいません)

このページはまだCSS Shapes を使っていません。
スクロール時に両サイドから画像とテキストが流れて来るだけですが、各テキストの要素がhoverされると、毎回ちがったカラーで表示されます。
また、「2段目、3段目」のテキストだけはhoverされる毎に内容がフェードインしながら異なった文になるようになっています。

テキストのカラーがランダムに変化するのは、JavaScript で乱数を発生させて、乱数値からcase により色を決めています。それを1~3段のテキストに対応させるので、1つの関数にさせました。
テキストの各要素にhoverさせると、関数がその都度呼び出されてランダムに色を変化させます。
また、ホバーさせた時点でフェードインする図形は、テキスト要素からbefore / after で発火させているだけです。


HTML

  • <div class="section2" id="section2"><br>
  •   <h1> <span class="jamp">SECTION TITLE 1</span></h1>
  •   <p class="note1" id="doc1">
  •     Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
  •   </p>
  •     <p class="note2" id="doc2">
  •       Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
  •     </p>
  •     <p class="note3" id="doc3">
  •       Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
  •     </p>
  •     
  •     <img class="note3-image2" src="image0070/2dky.gif"><!--woman-5545759_1280.jpg-->
  •     <img class="note3-image" src="image0070/1KCB.gif"><!-- woman-5545759_1280.jpg-->
  • </div>

CSS

  • .section2{
  •   width:100%;
  •   height:100vh;
  •   position: relative;
  •   overflow: hidden;
  •   background:#020409; /*#020409,#04070e,#05080f*/
  • }
  • .section2::before{
  •   width:800px;
  •   height:800px;
  •   content:'';
  •   position: absolute;
  •   top:-300px;
  •   left:-450px;
  •   border-radius: 50%;
  •   background:#7a00fc;
  •   opacity:0.6;
  •   z-index:2;
  • }
  • .section2 .note1{
  •   position: absolute;
  •   margin-top:20px;
  •   margin-right:150px; /*20px;*/
  •   top:60px;
  •   right:0;
  •   z-index:2;
  •   width:80%;
  •   font-size:1em;
  •   color:#fff;
  • }
  • .section2 .note2{
  •   position: absolute;
  •   margin-top:20px;
  •   margin-left:150px;
  •   top:200px;
  •   left:0;
  •   z-index:2;
  •   width:80%;
  •   font-size:1em;
  •   color:#fff;
  • }
  • .section2 .note3{
  •   position: absolute;
  •   padding:20px;
  •   top:370px;
  •   right:0;
  •   z-index:2;
  •   width:50%;
  •   font-size:1em;
  •   color:#fff;
  • }
  • .section2 .note1:hover::before{
  •   position: absolute;
  •   right:90%;
  •   content:'\025c7';
  •   color:#fff;
  •   font-size:250px;
  •   animation:rotate-anime 3s infinite;
  • }
  • .section2 .note2:hover::before{
  •   position: absolute;
  •   right:40%;
  •   content:'\02661';
  •   color:#fff;
  •   font-size:250px;
  •   z-index:2;
  •   animation:rotate-anime 3s infinite;
  • }
  • .section2 .note3:hover::before{
  •   position: absolute;
  •   right:30%;
  •   content:'\025b3';
  •   color:#fff;
  •   font-size:250px;
  •   animation:rotate-anime 3s infinite;
  • }
  • .section2 .note3-image{ /*** Moon ****/
  •   position: absolute;
  •   top:250px; /*370px;*/
  •   right:50%; /*55%;*/
  •   z-index:1;
  • }
  • .section2 .note3-image2{
  •   position: absolute;
  •   top:50px; /*370px;*/
  •   right:0%; /*55%;*/
  •   z-index:1;
  • }
  • @keyframes rotate-anime {
  •   0%{transform:scale(0);
  •      opacity:0;
  •    }
  •  50%{ transform:scale(1);
  •      opacity:0.5;
  •    }
  •  /*100%{ transform: rotateY(360deg)}*/
  •  100%{ transform:scale(0);
  •      opacity:0;
  •    }
  • }
  • @keyframes animate-right {
  •   0%{
  •     opacity:0;
  •     right:-100%;
  •   }
  •   50%{
  •     opacity:0.1;
  •   }
  •   80%{
  •     opacity:0.5;
  •   }
  •   100%{
  •     opacity:1;
  •     right:0;
  •   }
  • }
  • @keyframes animate-right-image {
  •   0%{
  •     opacity:0;
  •     right:-100%;
  •   }
  •   50%{
  •     opacity:0.1;
  •   }
  •   80%{
  •     opacity:0.5;
  •   }
  •   100%{
  •     opacity:1;
  •     right:50%; /*55%;*/
  •   }
  • }
  • @keyframes animate-left {
  •   0%{
  •     opacity:0;
  •     left:-100%;
  •   }
  •   50%{
  •     opacity:0.1;
  •   }
  •   80%{
  •     opacity:0.5;
  •   }
  •   100%{
  •     opacity:1;
  •     left:0;
  •   }
  • }


jQuery テキストをフェードインさせながら移動

  •   $(window).scroll(function(){
  •     var i = $(this).scrollTop()
  •     let page2 = $('.section2').offset().top;
  •         if (i > page2 - 900){
  •            $(".section2 .note1").css('animation','animate-right 1s');
  •            $(".section2 .note2").css('animation','animate-left 1.5s');
  •            $(".section2 .note3").css('animation','animate-right 2s');
  •            $(".section2 .note3-image").css('animation','animate-right-image 2.5s');
  •     }
  •         }
  •   });


テキストのカラーをランダムに変化

  •         var rnd,Color_code;
  •         function module(){
  •                     for (var y=0; y<7; y++){
  •                       rnd = Math.floor(Math.random() * 9);
  •                     /* console.log(rnd);*/
  •                       switch (rnd){
  •                         case 0: Color_code = '#ea06f7';
  •                                 break;
  •                         case 1: Color_code = '#ff1';
  •                                 break;
  •                         case 2: Color_code = '#9000ff';
  •                                 break;
  •                         case 3: Color_code = '#7a00fc';
  •                                 break;
  •                         case 4: Color_code = '#06ff51';
  •                                 break;
  •                         case 5: Color_code = '#d6ff05';
  •                                 break;
  •                         case 6: Color_code = '#ffb805';
  •                                 break;
  •                         case 7: Color_code = '#05ffb3';
  •                                 break;
  •                         case 8: Color_code = '#f00';
  •                                 break;
  •                     }
  •                 }
  •         }

テキストをhoverさせたら、文字の色を変化させながら内容を変更させる

  •         $(".section2 .note2").hover(function(){ //ホバーさせた際にテキストカラーとテキスト内容を変更。opacity変化させて表示する。
  •           module();
  •           var doc2 = document.getElementById("doc2");
  •           doc2.innerHTML = "Why do we use it? <br> It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English. Many desktop publishing packages and web page editors now use Lorem Ipsum as their default model text, and a search for 'lorem ipsum' will uncover many web sites still in their infancy. Various versions have evolved over the years, sometimes by accident, sometimes on purpose (injected humour and the like).";
  •           doc2.animate([{opacity: '0'}, {opacity: '1'}], 1000);
  •           doc2.style.color = Color_code;
  •     },
  •       function(){
  •                   var doc2 = document.getElementById("doc2");
  •                   doc2.innerHTML = " Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.";
  •                  doc2.animate([{opacity: '0'}, {opacity: '1'}], 1000);
  •                  doc2.style.color = '#fff';
  •     }
  •   );

タイトル表示の文字が飛び跳ねるアニメーションは、Web site (q-Az) https://q-az.net/javascript-word-jamping/ からの記事を利用させてもらいました。

テキストはどこまで回りこませるか、画像にクリッピング領域を設定する

このページは本題のとおり、テキストがシェイプされ、クリッピングされた画像に回り込んで来るといったアニメーションになります。
画像を円状にクリッピングさせるだけならば、簡単にできますが、凹凸のある画像の周囲に合わせシェイプさせるには、clip-path:polygon の設定で複雑に座標を指定しなければなりません。そこで、Web上で公開されているジェネレータを利用します。

CSS Clip-Path Generator https://www.cssportal.com/css-clip-path-generator/ (無料)

このクリップ・パス・ジェネレータを利用して、画像の凹凸に合わせたクリッピングが行えます。
ウエイブサイトから画像をアップロードさせたら、右手にある「クリッピング・パターン」の形状を選択して下さい。好みの形がなくとも、座標の指定個数の多いサンプルパターンからポイントを崩して形状を変えていけばOKです。今回の画像は出来るだけ複雑な形状に対応できるように「座標を指定する個所の数が9つあるStar型」のパーターンを選択し、アップロードした画像に合わせて座標位置を変えていきます。


9つのポイントを動かし、最終的にえた座標は
polygon(41% 29%, 47% 7%, 100% 0, 100% 100%, 34% 98%, 40% 58%, 9% 67%, 8% 57%, 17% 45%, 34% 41%);
となりました
インジケータからの得られたパス位置をコピーし、shape-outsiteも同様の値で

clip-path : polygon(41% 29%, 47% 7%, 100% 0, 100% 100%, 34% 98%, 40% 58%, 9% 67%, 8% 57%, 17% 45%, 34% 41%);
shape-outside : polygon(41% 29%, 47% 7%, 100% 0, 100% 100%, 34% 98%, 40% 58%, 9% 67%, 8% 57%, 17% 45%, 34% 41%);
float : right ;

とCSS 内で画像の要素に記述すれば、テキストが左から回り込んだ表示になります。
しかし、このままではテキストが貼り付いた状態だけなので、@keyframesでテキストが回り込む変化の様子をアニメーションをつけながら、shape-outsideの座標を変化させていきます。

position プロパティは使えない

スクロール時に要素が可視化部へ現れるアニメーションとして、馴染みある方法としてはposistionを使った位置の移動方法があります。
表示させたい範囲の要素をpositionプロパティにて可視化外に隠しておいてから、必用な所で位置を移動させる方法がありますが、「clip-pathやshape-outside」では要素の移動はできますが、画像に回り込んだ表示にさせる事はできません。
その為、要素の移動は「transformプロパティ」にて可視化外から内へと移動させる事にしました。
このページではテキストの要素を 左➡右へ移動させるために、
transform : translateX(-200%); ➡ translateX(0) ; へとjQueryで変化・移動をさせています。

HTML

  • <div class="section4" id="section4">
  •   <div>
  •     <h1> <span class="jamp">SECTION TITLE 3</span></h1>
  •     <br>
  •       <img class="picture" src="image0070/guava-2822182_1280.png">
  •       <p class="note">
  •             There are many variations of passages of Lorem Ipsum available, but the majority have suffered alteration in some form, by injected humour, or randomised words which don't look even slightly believable. If you are going to use a passage of Lorem Ipsum, you need to be sure there isn't anything embarrassing hidden in the middle of text. All the Lorem Ipsum generators on the Internet tend to repeat predefined chunks as necessary, making this the first true generator on the Internet. It uses a dictionary of over 200 Latin words, combined with a handful of model sentence structures, to generate Lorem Ipsum which looks reasonable. The generated Lorem Ipsum is therefore always free from repetition, injected humour, or non-characteristic words etc.
  •             There are many variations of passages of Lorem Ipsum available, but the majority have suffered alteration in some form, by injected humour, or randomised words which don't look even slightly believable. If you are going to use a passage of Lorem Ipsum, you need to be sure there isn't anything embarrassing hidden in the middle of text. All the Lorem Ipsum generators on the Internet tend to repeat predefined chunks as necessary, making this the first true generator on the Internet. It uses a dictionary of over 200 Latin words, combined with a handful of model sentence structures, to generate Lorem Ipsum which looks reasonable. The generated Lorem Ipsum is therefore always free from repetition, injected humour, or non-characteristic words etc.
  •             There are many variations of passages of Lorem Ipsum available, but the majority have suffered alteration in some form, by injected humour, or randomised words which don't look even slightly believable. If you are going to use a passage of Lorem Ipsum, you need to be sure there isn't anything embarrassing hidden in the middle of text. All the Lorem Ipsum generators on the Internet tend to repeat predefined chunks as necessary, making this the first true generator on the Internet. It uses a dictionary of over 200 Latin words, combined with a handful of model sentence structures, to generate Lorem Ipsum which looks reasonable.
  •         </p>
  •   </div>
  • </div>

CSS

  • .section4{
  •   width:100%;
  •   height:100vh;
  •   overflow: hidden;
  •   background:#020409; /*#020409,#04070e,#05080f*/
  • }
  • .section4 div{
  •   width:80%;
  •   height:100vh;
  •   margin:auto;
  • }
  • .section4 .note{
  •   transform:translateX(-200%);
  •   color:orange;
  •   font-size:16px;
  •   opacity:0;
  • }
  • .section4 .picture{
  •   width:70%;
  •   height:auto;
  •   clip-path: polygon(41% 29%, 47% 7%, 100% 0, 100% 100%, 34% 98%, 40% 58%, 9% 67%, 8% 57%, 17% 45%, 34% 41%);
  •   shape-outside: polygon(41% 29%, 47% 7%, 100% 0, 100% 100%, 34% 98%, 40% 58%, 9% 67%, 8% 57%, 17% 45%, 34% 41%);
  •   float:right;
  • }
  • @keyframes polygon2{
  •   0%{
  •      shape-outside: polygon(100% 100%, 100% 100%, 100% 0, 100% 100%, 100% 100%, 100% 100%, 100% 100%, 100% 100%, 100% 100%, 100% 100%);
  •   }
  •   50%{
  •       shape-outside: polygon(100% 100%, 100% 100%, 100% 0, 100% 100%, 100% 100%, 100% 100%, 100% 100%, 100% 100%, 100% 100%, 100% 100%);
  •   }
  •   85%{
  •       shape-outside: polygon(41% 29%, 47% 7%, 100% 0, 100% 100%, 34% 98%, 40% 58%, 9% 67%, 8% 57%, 17% 45%, 34% 41%);
  •   }
  •   100%{
  •       shape-outside: polygon(41% 29%, 47% 7%, 100% 0, 100% 100%, 34% 98%, 40% 58%, 9% 67%, 8% 57%, 17% 45%, 34% 41%);
  •   }
  • }

jQuery

  •   $(window).scroll(function(){
  •     var i = $(this).scrollTop()
  •     let page4 = $('.section4').offset().top;
  •         if (i > page4 - 650){
  •            $(".section4 .picture").css('animation','polygon2 2s');
  •            $(".section4 .note").css({
  •                                       'transition':'2.5s',
  •                                       'opacity':'1',
  •                                       'transform':'translateX(0)'
  •                                     });
  •           }
  •         }
  •   });

画像を円状にさせてテキストをクリッピングさせる場合

画像が円状の場合は、polygon 座標の指定はしなくてもいいので、ジェネレータを利用しなくともできます。
画像に対してのCSSは、
clip-path: ellipse(45% 45% at 50% 50%);
shape-outside:ellipse(45% 45% at 50% 50%);
float:left;

だけで済みます。
画像が縦長の円になっていますが、これは画像の縦横サイズをそのままclip-pathをかけたためです。

サイズが対照的になっていれば、正常な円でクリッピングされます。
テキストは上記と同じようにアニメーションで変化をつけながら「右 ➡ 左」へとシェイプされながら流れ込んで来るようにさせるので、「float : left ;」とし、
tranform : translateX(200%)の位置にテキスト要素を隠し、最終の到達位置をjQueryでtranslateX(0)まで変化・移動させます。

HTML,CSS,jQueryは前項のパターンとさほど変わらないので、クリッピング、シェイプの設定値と、左右のどちらからテキストが表れるか、この違いだけです。

HTML

  • <div class="section7" id="section7">
  •   <div>
  •     <img class="picture" src="image0070/judeus-samson-y2ny77b5sU0-unsplash.jpg"><!--judeus-samson-y2ny77b5sU0-unsplash.jpg,imat-bagja-gumilar-4fT8iYzNtMg-unsplash.jpg-->
  •     <h1 class="note"> <span class="jamp">SECTION TITLE 6</span></h1>
  •     <br>
  •     <p class="note">
  •         Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
  •         <br><br>
  •         Why do we use it?<br> It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English. Many desktop publishing packages and web page editors now use Lorem Ipsum as their default model text, and a search for 'lorem ipsum' will uncover many web sites still in their infancy. Various versions have evolved over the years, sometimes by accident, sometimes on purpose (injected humour and the like).
  •         <br><br>
  •         Where can I get some?<br>
  •         There are many variations of passages of Lorem Ipsum available, but the majority have suffered alteration in some form, by injected humour, or randomised words which don't look even slightly believable. If you are going to use a passage of Lorem Ipsum, you need to be sure there isn't anything embarrassing hidden in the middle of text. All the Lorem Ipsum generators on the Internet tend to repeat predefined chunks as necessary, making this the first true generator on the Internet. It uses a dictionary of over 200 Latin words, combined with a handful of model sentence structures, to generate Lorem Ipsum which looks reasonable. The generated Lorem Ipsum is therefore always free from repetition, injected humour, or non-characteristic words etc.
  •     <p>
  •     </div>
  • </div>

CSS

  • .section7{
  •   width:100%;
  •   height:110vh;
  •   overflow: hidden;
  •   background:#020409;
  • }
  • .section7 div{
  •   width:80%;
  •   height:100vh;
  •   margin:auto;
  • }
  • .section7 .picture{
  •   width:35%;
  •   height:auto;
  •   margin:30px;
  •   clip-path: ellipse(45% 45% at 50% 50%);
  •   shape-outside:ellipse(45% 45% at 50% 50%);
  •   float:left;
  • }
  • .section7 .note{
  •   transform:translateX(200%);
  •   padding-right:100px;
  •   width:100%;
  •   color:#05ffb3;
  •   opacity:0;
  • }

jQuery

  •   $(window).scroll(function(){
  •     var i = $(this).scrollTop()
  •     let page7 = $('.section7').offset().top;
  •         if (i > page7 - 650){
  •            $(".section7 .picture").css('animation','polygon 2s');
  •            $(".section7 .note").css({
  •                                       'transition':'2.5s',
  •                                       'opacity':'1',
  •                                       'transform':'translateX(0)'
  •                                     });
  •         }
  •   });

CodePenではLoadingページをjQuery、その他はJavaScriptに書き換えて記述しています。
大変見ずらいかも知れませんが、倍率を変更するか、DEMOをご覧ください。

See the Pen Text animation using CSS Shapes by bens-user (@ben1099user) on CodePen.

内容的にボリュームが足りないので・・・😓

ページの内容がシェイプされて行くテキストアニメーションのみだと何だか殺風景なので、適度にレイアウト内にアニメーションやhover処理を組み込みました。
センスがないので笑われるかも知れませんが、そこのところはご勘弁くださいね。
😀

コメント

  1. erotik より:

    I have been browsing online more than three hours these days, but I by no means found any fascinating article like yours. It is lovely value enough for me. In my view, if all website owners and bloggers made excellent content material as you did, the net will be much more useful than ever before. Ertha Chen Travers

  2. erotik より:

    I love it when people come together and share ideas. Aloysia Hillie Mitchael

  3. bursa escort より:

    This is the right site for everyone who would like to understand this topic. Auroora Giff Weidar

  4. escort bayan より:

    This is a great inspiring article. I am pretty much pleased with your good work. Anett Evelin Joana

  5. erotik より:

    whoah this blog is excellent i really like studying your posts. Stay up the great work! You already know, lots of individuals are looking round for this info, you can help them greatly. Laurie Tobias Cherida

  6. erotik より:

    Hello there. I found your site by the use of Google even as searching for a similar subject, your website got here up. It appears great. I have bookmarked it in my google bookmarks to come back then. Janine Weston Helgeson

  7. whoiscall より:

    Thanks again!