CSS + JSで万華鏡を作成する

画像 ページ上の万華鏡のようなものを考えたことはありませんでした。 前に一度見たことがありますが、あまり注意を払いませんでした。 それから、レベデフのポートフォリオの近くのフラッシュで万華鏡を見、マウスをひねり、仕事の原理を理解し、「クリスマスツリー、それは難しくない!」と考えました。



もちろん、本当に簡単だとは言えません。 そして、それは私が望んでいたすべてを完全に実現したとは言えません。 しかし、見るべきものがあります。そのために私はあなたを猫に招待します。



UPD

投稿で、IEで機能しないhlomzik hablovekaの改良版を追加しましたが、コードは少なくなり、動作はより正確になりました。





最初は、どこでも完全に機能することを望んでいました。 うまくいきませんでした。 その結果:





私が話していることを明確にするために、すぐに実際の例へのリンクを提供します: kaleidoscope.terion.name

行きましょう。



タスク1:方法を理解する。



万華鏡は、ディスクに収集された12のセクターで構成されています。 したがって、問題が発生します。セクターをどのように作るか? 実際、非常に簡単です。 4つのブロックといくつかのCSSが必要になります。 次のようになります。

画像

ブロックコンテナ、-15°回転したブロック、30°回転したブロック内、-15°回転した別のブロック内

セクターには、シフトする背景画像があります。



タスク2:実際、すべてを収集します。



したがって、コードは非常に単純です。

<div class = "sc s1" >

<div class = "rl" >

<div class = "rr" >

<div class = "sv" >

</div>

</div>

</div>

</div>








はい、すぐにページ上に複数の万華鏡があると想定しているため、クラスのみを使用します。

重要な条件 :万華鏡のサイズは、コンテナーのみのサイズを変更することで変更する必要があるため、内部のすべてがパーセント単位である必要があります。

パーセンテージは科学的突撃の方法によって選択されたことにすぐに注意します。 三角法の私の知識は、これをすべて計算するほど深くはありません:)



  1. .scope_container .sc {
  2. 幅:50%;
  3. 高さ:50%;
  4. -webkit-transform-origin:上部中央。
  5. -moz-transform-origin:上部中央。
  6. -o-transform-origin:上部中央。
  7. transform-origin:上部中央。
  8. 位置:絶対;
  9. トップ:50%;
  10. 左:25%;
  11. z-index:-1;
  12. }
  13. .scope_container .sc div {
  14. オーバーフロー:非表示}
  15. .scope_container .rl {
  16. 高さ:110%;
  17. 幅:60%;
  18. -webkit-transform:回転(-15度);
  19. -moz-transform:回転(-15度);
  20. -o-transform:回転(-15度);
  21. 変換:回転(-15度);
  22. 位置:相対;
  23. 上:1.5%;
  24. 左:4.5%;
  25. }
  26. .scope_container .rr {
  27. 高さ:100%;
  28. 幅:100%;
  29. -webkit-transform:回転(30度);
  30. -moz-transform:回転(30度);
  31. -o-transform:回転(30度);
  32. 変換:回転(30度);
  33. 位置:相対;
  34. 上:7%;
  35. 左:51%;
  36. }
  37. .scope_container .sv {
  38. 幅:105%;
  39. 高さ:105%;
  40. -webkit-transform:回転(-15度);
  41. -moz-transform:回転(-15度);
  42. -o-transform:回転(-15度);
  43. 変換:回転(-15度);
  44. 位置:相対;
  45. 上:-2%;
  46. 左:-29%;
  47. }




そのため、セクターのコードがあります。 これで、これらのセクターは12になり、どちらも2つのコンテナーにラップされなくなります。 内側の要素は要素の配置に使用され、外側の要素はサイズの設定と余分な部分のトリミングに使用されます。



その結果、HTMLコード全体は次のようになります。



  1. < div class = "parent" >
  2. < div class = "scope_container pattern" >
  3. < div class = "sc s1" > < div class = "rl" > < div class = "rr" > < div class = "sv" > </ div > </ div > </ div > </ div >
  4. < div class = "sc s2" > < div class = "rl" > < div class = "rr" > < div class = "sv" > </ div > </ div > </ div > </ div >
  5. < div class = "sc s3" > < div class = "rl" > < div class = "rr" > < div class = "sv" > </ div > </ div > </ div > </ div >
  6. < div class = "sc s4" > < div class = "rl" > < div class = "rr" > < div class = "sv" > </ div > </ div > </ div > </ div >
  7. < div class = "sc s5" > < div class = "rl" > < div class = "rr" > < div class = "sv" > </ div > </ div > </ div > </ div >
  8. < div class = "sc s6" > < div class = "rl" > < div class = "rr" > < div class = "sv" > </ div > </ div > </ div > </ div >
  9. < div class = "sc s7" > < div class = "rl" > < div class = "rr" > < div class = "sv" > </ div > </ div > </ div > </ div >
  10. < div class = "sc s8" > < div class = "rl" > < div class = "rr" > < div class = "sv" > </ div > </ div > </ div > </ div >
  11. < div class = "sc s9" > < div class = "rl" > < div class = "rr" > < div class = "sv" > </ div > </ div > </ div > </ div >
  12. < div class = "sc s10" > < div class = "rl" > < div class = "rr" > < div class = "sv" > </ div > </ div > </ div > </ div >
  13. < div class = "sc s11" > < div class = "rl" > < div class = "rr" > < div class = "sv" > </ div > </ div > </ div > </ div >
  14. < div class = "sc s12" > < div class = "rl" > < div class = "rr" > < div class = "sv" > </ div > </ div > </ div > </ div >
  15. </ div >
  16. </ div >




クラスs1-s12は、各セクターの位置を決定します。

パターンクラスは、使用する画像を決定します(パターンのeto_moy_nickに感謝します:))



ブロックを場所に配置します。

  1. .scope_container .s1 {
  2. -webkit-transform:回転(0度);
  3. -moz-transform:回転(0度);
  4. -o-transform:回転(0度);
  5. 変換:回転(0度);
  6. }
  7. .scope_container .s2 {
  8. -webkit-transform:回転(30度);
  9. -moz-transform:回転(30度);
  10. -o-transform:回転(30度);
  11. 変換:回転(30度);
  12. }
そして、30度単位で12日まで続きます。



それだけです。

しかし、これをすべて理解していないIEがいます! しかし、IEにはフィルターfilter:progid:DXImageTransform.Microsoft.Matrix(...)があります。

したがって、条件付きコメント[IE 8の場合]に次のコードを追加します。



  1. .scope_container .s1 {
  2. -webkit-transform:回転(0度);
  3. -moz-transform:回転(0度);
  4. -o-transform:回転(0度);
  5. 変換:回転(0度);
  6. }
  7. .scope_container .s2 {
  8. -webkit-transform:回転(30度);
  9. -moz-transform:回転(30度);
  10. -o-transform:回転(30度);
  11. 変換:回転(30度);
  12. }
実験が示したように、絶対位置とマトリックスでは、IEには問題があります。 したがって、そのような松葉杖を作る必要がありました。



次:

  1. .s2 {
  2. フィルター:progid:DXImageTransform.Microsoft.Matrix(M11 = 0.86602540、M12 = -0.50000000、M21 = 0.50000000、M22 = 0.86602540、SizingMethod = 'auto expand'、FilterType = 'nearest neighbor');
  3. マージン:-64.5%0 0 -25%;
  4. }
  5. .s3 {
  6. フィルター:progid:DXImageTransform.Microsoft.Matrix(M11 = 0.50000000、M12 = -0.86602540、M21 = 0.86602540、M22 = 0.50000000、SizingMethod = 'auto expand'、FilterType = 'nearest neighbor');
  7. マージン:-60.5%0 0 -32.8%;
  8. }


驚いたことに、 FilterType = '最近接'は結果をもたらしませんでした( バイキュービックスムージングなしでは、おそらく、そのようなブレーキはありません)。

マトリックスを計算するために、私はちょうど私の命を救ったこのツールを使用しました: www.boogdesign.com/examples/transforms/matrix-calculator.html

ブロックはマージンによって手動で配置されました。 すべてをIE7で機能させたい場合は、彼のためにこれらの同じマージンを書き直す必要があります。



タスク3:動かす



Javascript マウスの後ろのセクターの背景を移動する必要があります。 同時に、ページ上に万華鏡が1つもないことを覚えています。 以下のコード、コメントを読んでください:

  1. <script type = "text / javascript" >
  2. //クラスを使用しますが、IEはそれらの選択方法を知りません。 この欠点を補います。
  3. ifdocument .getElementsByClassName){
  4. getElementsByClass = function (classList、node){
  5. return (node || document ).getElementsByClassName(classList)
  6. }
  7. } else {
  8. getElementsByClass = function (classList、node){
  9. var node = node || 文書
  10. list = node.getElementsByTagName( '*' )、
  11. 長さ= list.length、
  12. classArray = classList.split(/ \ s + /)、
  13. クラス= classArray.length、
  14. 結果= []、i、j
  15. for (i = 0; i <length; i ++){
  16. for (j = 0; j <クラス; j ++){
  17. if (list [i] .className.search( '\\ b' + classArray [j] + '\\ b' )!= -1){
  18. result.push(リスト[i])
  19. 破る
  20. }
  21. }
  22. }
  23. 結果を返す
  24. }
  25. }
  26. //マウス座標を取得します
  27. 関数 mousePageXY(e)
  28. {
  29. var x = 0、y = 0;
  30. if (!e)e =ウィンドウ。 イベント ;
  31. if (e.pageX || e.pageY)
  32. {
  33. x = e.pageX;
  34. y = e.pageY;
  35. }
  36. else if (e.clientX || e.clientY)
  37. {
  38. x = e.clientX +( document .documentElement.scrollLeft || document .body.scrollLeft)-document .documentElement.clientLeft;
  39. y = e.clientY +( document .documentElement.scrollTop || document .body.scrollTop)-document .documentElement.clientTop;
  40. }
  41. return { "x" :x、 "y" :y};
  42. }
  43. window.onload = function (){
  44. var scope_cont = getElementsByClass( 'scope_container'document );
  45. //複数の万華鏡が存在する可能性があります。これを考慮してください。
  46. for (i = 0; i <scope_cont.length; i ++)
  47. {
  48. scope_cont [i] .onmouseover = function (){
  49. var sect = getElementsByClass( 'sv'this );
  50. var curscope = this ;
  51. this .onmousemove = function (e){
  52. var mCur = mousePageXY(e);
  53. for (n = 0; n <sect.length; n ++)
  54. {
  55. //偶数セクターの場合、背景は一方向に移動します
  56. if (n%2){
  57. sect [n] .style.backgroundPosition = mCur.x + 'px' + mCur.y + 'px' ;
  58. }
  59. //奇数-別の
  60. その他 {
  61. sect [n] .style.backgroundPosition = mCur.x *(-1)+ 'px' + mCur.y + 'px'
  62. }
  63. }
  64. }
  65. }
  66. scope_cont [i] .onmouseout = function (){
  67. //ブラウザを過負荷にしないために、自分で掃除します
  68. document .onmousemove = null ;
  69. }
  70. }
  71. }
  72. </ script>




一般に、準備ができています。

オペラ:

overflow:hidden.patternブロックに追加すると、 すべてが消えます。 その結果、空白のページが「ファン」の幅までボイドにスクロールします。

overflow:hiddenが削除された場合、「地球上で最も高速なブラウザ」©では、この構造はIEよりも遅くなります。

これは完全な失敗です。



私はあなたが興味を持っていたことを願っています:)



UPD

そして、これはhlomzikの人による改良版です

quaint.su/for/habrahabr/kaleidoscope

それが生まれた議論は: habrahabr.ru/blogs/css/99019/?reply_to=3057019#comment_3054307



All Articles