1.3d cssを作成する。
下のサイトを参考に3dのballを作成してみた。
3d css sphereこんな感じ
htmlはこんな感じ。pythonで編集して貼り付け。
html
<div id="scene"> <div class="wrapper"> <ul class="ball"> <li class="ring"></li> <li class="ring"></li> <li class="ring"></li> <li class="ring"></li> <li class="ring"></li> <li class="ring"></li> <li class="ring"></li> <li class="ring"></li> <li class="ring"></li> <li class="ring"></li> <li class="ring"></li> <li class="ring"></li> <li class="ring"></li> <li class="ring"></li> <li class="ring"></li> <li class="ring"></li> <li class="ring"></li> <li class="ring"></li> <li class="ring"></li> <li class="ring"></li> <li class="ring"></li> <li class="ring"></li> <li class="ring"></li> <li class="ring"></li> <li class="ring"></li> <li class="ring"></li> <li class="ring"></li> <li class="ring"></li> <li class="ring"></li> <li class="ring"></li> <li class="ring"></li> <li class="ring"></li> <li class="ring"></li> <li class="ring"></li> <li class="ring"></li> <li class="ring"></li> <li class="ring"></li> <li class="ring"></li> <li class="ring"></li> <li class="ring"></li> <li class="ring"></li> <li class="ring"></li> <li class="ring"></li> <li class="ring"></li> <li class="ring"></li> <li class="ring"></li> </ul> </div> </div>
2.css
css
nth-childは長いのでpythonでtextを作成して貼り付け
@keyframes roundandround { to { transform: rotateX(360deg) rotateY(360deg); } } @keyframes show { to { opacity: 1; } } body { background-color: #000000; } #scene { width:600px; height:600px; margin: 100px auto; perspective: 1000px; zoom: 0.2; animation-name: start; animation-duration: 1s; display: inline-block; position: relative; margin-left: -300px; left: 50%; } .wrapper { width:100%; height:100%; transform: rotateX(45deg) rotateY(45deg); -webkit-transform-style: preserve-3d; -moz-transform-style: preserve-3d; } .ball { position: relative; width: 100%; height: 100%; margin:0 auto; -webkit-transform-style: preserve-3d; -moz-transform-style: preserve-3d; animation: roundandround 7.5s 1.3s infinite linear; } .ball .ring { position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:20px; border-style: dotted; border-radius: 50%; opacity: 0.0; animation: show 0.75s forwards ease-in-out; display:block; } .ring:nth-child(0) { color:#b00083; transform: rotateY(0deg); animation-delay: 0s; } .ring:nth-child(1) { color:#b20185; transform: rotateY(4deg); animation-delay: 0s; } .ring:nth-child(2) { color:#b30286; transform: rotateY(8deg); animation-delay: 0s; } .ring:nth-child(3) { color:#b50388; transform: rotateY(12deg); animation-delay: 0s; } .ring:nth-child(4) { color:#b70589; transform: rotateY(16deg); animation-delay: 0s; } .ring:nth-child(5) { color:#b9068b; transform: rotateY(20deg); animation-delay: 0s; } .ring:nth-child(6) { color:#ba078d; transform: rotateY(24deg); animation-delay: 0s; } .ring:nth-child(7) { color:#bc088e; transform: rotateY(28deg); animation-delay: 0s; } .ring:nth-child(8) { color:#be0990; transform: rotateY(32deg); animation-delay: 0s; } .ring:nth-child(9) { color:#bf0a91; transform: rotateY(36deg); animation-delay: 0s; } .ring:nth-child(10) { color:#c10c93; transform: rotateY(40deg); animation-delay: 0s; } .ring:nth-child(11) { color:#c30d94; transform: rotateY(44deg); animation-delay: 0s; } .ring:nth-child(12) { color:#c50e96; transform: rotateY(48deg); animation-delay: 0s; } .ring:nth-child(13) { color:#c60f98; transform: rotateY(52deg); animation-delay: 0s; } .ring:nth-child(14) { color:#c81099; transform: rotateY(56deg); animation-delay: 0s; } .ring:nth-child(15) { color:#ca119b; transform: rotateY(60deg); animation-delay: 0s; } .ring:nth-child(16) { color:#cb129c; transform: rotateY(64deg); animation-delay: 0s; } .ring:nth-child(17) { color:#cd149e; transform: rotateY(68deg); animation-delay: 0s; } .ring:nth-child(18) { color:#cf15a0; transform: rotateY(72deg); animation-delay: 0s; } .ring:nth-child(19) { color:#d116a1; transform: rotateY(76deg); animation-delay: 0s; } .ring:nth-child(20) { color:#d217a3; transform: rotateY(80deg); animation-delay: 0s; } .ring:nth-child(21) { color:#d418a4; transform: rotateY(84deg); animation-delay: 0s; } .ring:nth-child(22) { color:#d619a6; transform: rotateY(88deg); animation-delay: 0s; } .ring:nth-child(23) { color:#d81ba8; transform: rotateY(92deg); animation-delay: 0s; } .ring:nth-child(24) { color:#d91ca9; transform: rotateY(96deg); animation-delay: 0s; } .ring:nth-child(25) { color:#db1dab; transform: rotateY(100deg); animation-delay: 0s; } .ring:nth-child(26) { color:#dd1eac; transform: rotateY(104deg); animation-delay: 0s; } .ring:nth-child(27) { color:#de1fae; transform: rotateY(108deg); animation-delay: 0s; } .ring:nth-child(28) { color:#e020af; transform: rotateY(112deg); animation-delay: 0s; } .ring:nth-child(29) { color:#e221b1; transform: rotateY(116deg); animation-delay: 0s; } .ring:nth-child(30) { color:#e423b3; transform: rotateY(120deg); animation-delay: 0s; } .ring:nth-child(31) { color:#e524b4; transform: rotateY(124deg); animation-delay: 0s; } .ring:nth-child(32) { color:#e725b6; transform: rotateY(128deg); animation-delay: 0s; } .ring:nth-child(33) { color:#e926b7; transform: rotateY(132deg); animation-delay: 0s; } .ring:nth-child(34) { color:#ea27b9; transform: rotateY(136deg); animation-delay: 0s; } .ring:nth-child(35) { color:#ec28bb; transform: rotateY(140deg); animation-delay: 0s; } .ring:nth-child(36) { color:#ee29bc; transform: rotateY(144deg); animation-delay: 0s; } .ring:nth-child(37) { color:#f02bbe; transform: rotateY(148deg); animation-delay: 0s; } .ring:nth-child(38) { color:#f12cbf; transform: rotateY(152deg); animation-delay: 0s; } .ring:nth-child(39) { color:#f32dc1; transform: rotateY(156deg); animation-delay: 0s; } .ring:nth-child(40) { color:#f52ec2; transform: rotateY(160deg); animation-delay: 0s; } .ring:nth-child(41) { color:#f62fc4; transform: rotateY(164deg); animation-delay: 0s; } .ring:nth-child(42) { color:#f830c6; transform: rotateY(168deg); animation-delay: 0s; } .ring:nth-child(43) { color:#fa32c7; transform: rotateY(172deg); animation-delay: 0s; } .ring:nth-child(44) { color:#fc33c9; transform: rotateY(176deg); animation-delay: 0s; } .ring:nth-child(45) { color:#fd34ca; transform: rotateY(180deg); animation-delay: 0s; } /* この下は左右スワイプのアニメーション */ @keyframes start { 0% {} 100% {} } @keyframes move_right1 { 0% {left: 10%;} 100% {left: 50%;} } @keyframes move_right2 { 0% {left: 50%;} 100% {left: 90%;} } @keyframes move_left1 { 0% {left: 90%;} 100% {left: 50%;} } @keyframes move_left2 { 0% {left: 50%;} 100% {left: 10%;} }
3.tap eventを実装
tap eventをjavascriptで実装
esp6288に組込みたいので、javascriptで作成。
//touch event document.addEventListener('touchstart', handleTouchStart, false); document.addEventListener('touchmove', handleTouchMove, false); var position = 0; /* -1 left:0%, 0 left:50%, 1 left:100% */ var leftPos = '10%'; var centerPos = '50%'; var rightPos = '90%'; /* touchの利用可能判別 */ var supportTouch = 'ontouchend' in document; console.log('supportTouch:', supportTouch); var xDown = null; var yDown = null; /* touch */ function handleTouchStart(evt) { xDown = evt.touches[0].clientX; yDown = evt.touches[0].clientY; }; function leftMove(){ var elem = document.getElementById('scene'); if (position === 0){ position = -1; elem.style.animationName = 'move_left2'; elem.style.left = leftPos; }else if(position === 1){ position = 0; elem.style.animationName = 'move_left1'; elem.style.left = centerPos; } }; function rightMove(){ var elem = document.getElementById('scene'); if (position === 0){ position = 1; elem.style.animationName = 'move_right2'; elem.style.left = rightPos; }else if(position === -1){ position = 0 elem.style.animationName = 'move_right1'; elem.style.left = centerPos; } }; function handleTouchMove(evt) { if ( ! xDown || ! yDown ) { return; } var xUp = evt.touches[0].clientX; var yUp = evt.touches[0].clientY; var xDiff = xDown - xUp; var yDiff = yDown - yUp; if ( Math.abs( xDiff ) > Math.abs( yDiff ) ) {/*most significant*/ if ( xDiff > 0 ) { /* left swipe */ console.log('left!!!!!'); leftMove(); } else { /* right swipe */ console.log('right!!!!!'); rightMove(); } } else { if ( yDiff > 0 ) { /* up swipe */ } else { /* down swipe */ } } /* reset values */ xDown = null; yDown = null; };
4.mouse eventも実装
PCとスマホで動かすので、両方実装。
mousedownと同時にmousemoveのイベントもはいるので、
mousemoveイベントをmousedownのイベントでつけmousedownで外す。
それでも動いたり動かなかったり不安定なので、1回目のmousemoveイベントをはじく
/* mouse */ document.addEventListener('mousedown', handleMouseDown, false); //document.addEventListener('mousemove', handleOnMouseMove, false); document.addEventListener('mouseup', handleMouseUp, false); // mouse var mouseMoveStart = 0; function handleOnMouseMove(evt) { if ( ! xDown || ! yDown ) { return; } if(mouseMoveStart === 1){ mouseMoveStart = 0; return; } var xUp = evt.pageX; var yUp = evt.pageY; var xDiff = xDown - xUp; var yDiff = yDown - yUp; if ( Math.abs( xDiff ) > Math.abs( yDiff ) ) {/*most significant*/ if ( xDiff > 0 ) { /* left swipe */ console.log('left!!!!!'); leftMove(); } else { /* right swipe */ console.log('right!!!!!'); rightMove(); } } else { if ( yDiff > 0 ) { /* up swipe */ } else { /* down swipe */ } } /* reset values */ xDown = null; yDown = null; //mouseClickOn = 0; }; function handleMouseDown(evt) { xDown = evt.pageX; yDown = evt.pageY; mouseMoveStart = 1; document.addEventListener('mousemove', handleOnMouseMove, false); }; function handleMouseUp(evt){ handleOnMouseMove = null; document.removeEventListener('mousemove', handleOnMouseMove, false); };
5.swipeつきの3d css
こんな感じで実装できた。
PCとchromeの検証のデバイスモードで動作した。
画面を左右にswipeするとボールが左右に動く。
マウスでswipeしても動作する。
これをスイッチにしてesp8266のポートを動かそうかと考え中、、、