Forked from: kimmy's Yokohama Codes Collection 2016 View Diff (152) forked: Yokohama Codes Collection 2016 tsmallfield Follow 2016-05-06 13:21:36 License: MIT License Fork0 Fav2 View1001 Play Stop Reload Fullscreen Smart Phone Readme JavaScript 71 lines HTML 8 lines CSS 71 lines ※ JSでのStyle変更がなるべく少なく済むDOM構造に ※ イベントハンドラは必要なときだけ貼る ※ ウィンドウリサイズ対応 ※ 内部状態を割合で保持する(pxではなく) ※ グローバル変数を最低限に ※ フラグいらない ※ クリック領域はなるべく広く forked: Yokohama Codes Collection 2016 // forked from kimmy's "Yokohama Codes Collection 2016" http://jsdo.it/kimmy/gw5z (function(win, doc) { 'use strict'; var slider = doc.getElementById('slider'), track = doc.getElementById('track'), tint = doc.getElementById('tint'), balloon = doc.getElementById('balloon'), thumb = doc.getElementById('thumb'), TRACK_OFFSET = track.offsetLeft, startX, sliderRate, trackWidth; win.addEventListener('resize', handleWindowResize, false); handleWindowResize(); slider.addEventListener('click', handleSliderClick, false); thumb.addEventListener('mousedown', handleThumbMouseDown, false); updateThumbPos(0); function handleWindowResize() { trackWidth = track.offsetWidth; } function handleThumbMouseDown(evt) { var thumbX = trackWidth * sliderRate; startX = evt.pageX - thumbX; thumb.removeEventListener('mousedown', handleThumbMouseDown, false); doc.addEventListener('mousemove', handleMouseMove, true); doc.addEventListener('mouseup', handleMouseUp, true); } function handleMouseMove(evt) { var deltaX = evt.pageX - startX, rate = deltaX / trackWidth; updateThumbPos(rate); } function handleMouseUp() { thumb.addEventListener('mousedown', handleThumbMouseDown, false); doc.removeEventListener('mousemove', handleMouseMove, true); doc.removeEventListener('mouseup', handleMouseUp, true); } function handleSliderClick(evt) { var rect, layerX, rate; if (evt.target === thumb) { return; } rect = slider.getBoundingClientRect();// ※横スクロール対応無し layerX = evt.pageX - rect.left - TRACK_OFFSET; rate = layerX / trackWidth; updateThumbPos(rate); } function updateThumbPos(rate) { var per; rate = rate < 0 ? 0 : rate > 1 ? 1 : rate; per = (rate * 100 | 0) + '%'; tint.style.cssText += ';width:' + per + ';'; balloon.innerHTML = per; sliderRate = rate; } })(window, document); <div id="slider"> <div id="track"> <div id="tint"> <div id="balloon"></div> <div id="thumb"></div> </div> </div> </div> forked: Yokohama Codes Collection 2016 body { background: #e3e3e3; } #slider { position: absolute; top: 50%; right: 50px; left: 50px; height: 80px; background: #6e6e6e; border-radius: 10px; box-shadow: 0 0 2px rgba(0, 0, 0, 0.2) inset; -webkit-user-select: none; } #track { position: absolute; top: 35px; right: 35px; bottom: 35px; left: 35px; height: 10px; background: #3e3e3e; border-radius: 5px; box-shadow: 0 0 2px rgba(0, 0, 0, 0.8) inset; } #tint { -webkit-transition: width .2s ease-out; position: absolute; top: 0; bottom: 0; left: 0; border-radius: 5px; background: #e91e63; box-shadow: 0 0 2px rgba(0, 0, 0, 0.8) inset; } #tint:active { -webkit-transition: none; } #balloon { box-sizing: border-box; position: absolute; top: -130px; right: -60px; width: 120px; height: 60px; background: rgba(0, 0, 0, 0.9); color: rgba(255, 255, 255, 0.9); border-radius: 10px; box-shadow: 0 0 2px black inset; font-size: 20px; font-family: AvenirNext-Heavy; line-height: 60px; text-align: center; } #balloon:before { display: block; position: absolute; left: 50%; bottom: -20px; width: 0; height: 0; margin-left: -10px; border: solid 10px transparent; border-top-color: rgba(0, 0, 0, 0.9); content: ""; } #thumb { position: absolute; top: -18px; right: -22px; width: 44px; height: 44px; background: #8e8e8e; border-radius: 50%; box-shadow: 0 0 2px rgba(0, 0, 0, 0.2); cursor: move; } ※ JSでのStyle変更がなるべく少なく済むDOM構造に ※ イベントハンドラは必要なときだけ貼る ※ ウィンドウリサイズ対応 ※ 内部状態を割合で保持する(pxではなく) ※ グローバル変数を最低限に ※ フラグいらない ※ クリック領域はなるべく広く // forked from kimmy's "Yokohama Codes Collection 2016" http://jsdo.it/kimmy/gw5z (function(win, doc) { 'use strict'; var slider = doc.getElementById('slider'), track = doc.getElementById('track'), tint = doc.getElementById('tint'), balloon = doc.getElementById('balloon'), thumb = doc.getElementById('thumb'), TRACK_OFFSET = track.offsetLeft, startX, sliderRate, trackWidth; win.addEventListener('resize', handleWindowResize, false); handleWindowResize(); slider.addEventListener('click', handleSliderClick, false); thumb.addEventListener('mousedown', handleThumbMouseDown, false); updateThumbPos(0); function handleWindowResize() { trackWidth = track.offsetWidth; } function handleThumbMouseDown(evt) { var thumbX = trackWidth * sliderRate; startX = evt.pageX - thumbX; thumb.removeEventListener('mousedown', handleThumbMouseDown, false); doc.addEventListener('mousemove', handleMouseMove, true); doc.addEventListener('mouseup', handleMouseUp, true); } function handleMouseMove(evt) { var deltaX = evt.pageX - startX, rate = deltaX / trackWidth; updateThumbPos(rate); } function handleMouseUp() { thumb.addEventListener('mousedown', handleThumbMouseDown, false); doc.removeEventListener('mousemove', handleMouseMove, true); doc.removeEventListener('mouseup', handleMouseUp, true); } function handleSliderClick(evt) { var rect, layerX, rate; if (evt.target === thumb) { return; } rect = slider.getBoundingClientRect();// ※横スクロール対応無し layerX = evt.pageX - rect.left - TRACK_OFFSET; rate = layerX / trackWidth; updateThumbPos(rate); } function updateThumbPos(rate) { var per; rate = rate < 0 ? 0 : rate > 1 ? 1 : rate; per = (rate * 100 | 0) + '%'; tint.style.cssText += ';width:' + per + ';'; balloon.innerHTML = per; sliderRate = rate; } })(window, document); <div id="slider"> <div id="track"> <div id="tint"> <div id="balloon"></div> <div id="thumb"></div> </div> </div> </div> body { background: #e3e3e3; } #slider { position: absolute; top: 50%; right: 50px; left: 50px; height: 80px; background: #6e6e6e; border-radius: 10px; box-shadow: 0 0 2px rgba(0, 0, 0, 0.2) inset; -webkit-user-select: none; } #track { position: absolute; top: 35px; right: 35px; bottom: 35px; left: 35px; height: 10px; background: #3e3e3e; border-radius: 5px; box-shadow: 0 0 2px rgba(0, 0, 0, 0.8) inset; } #tint { -webkit-transition: width .2s ease-out; position: absolute; top: 0; bottom: 0; left: 0; border-radius: 5px; background: #e91e63; box-shadow: 0 0 2px rgba(0, 0, 0, 0.8) inset; } #tint:active { -webkit-transition: none; } #balloon { box-sizing: border-box; position: absolute; top: -130px; right: -60px; width: 120px; height: 60px; background: rgba(0, 0, 0, 0.9); color: rgba(255, 255, 255, 0.9); border-radius: 10px; box-shadow: 0 0 2px black inset; font-size: 20px; font-family: AvenirNext-Heavy; line-height: 60px; text-align: center; } #balloon:before { display: block; position: absolute; left: 50%; bottom: -20px; width: 0; height: 0; margin-left: -10px; border: solid 10px transparent; border-top-color: rgba(0, 0, 0, 0.9); content: ""; } #thumb { position: absolute; top: -18px; right: -22px; width: 44px; height: 44px; background: #8e8e8e; border-radius: 50%; box-shadow: 0 0 2px rgba(0, 0, 0, 0.2); cursor: move; } use an iframe compat browser, deer Play on jsdo.it games Author Share ブログに埋め込む QR Tag Download Complete! Description What kind of game? ※ JSでのStyle変更がなるべく少なく済むDOM構造に ※ イベントハンドラは必要なときだけ貼る ※ ウィンドウリサイズ対応 ※ 内部状態を割合で保持する(pxではなく) ※ グローバル変数を最低限に ※ フラグいらない ※ クリック領域はなるべく広く Control Device Smartphone Controllerjsdo.it WebSocket Controller» Mouse Keyboard Touch Device Fullscreen Activated Inactivated jsdo.it games から削除する Submit Author tsmallfield Interactive designer at Kayac inc. http://www.kayac.com/team/obara-toru http://dribbble.com/tsmallfield https://twitter.com/tsmallfield http://codepen.io/tsmallfield http://tsmallfield.hateblo.jp/ Tweet Default Panel Auto play Screenshot Readme JavaScript HTML CSS Size Width: px Height: px code <script type="text/javascript" src="http://jsdo.it/blogparts/KW81/js"></script> Discussion Questions on this code? Favorite by shuuuuun kimmy