CSS のヒント: CSS の乱数

阿神
阿神オリジナル
2017-01-24 11:49:005548ブラウズ

最近、偶然興味深い問題に遭遇しました。アニメーション期間の値をランダムに設定したいと考えています。 これはランダムではない例です:

これは私が CSS で書いたアニメーションです:

@keyframes flicker {
  0% {
    opacity: 1;
  }
  100% {
    opacity: 0;
  }
}

#red {
  animation: flicker 2s ease alternate infinite;
}

現在は正常に動作していますが、ここではランダム化はなく、アニメーションの実行時間は 2 秒に固定されています。

私が欲しいアニメーションは実行時間が2秒以内の乱数です。私が望む効果は次のようなものです:

.element {
  animation: flicker $randomNumber alternate infinite;
}

$randomNumber ここで、特定の関数によって生成された乱数です。

Sass などの CSS プリプロセッサは次のような関数を提供します:

$randomNumber: random(5);

.thing {
  animation-duration: $randomNumber + s;
}

これはあなたが望むものかもしれませんが、私が望むものではありません。プリプロセッサによる乱数の生成プロセスには明らかな欠陥があります:

Sass中,随机数生成过程就像是从一个故事中选择名字的过程,它仅仅在写完之后随机取出,然后它就不再变化了。
— jake albaugh (@jake_albaugh) 2016年12月29日

Inつまり、CSS プリプロセッサが実行されると、ランダム化プロセスは終了し、生成された乱数は永久に値に固定されます (つまり、CSS プリプロセッサが再度実行されるまで再生成されません。)

これは、JavaScript の実行時に乱数を生成する JavaScript のランダム関数 (Math.random() など) とは異なります。

とても後悔しつつ、これはCSS変数(CSS自身のプロパティ)を使う絶好の機会だったということにも気づきました!これを使用して乱数を生成するのは簡単な作業ではありませんが、それでも役立ちます。

これらに詳しくなくても、心配する必要はありません。実際、CSS 変数は組み込みであり、SASS や LESS などの CSS プリプロセッサでよく知られている変数とは異なります。 Chris がリストした多くのメリットをここでご覧ください:

● 前処理を使用せずにそれらを使用できます。

●カスケード式です。この変数の値を設定したり、任意のセレクターで現在の変数参照をオーバーライドしたりできます。

●値が変更されると (メディア クエリやその他の状態の変化など)、ブラウザは再レンダリングされます

● JavaScript を使用してそれらにアクセスし、操作することができます

最後の点は、私たちにとって重要です。 。 JavaScriptで乱数を生成し、生成された値をCSS変数に設定します。

CSS カスタム プロパティを設定し、デフォルト値を与えます (これは、値の書き込み時に JavaScript が何らかの理由で失敗した場合に便利です):

/* 设置默认的动画执行时间 */
:root {
  --animation-time: 2s; 
  }

これで、この変数を CSS で次のように使用できるようになります:

#red {
  animation: flicker var(--animation-time) ease alternate infinite;
  }

これ以上の手間はかかりません。 、早速始めてみましょう。 これは以前の SVG アニメーションの 1 つに似ていますが、CSS 変数を使用して作成されており、変数の値を変更して動作をテストできます。リアルタイムで効果をプレビューできます。

ここで、JavaScript を使用してこの変数にアクセスし、操作します:

var time = Math.random();

ここでは、SVG を使用して作成された赤い円を見つけ、setProperty を使用して --animation-time の値を変更できます。

var red = document.querySelector('#red');
red.style.setProperty('--animation-time', time +'s');

ここを見てください! SVG アニメーション要素に乱数が設定されています:

CodePen で Robin Rendle (@robinrendle) によって書かれたこの例の CSS 乱数 #3 を見てください。

これは、その値が JavaScript の実行時に生成される乱数であり、毎回変更されるため、以前のものよりも大幅に改善されています。 これで目的の効果が得られましたが、実行時に少し問題が発生しました: 実行時の乱数の周期的なアニメーション

幸いなことに、JavaScript を使用できるようになり、必要に応じてカスタマイズできます。必要に応じてカスタム変数を追加します。以下は、animation-duration の値を毎秒更新する例です:

var red = document.querySelector('#red');

function setProperty(duration) {
  red.style.setProperty('--animation-time', duration +'s');
}

function changeAnimationTime() {
  var animationDuration = Math.random();
  setProperty(animationDuration);
}

setInterval(changeAnimationTime, 1000);

これはまさに私が望むものです: Robin Rendle (@robinrendle) による CSS 乱数 #4 の例を CodePen で確認してください。

ただし、CSS 変数 (カスタム属性) のサポートはまだあまり充実していないため、使用する場合は注意してください。 次のようなプログレッシブ エンハンスメント アニメーションを実装できます:

#red {
  animation: flicker .5s ease alternate infinite;
  animation: flicker var(--animation-time) ease alternate infinite;}

CSS 変数がサポートされていない場合は、アニメーションの一部を見ることもできますが、私の頭の中では完璧な見た目ではありません。


ありがたいことに、CSS 変数はランダムなアニメーション継続時間の値を生成できる唯一の方法です。 JavaScript を使用して DOM を操作し、値をスタイルに直接設定できます:

var red = document.querySelector('#red');
red.style.animationDuration = Math.floor(Math.random() * 5 + 1) + "s";

そのような効果が必要な場合は、アニメーションが完了するのを待ってから新しい時間を設定することもできます:

var red = document.querySelector('#red');

function setRandomAnimationDuration() {
  red.style.animationDuration = Math.floor(Math.random() * 10 + 1) + "s";
}

red.addEventListener("animationiteration", setRandomAnimationDuration);

ここでは、これを実現する方法のリスト 可能な方法として、EQCSS を使用してこの効果を実現することもできます:

@element '#animation' {
  .element {
    animation-duration: eval('rand')s;
  }}
var rand = Math.random();EQCSS.apply();

CSS 自体が正しい乱数を生成できることを期待していますか? たとえ存在するとしても、私はこれを知りません。しばらくお待ちいただく場合があります。実際に使用するには時間がかかります。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。