質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

CSS

CSSはXMLやHTMLで表現した色・レイアウト・フォントなどの要素を指示する仕様の1つです。

Q&A

解決済

1回答

6653閲覧

カーソルの動きに合わせて要素を動かす場合の速度の指定方法について

IGE

総合スコア46

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

CSS

CSSはXMLやHTMLで表現した色・レイアウト・フォントなどの要素を指示する仕様の1つです。

0グッド

3クリップ

投稿2017/09/15 04:19

すみません。
無知ながら恐縮なのですが、CSS、JSで以下参考サイトのような、
カーソルと連動して3Dで動くwebを作りたいと思っております。

参考サイト:
https://www.clicktorelease.com/code/css3d-clouds-tutorial/final.html
https://www.clicktorelease.com/blog/how-to-make-clouds-with-css-3d/

ただ、こちらの参考サイトはカーソルの動きに過敏?に反応し、
カーソルを動かせば要素もすぐ動く、といった動作で、
カーソルを動かした時の動きに滑らかさがありません。

これにヌルヌルとして滑らかの動きを付けれれば、、と思っております。

カーソルを動かした時の、要素の動く速度などを調整し、easingなどを付ければいいのかと思うのですが、
どのように書けばよいのでしょうか。。

参考サイトのJSは以下のようになっております。

javascript

1<script> 2 3 (function() { 4 var lastTime = 0; 5 var vendors = ['ms', 'moz', 'webkit', 'o']; 6 for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { 7 window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame']; 8 window.cancelRequestAnimationFrame = window[vendors[x]+ 9 'CancelRequestAnimationFrame']; 10 } 11 12 if (!window.requestAnimationFrame) 13 window.requestAnimationFrame = function(callback, element) { 14 var currTime = new Date().getTime(); 15 var timeToCall = Math.max(0, 16 - (currTime - lastTime)); 16 var id = window.setTimeout(function() { callback(currTime + timeToCall); }, 17 timeToCall); 18 lastTime = currTime + timeToCall; 19 return id; 20 }; 21 22 if (!window.cancelAnimationFrame) 23 window.cancelAnimationFrame = function(id) { 24 clearTimeout(id); 25 }; 26 }()) 27 28 var layers = [], 29 objects = [], 30 31 world = document.getElementById( 'world' ), 32 viewport = document.getElementById( 'viewport' ), 33 34 d = 0, 35 p = 400, 36 worldXAngle = 0, 37 worldYAngle = 0; 38 39 viewport.style.webkitPerspective = p; 40 viewport.style.MozPerspective = p; 41 viewport.style.oPerspective = p; 42 43 generate(); 44 45 function createCloud() { 46 47 var div = document.createElement( 'div' ); 48 div.className = 'cloudBase'; 49 var x = 256 - ( Math.random() * 512 ); 50 var y = 256 - ( Math.random() * 512 ); 51 var z = 256 - ( Math.random() * 512 ); 52 var t = 'translateX( ' + x + 'px ) translateY( ' + y + 'px ) translateZ( ' + z + 'px )'; 53 div.style.webkitTransform = t; 54 div.style.MozTransform = t; 55 div.style.oTransform = t; 56 world.appendChild( div ); 57 58 for( var j = 0; j < 5 + Math.round( Math.random() * 10 ); j++ ) { 59 var cloud = document.createElement( 'img' ); 60 cloud.style.opacity = 0; 61 var r = Math.random(); 62 var src = 'cloud.png'; 63 ( function( img ) { img.addEventListener( 'load', function() { 64 img.style.opacity = .8; 65 } ) } )( cloud ); 66 cloud.setAttribute( 'src', src ); 67 cloud.className = 'cloudLayer'; 68 69 var x = 256 - ( Math.random() * 512 ); 70 var y = 256 - ( Math.random() * 512 ); 71 var z = 100 - ( Math.random() * 200 ); 72 var a = Math.random() * 360; 73 var s = .25 + Math.random(); 74 x *= .2; y *= .2; 75 cloud.data = { 76 x: x, 77 y: y, 78 z: z, 79 a: a, 80 s: s, 81 speed: .1 * Math.random() 82 }; 83 var t = 'translateX( ' + x + 'px ) translateY( ' + y + 'px ) translateZ( ' + z + 'px ) rotateZ( ' + a + 'deg ) scale( ' + s + ' )'; 84 cloud.style.webkitTransform = t; 85 cloud.style.MozTransform = t; 86 cloud.style.oTransform = t; 87 88 div.appendChild( cloud ); 89 layers.push( cloud ); 90 } 91 92 return div; 93 } 94 95 window.addEventListener( 'mousewheel', onContainerMouseWheel ); 96 window.addEventListener( 'DOMMouseScroll', onContainerMouseWheel ); 97 window.addEventListener( 'mousemove', onMouseMove ); 98 window.addEventListener( 'touchmove', onMouseMove ); 99 100 function onMouseMove ( e ) { 101 102 var x = e.clientX || e.touches[ 0 ].clientX; 103 var y = e.clientY || e.touches[ 0 ].clientY; 104 105 worldYAngle = -( .5 - ( x / window.innerWidth ) ) * 180; 106 worldXAngle = ( .5 - ( y / window.innerHeight ) ) * 180; 107 updateView(); 108 event.preventDefault(); 109 110 } 111 112 function onContainerMouseWheel( event ) { 113 114 event = event ? event : window.event; 115 d = d - ( event.detail ? event.detail * -5 : event.wheelDelta / 8 ); 116 updateView(); 117 event.preventDefault(); 118 119 } 120 121 function generate() { 122 123 objects = []; 124 125 if ( world.hasChildNodes() ) { 126 while ( world.childNodes.length >= 1 ) { 127 world.removeChild( world.firstChild ); 128 } 129 } 130 131 for( var j = 0; j < 5; j++ ) { 132 objects.push( createCloud() ); 133 } 134 135 } 136 137 function updateView() { 138 var t = 'translateZ( ' + d + 'px ) rotateX( ' + worldXAngle + 'deg) rotateY( ' + worldYAngle + 'deg)'; 139 world.style.webkitTransform = t; 140 world.style.MozTransform = t; 141 world.style.oTransform = t; 142 } 143 144 function update (){ 145 146 for( var j = 0; j < layers.length; j++ ) { 147 var layer = layers[ j ]; 148 layer.data.a += layer.data.speed; 149 var t = 'translateX( ' + layer.data.x + 'px ) translateY( ' + layer.data.y + 'px ) translateZ( ' + layer.data.z + 'px ) rotateY( ' + ( - worldYAngle ) + 'deg ) rotateX( ' + ( - worldXAngle ) + 'deg ) rotateZ( ' + layer.data.a + 'deg ) scale( ' + layer.data.s + ')'; 150 layer.style.webkitTransform = t; 151 layer.style.MozTransform = t; 152 layer.style.oTransform = t; 153 } 154 155 requestAnimationFrame( update ); 156 157 } 158 159 update(); 160 161 </script> 162

上記コードにどのうように書き足せば思った動きに近づくか、
お教えいただければ幸いです。。

どうぞよろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

上記のサイトの雲の方を拝見させていただきました。

簡単に仕組み

マウスを移動した場合、現在のポインタの位置と画面の幅・高さを計算して画面を何度回転させるかを計算してcssのtransform: rotate(xdeg, ydeg)に入れます。
マウスをスクロールした場合は、cssのtransform: translateZ(z)に値を入れて画面全体を拡大したり縮小したりします

コードの中身を見てみる

マウスを動かしたりスクロールしたりすると色々画面が変更されるのでその部分を探してみましょう。
コードの中にマウスを移動したり、スクロールしたりなどのイベントがあります。

window.addEventListener( 'mousewheel', onContainerMouseWheel ); window.addEventListener( 'DOMMouseScroll', onContainerMouseWheel ); window.addEventListener( 'mousemove', onMouseMove ); window.addEventListener( 'touchmove', onMouseMove );

次に、マウスが移動して画面がくるくる回る部分だけにまず注目しましょう。
上記のイベントだとmousemoveが該当するのでonMouseMoveに注目します。

js

1 2function onMouseMove ( e ) { 3 var x = e.clientX || e.touches[ 0 ].clientX; 4 var y = e.clientY || e.touches[ 0 ].clientY; 5 6 worldYAngle = -( .5 - ( x / window.innerWidth ) ) * 180; 7 worldXAngle = ( .5 - ( y / window.innerHeight ) ) * 180; 8 updateView(); 9 event.preventDefault(); 10}

e.clientXe.clientYは画面上でのマウスポインターの場所です。
それを色々計算してworldXAngleworldYAngleと言うものを出していますよね?

これで計算された値をupdateView()で反映しているわけです。

function updateView() { var t = 'translateZ( ' + d + 'px ) rotateX( ' + worldXAngle + 'deg) rotateY( ' + worldYAngle + 'deg)'; world.style.webkitTransform = t; world.style.MozTransform = t; world.style.oTransform = t; }

translateZとrotateXとrotateYに、dとworldXAngleとworldYAngleを入れてますよね?

マウス移動だけに注目して仕組みを見てみる

先ほどのonMouseMoveに戻って、worldXanguleを見るとx/window.innerWidthというものを計算しています。
windowの横幅が1000pxと仮定し、画面の横幅の真ん中にマウスを持ってきたとしましょう。
その場合のworldXAngleは0度になります。

worldXAngle = -( .5 - ( x / window.innerWidth ) ) * 180; ↓ worldXAngle = -( .5 - ( 500 / 1000 ) ) * 180; ↓ worldXAngle = -( .5 - 0.5 ) * 180; ↓ worldXAngle = 0;

同様に、画面の左端(0px)と右端(1000px)は

// 0pxの場合 worldXAngle = -(.5 * 180); //-90deg // 1000pxの場合 worldXAngle = -(-0.5 * 180); //90deg

これはy軸も同様です。
これからわかることは、実はこの雲は180度しか回っていません。
360度が1回転なので、0.5回転で反転(日本語あってるかな?)しかしてません。

つまり、画面をどう動かしても半分しか回転しないということです。
なのでクルクルの速度は画面が小さい早くなり、画面が大きいとマウスを動かす量が大きくなるのでゆっくり回るということです。

結論

ただ、こちらの参考サイトはカーソルの動きに過敏?に反応し、カーソルを動かせば要素もすぐ動く、といった動作で、カーソルを動かした時の動きに滑らかさがありません。
これにヌルヌルとして滑らかの動きを付けれれば、、と思っております。

長くなってしまいましたが、質問者様がおっしゃっていることを満たすのあれば、方法は2つです。

画面を大きくする

これは冗談というかユーザーの環境に大きく影響するので実現不可能だと思います。
ただ、仕組み的には画面が大きい&マウスの移動距離が大きくなるのでゆっくり回ると思います。
1つの可能性として捉えてください(笑)

回転率計算の部分の式をいじる

これは結構現実的です。
マウスの場所のx座標を実際の値より小さくする or 回転するmax値(下の例で言うと180)を小さくする方法です。

js

1function onMouseMove ( e ) { 2 var x = e.clientX || e.touches[ 0 ].clientX; //ここをいじる or 3 var y = e.clientY || e.touches[ 0 ].clientY; 4 5 worldYAngle = -( .5 - ( x / window.innerWidth ) ) * 180; // ここをいじる 6 worldXAngle = ( .5 - ( y / window.innerHeight ) ) * 180; 7 updateView(); 8 event.preventDefault(); 9}

x座標の値をいじる

js

1function onMouseMove ( e ) { 2 var x = (e.clientX || e.touches[ 0 ].clientX) / 2; //実際の場所の半分 3 var y = (e.clientY || e.touches[ 0 ].clientY) / 2; //実際の場所の半分 4 5 worldYAngle = -( .5 - ( x / window.innerWidth ) ) * 180; //当然算出される角度も半分に 6 worldXAngle = ( .5 - ( y / window.innerHeight ) ) * 180; //当然算出される角度も半分に 7 updateView(); 8 event.preventDefault(); 9}

回転の幅をいじる

js

1function onMouseMove ( e ) { 2 var x = e.clientX || e.touches[ 0 ].clientX; 3 var y = e.clientY || e.touches[ 0 ].clientY; 4 5 worldYAngle = -( .5 - ( x / window.innerWidth ) ) * 90; //回転のmax幅を半分にする 6 worldXAngle = ( .5 - ( y / window.innerHeight ) ) * 90; //回転のmax幅を半分にする 7 updateView(); 8 event.preventDefault(); 9}

デメリット

ただ、上記の方法にはもちろんデメリットも有り、それは見える範囲が狭くなってしまうという点です。
まぁ画面というインターフェースしかない以上しょうがない気もしますが。。。

まとめ

すごく長くなってしまいましたが、説明したとおりです。
仕組み等を理解していただけるとうれしいです!

失礼しました!

投稿2017/09/15 06:34

MasakazuFukami

総合スコア1869

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

IGE

2017/09/16 14:23

とても詳しいご回答ありがとうございます!!何度も見返し勉強させていただきたいと思います。ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問