バネ運動|HTML5(HTML5, JavaScript, CSS3) : デモ
バネ運動|HTML5(HTML5, JavaScript, CSS3) : ZIPファイル(7kb)
1.HTML
<!DOCTYPE html> <html lang="jp"> <head> <meta charset="UTF-8" /> <title>バネ運動</title> <link href="css/base.css" rel="stylesheet" type="text/css"> <script src="js/devicecheck.js"></script> <script src="js/base.js"></script> </head> <body> <div id="contents"> <div id="xy">x: 0<br/>y: 0</div> <canvas id="canvas" width="300" height="300"></canvas> </div> </body> </html>
2.CSS
@charset "utf-8"; body { margin:0; padding:0; background-color: #fff; font-family:Helvetica, HiraKakuProN-W3, sans-serif; font-size:12px; color:#000; } #contents { position: absolute; top: 0; left: 0; width: 300px; height:300px; border: 1px solid #000; overflow:hidden; } #canvas { position: absolute; top: 0; left: 0; width: 300px; height:300px; } #xy { position: absolute; top: 0; left: 0; width: 300px; height:10px; }
3.JavaScript
base.js
window.addEventListener("load", init, false); var mouseX = 0; var mouseY = 0; var ctx = null; var buttonDown = null; var buttonMove = null; var buttonUp = null; var theCanvas = null; var ball1 = new Object(); ball1.f = null; ball1.x = 0; ball1.y = 0; ball1.vx = 0; ball1.vy = 0; ball1.r = 10; ball1.d = 0; var bounce = -0.7; var gravity = 0.9; var offsetX = 0; var offsetY = 0; var oldX = 0; var oldY = 0; var radian = 0 * Math.PI/180; var range = 100; var speed = 0.09; var gravity = 0.997; function init() { var theContents = document.getElementById("contents"); offsetX = (theContents.currentStyle || document.defaultView.getComputedStyle(theContents,'')).width; offsetX = Number(offsetX.replace('px','')); offsetY = (theContents.currentStyle || document.defaultView.getComputedStyle(theContents,'')).height; offsetY = Number(offsetY.replace('px','')); document.getElementById('canvas').addEventListener('touchstart', function() { event.preventDefault(); }); document.getElementById('canvas').addEventListener('touchmove', function() { event.preventDefault(); }); document.getElementById('canvas').addEventListener('touchend', function() { event.preventDefault(); }); //ボタンタイプ if(g_mobiledevice==true) { buttonDown = 'touchstart'; buttonMove = 'touchmove'; buttonUp = 'touchend'; } else { buttonDown = 'mousedown'; buttonMove = 'mousemove'; buttonUp = 'mouseup'; } ball1.x = offsetX/2; ball1.y = offsetY/2; ball1.vx = Math.random()*10-5; ball1.vy = -10; document.getElementById('canvas').addEventListener(buttonDown, mouseDownHandler, false); document.getElementById('canvas').addEventListener(buttonUp, mouseUpHandler, false); setBallAnimation(); } function setBallAnimation() { ctx = document.getElementById('canvas').getContext("2d"); setInterval(animation, 1000/60); } function animation() { if(!ball1.f) { //ball1.vy += gravity; //ball1.x += ball1.vx; //ball1.y += ball1.vy; range = range*gravity; ball1.y = Math.sin(radian)*range; radian+=speed; /*if(ball1.x+ball1.r> offsetX) { ball1.x = offsetX-ball1.r; ball1.vx *= bounce; } else if(ball1.x-ball1.r< 0) { ball1.x = ball1.r; ball1.vx *= bounce; } if(ball1.y+ball1.r> offsetY) { ball1.y = offsetY-ball1.r; ball1.vy *= bounce; } else if(ball1.y-ball1.r< 0) { ball1.y = ball1.r; ball1.vy *= bounce; }*/ } ctx.clearRect(0,0,300,300); ctx.strokeStyle = "#000000"; ctx.lineWidth = 1; ctx.beginPath(); ctx.arc(150, ball1.y+offsetY/2, ball1.r, 0, Math.PI*2, true); ctx.fill(); ctx.stroke(); ctx.fillStroke="#000000"; ctx.lineWidth=1; ctx.beginPath(); ctx.moveTo(150,0); ctx.lineTo(150,ball1.y+offsetY/2); ctx.fill(); ctx.stroke(); } function setMouseXY(e) { if(g_mobiledevice) { var rect = event.currentTarget.getBoundingClientRect(); mouseX = event.touches[0].pageX - rect.left; mouseY = event.touches[0].pageY - rect.top; } else if(g_browsername == 'MSIE'||g_browsername == 'Opera') { rect = document.getElementById("canvas").getBoundingClientRect(); mouseX = event.clientX - rect.left; mouseY = event.clientY - rect.top; } else if(g_browsername == 'Firefox') { rect = document.getElementById("canvas").getBoundingClientRect(); mouseX = e.clientX - rect.left; mouseY = e.clientY - rect.top; } else { rect = event.currentTarget.getBoundingClientRect(); mouseX = event.clientX - rect.left; mouseY = event.clientY - rect.top; } } function mouseUpHandler() { ball1.f = false; } function mouseDownHandler(e) { setMouseXY(e); oldX = ball1.x; oldY = ball1.y; var dx1 = mouseX - ball1.x; var dy1 = mouseY - ball1.y-offsetY/2; ball1.d = Math.sqrt(dx1 * dx1 + dy1 * dy1); if(ball1.d <= ball1.r) { ball1.f = true; } document.getElementById('canvas').addEventListener(buttonMove, mouseMoveHandler, false); } function mouseMoveHandler(e) { if(ball1.f) { setMouseXY(e); ball1.y = mouseY - offsetY/2; radian = 90 * Math.PI/180; range = ball1.y; document.getElementById('xy').innerHTML='x: '+mouseX+'<br/>'+'y: '+mouseY; } }
devicecheck.js
var g_mobiledevice = false; //iPhone、iPad、Androidのときtrue var g_browsername = 'unknown'; var g_browserver = -1; if(checkUserAgent() == false) { window.alert('このブラウザは対象外です'); } function checkUserAgent() { var ua = navigator.userAgent; //iPhoneか? var mstr = ua.match(/iPhone OS \d+/); if(mstr != null){ var vstr = mstr[0].match(/\d+/); if(parseInt(vstr[0]) >= 3) { g_mobiledevice = true; g_browsername = 'iPhone'; //alert('major-version ' + vstr); return true; } } //iPadか? if(ua.indexOf('iPad') > -1) { mstr = ua.match(/CPU OS \d+/); if(mstr != null) { var vstr = mstr[0].match(/\d+/); if(parseInt(vstr[0]) >= 3) { g_mobiledevice = true; g_browsername = 'iPad'; //alert('major-version ' + vstr); return true; } } } //Androidか? var mstr = ua.match(/Android \d+\.\d+/); if(mstr != null) { g_browsername = 'Android'; var vstr = mstr[0].match(/\d+\.\d+/); g_browserver = parseFloat(vstr[0]); g_mobiledevice = true; if(pg_browserver > 2.1) { //alert('version ' + vstr); return true; } } //Chromeか? mstr = ua.match(/Chrome\/\d+/); if(mstr != null) { g_browsername = 'Chrome'; var vstr = mstr[0].match(/\d+/); g_browserver = parseInt(vstr[0]); if(g_browserver >= 9) { //alert('major-version ' + vstr); return true; } } //Safariか? if(ua.indexOf('Safari') > -1) { mstr = ua.match(/Version\/\d+/); if(mstr != null){ var vstr = mstr[0].match(/\d+/); if(parseInt(vstr[0]) >= 5) { g_browsername = 'Safari'; //alert('major-version ' + vstr); return true; } } } //Internet Explorerか? mstr = ua.match(/MSIE \d+/); if(mstr != null) { var vstr = mstr[0].match(/\d+/); if(parseInt(vstr[0]) >= 9) { g_browsername = 'MSIE'; //alert('major-version ' + vstr); return true; } } //Firefoxか? mstr = ua.match(/Firefox\/\d+/); if(mstr != null){ var vstr = mstr[0].match(/\d+/); if(parseInt(vstr[0]) >= 4) { g_browsername = 'Firefox'; //alert('major-version ' + vstr); return true; } } //Operaか? if(ua.indexOf('Opera') > -1) { mstr = ua.match(/Version\/\d+/); if(mstr != null){ var vstr = mstr[0].match(/\d+/); if(parseInt(vstr[0]) >= 11) { g_browsername = 'Opera'; //alert('major-version ' + vstr); return true; } } } return false; }