

## 目的

ボタンをおすとテキストが複製されて画面が埋め尽くされる演出を作りたいです  
調べてみてもうまく動くものがありませんでした

## 問題

ただ、HTMLを増やすとHTMLの数等でCSSを当てている所でデザインが崩れてしまいます  
（例：nth-childやjQueryのeq）

  * これの直すのにかなりの時間がかかりそうなので、できればhtmlをふさやないままでテキストを複製したいです

  * また演出がデザインのためなので、じかにhtmlを増やしてしまうよりcssでやるほうが行儀がいいと感じたのでCSSでやりたいです

  * text()でテキストを複製してもその位置が指定できないのでつまってしまいました

## ソース

元ソースはもっと複雑で全部のせれないですが、簡単にはこのようになっています  
（実際はJQueryやCSSで順番系の指定を使ってると思っていただければ）

[code]

    <body>
        <div class="wrap">
            <section class="horror_phase3">
                <p>怖い文章</p><button type="button">～ですか?</button>
            </section>
        </div>
    </body>
    
[/code]

[code]

    .wrap {
         height: 100vh;
         width: 100%;
         position: relative;
    }
     .horror_phase3 {
         z-index: 3;
         position: absolute;
         display: flex;
         width: 100%;
         height: 100%;
         flex-direction: column;
         justify-content: center;
         align-items: center;
    }
     .horror_phase3 p {
         display: none;
    }
    
[/code]

[code]

    $(".horror_phase3 button").click(function() {
        let count = 1;
        let this1 = $(this);
        this1.prop("disabled", true);
        var counter = setInterval(function() {
    
    
            let p = this1.prev().clone();
            this1.parent().append(p.css({
                display: "block",
                position: "absolute",
                top: Math.floor(Math.random() * Math.floor(100)).toString() + "%",
                right: Math.floor(Math.random() * Math.floor(100)).toString() + "%"
            }));
            count++;
            if (count == 100) {
                clearInterval(counter);
            }
        }, 50);
    });
    
[/code]


CC BY-SA 4.0
2019-06-30T03:10:24.940
56238
2019-06-30T07:23:10.277
2019-06-30T06:43:59.557
2376
34910
question
html jquery css
テキストをHTMLを増やさず複製するには？


質問者さんの行ないたいことは、[`text-shadow`
プロパティ](https://developer.mozilla.org/ja/docs/Web/CSS/text-
shadow)を用いることで実現出来ると思います。しかし、この方法では **テキストに細かい装飾を行なうことが難しい**
ため、もし各テキストに対して適用するスタイルなどが存在する場合は、ノードを複製したほうが簡単だと思います。

今回は、[`color` プロパティ](https://developer.mozilla.org/ja/docs/Web/CSS/color)に
transparent を設定した上で、[`user-select`
プロパティ](https://developer.mozilla.org/ja/docs/Web/CSS/user-select)に none
を設定することで元テキストを隠しています。 **影の色のデフォルト値は currentColor** なので、[`text-shadow`
プロパティ](https://developer.mozilla.org/ja/docs/Web/CSS/text-
shadow)を指定する際に影の色を設定しなければ、影は透明になってしまいます[[1]](https://drafts.csswg.org/css-
text-decor-3/#text-shadow-property)。

> ## § 4. Text Shadows: the text-shadow
> property[[1]](https://drafts.csswg.org/css-text-decor-3/#text-shadow-
> property)
>
> This property accepts a comma-separated list of shadow effects to be applied
> to the text of the element. Values are interpreted as for `box-shadow` [CSS-
> BACKGROUNDS-3]. (But note that spread values and the `inset` keyword are not
> allowed.) Each layer shadows the element’s text and all its text decorations
> (composited together). If the color of the shadow is not specified, it
> defaults to `currentColor`, i.e. the shadow’s color is taken from the
> element’s `color` property.

また、オフセットを指定する際に使用出来る長さの単位は `<length>` 型であるため、必然的に **使用する単位は`vw`, `vh`**
になります[[1]](https://drafts.csswg.org/css-text-decor-3/#text-shadow-property)。

> ## § 4. Text Shadows: the text-shadow
> property[[1]](https://drafts.csswg.org/css-text-decor-3/#text-shadow-
> property)
>

>>   * Name: `text-shadow`

>>   * Value: `none` | [ `<color>` ? && `<length>`{2,3} ]#

>>   * Initial: `none`

>>   * Applies to: all elements

>>   * Inherited: yes

>>   * Percentages: n/a

>>   * Computed value: either the keyword `none` or a list, each item
consisting of three absolute lengths plus a computed color

>>   * Canonical order: per grammar

>>   * Animation type: by computed value, treating `none` as a zero-item list
and appending blank shadows (`transparent 0 0 0`) as needed to match the
longer list if the the shorter list is otherwise compatible with the longer
one

>>

[code]

    $(".horror_phase3 button").on("click", function() {
      $(this).prop("disabled", true);
    
      var count = 0;
      var counter = setInterval(
        function() {
          var p = this.prev()[0],
            x = Math.floor(Math.random() * Math.floor(100)) + "vw",
            y = Math.floor(Math.random() * Math.floor(100)) + "vh",
            text_offset = [x, y, "#000"].join(" "),
            text_shadow = p.style.textShadow;
          count = ++count;
    
          if (count == 100) {
            clearInterval(counter);
          }
    
          p.style.textShadow = text_shadow ?
            text_shadow.concat(",", text_offset) :
            text_offset;
        }.bind($(this)),
        50
      );
    });
[/code]

[code]

    * {
      margin: 0;
    }
    
    .wrap {
      position: relative;
      width: 100%;
      height: 100vh;
    }
    
    .horror_phase3 {
      display: flex;
      z-index: 3;
      position: absolute;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      width: 100%;
      height: 100%;
    }
    
    .horror_phase3 p {
      position: absolute;
      top: 0;
      left: 0;
      color: transparent;
      -moz-user-select: none;
      -webkit-user-select: none;
      -ms-user-select: none;
      user-select: none;
    }
[/code]

[code]

    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <div class="wrap">
      <section class="horror_phase3">
        <p>怖い文章</p>
        <button type="button">～ですか?</button>
      </section>
    </div>
[/code]


CC BY-SA 4.0
2019-06-30T07:23:10.277
56245
2019-06-30T07:23:10.277
32986
56238
answer