Added accelerometer
This commit is contained in:
322
accelerometer.html
Normal file
322
accelerometer.html
Normal file
@@ -0,0 +1,322 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>
|
||||
Accelerometer
|
||||
</title>
|
||||
<meta http-equiv="ScreenOrientation" content="autoRotate:disabled"/>
|
||||
<style>
|
||||
html, body {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0px;
|
||||
border: 0;
|
||||
overflow: hidden;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.greenSlider {
|
||||
position: absolute;
|
||||
width: 40%;
|
||||
top: 20%;
|
||||
-webkit-appearance: none;
|
||||
border-radius: 20px;
|
||||
height: 40px;
|
||||
background: #d3d3d3;
|
||||
outline: none;
|
||||
opacity: 0.7;
|
||||
-webkit-transition: .2s;
|
||||
transition: opacity .2s;
|
||||
transform: rotate(-90deg);
|
||||
}
|
||||
|
||||
.greenSlider::-webkit-slider-thumb {
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
background: #00ff00;
|
||||
border-radius: 50%;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
t {
|
||||
font-size: 45px;
|
||||
position: absolute;
|
||||
top: 5%;
|
||||
left: 20%;
|
||||
text-align: center;
|
||||
vertical-align: center;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
#valueText {
|
||||
top: 40%;
|
||||
}
|
||||
|
||||
label {
|
||||
font-size: 45px;
|
||||
position: absolute;
|
||||
left: 20%;
|
||||
text-align: center;
|
||||
vertical-align: center;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
input {
|
||||
position: absolute;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 10%;
|
||||
height: 10%;
|
||||
}
|
||||
|
||||
#label {
|
||||
left: 20%;
|
||||
top: 70%;
|
||||
}
|
||||
|
||||
#t1 {
|
||||
left: 20%;
|
||||
top: 75%;
|
||||
}
|
||||
|
||||
#label2 {
|
||||
left: 20%;
|
||||
top: 50%;
|
||||
}
|
||||
|
||||
#t2 {
|
||||
left: 20%;
|
||||
top: 55%;
|
||||
}
|
||||
</style>
|
||||
<link rel="shortcut icon" href="http://azgeorgis.net/rmg/favicon.ico" type="image/x-icon">
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="myCanvas" width="1" height="1" style="border:1px solid #ffffff;"></canvas>
|
||||
<form id = "form">
|
||||
<label for="t1" id="label">Graph</label>
|
||||
<input type="checkbox" id="t1" onclick="t1Click()">
|
||||
<label for="t2" id="label2">Pause</label>
|
||||
<input type="checkbox" id="t2" onclick="t2Click()">
|
||||
</form>
|
||||
<div class="slidecontainer">
|
||||
<t>Damping</t>
|
||||
<input type="range" min="0" max="0.02" value="0.01" step = "0.001" class="greenSlider" id="dampingSlider">
|
||||
<t id="valueText">0.01</t>
|
||||
</div>
|
||||
<script>
|
||||
var c = document.getElementById("myCanvas");
|
||||
var ctx = c.getContext("2d");
|
||||
ctx.canvas.width = window.innerWidth;
|
||||
ctx.canvas.height = window.innerHeight;
|
||||
|
||||
function Clear(ctx)
|
||||
{
|
||||
ctx.clearRect(-c.width, -c.height, c.width * 2, c.height * 2);
|
||||
}
|
||||
|
||||
window.addEventListener("devicemotion", accelerometerUpdate, true);
|
||||
ctx.scale(1.5, 1.5);
|
||||
|
||||
var aX = 0;
|
||||
var aY = 0;
|
||||
var aZ = 0;
|
||||
var yMass = 600;
|
||||
var vMass = 0;
|
||||
var m = 0;
|
||||
var k = 0.05;
|
||||
var xPos = 350;
|
||||
var yPos = 500;
|
||||
var nSteps = 2000;
|
||||
var stepWidth = 0.5;
|
||||
var damping = 0.01;
|
||||
var dampingSlider = document.getElementById("dampingSlider");
|
||||
var clickedOnSpring = false;
|
||||
var drawing = false;
|
||||
var mousePos = { x:0, y:0 };
|
||||
var lastPos = mousePos;
|
||||
var graph = false;
|
||||
var pause = false;
|
||||
var pastPositions = new Array(nSteps);
|
||||
|
||||
|
||||
dampingSlider.oninput = function()
|
||||
{
|
||||
damping = this.value;
|
||||
document.getElementById("valueText").textContent = damping.toString();
|
||||
}
|
||||
|
||||
function t1Click()
|
||||
{
|
||||
graph = !graph;
|
||||
}
|
||||
|
||||
function t2Click()
|
||||
{
|
||||
pause = !pause;
|
||||
}
|
||||
|
||||
function accelerometerUpdate(event) {
|
||||
aX = event.accelerationIncludingGravity.x;
|
||||
aY = event.accelerationIncludingGravity.y;
|
||||
aZ = event.accelerationIncludingGravity.z;
|
||||
}
|
||||
|
||||
function Update()
|
||||
{
|
||||
if (!pause)
|
||||
{
|
||||
Clear(ctx);
|
||||
m += 0.1;
|
||||
if (aY == null)
|
||||
{
|
||||
aY = 9.8;
|
||||
}
|
||||
vMass += 0.1 * aY - (yMass - yPos) * k * 0.1 - damping * vMass;
|
||||
yMass += vMass;
|
||||
if (graph)
|
||||
{
|
||||
for (i = nSteps - 1; i > 0; i--)
|
||||
{
|
||||
pastPositions[i] = pastPositions[i - 1];
|
||||
}
|
||||
pastPositions[0] = yMass;
|
||||
ctx.strokeStyle = "#ff0000";
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(xPos, yMass);
|
||||
for (i = 1; i < nSteps; i++)
|
||||
{
|
||||
ctx.lineTo(xPos + i * stepWidth, pastPositions[i]);
|
||||
}
|
||||
ctx.stroke();
|
||||
} else
|
||||
{
|
||||
pastPositions = new Array(nSteps);
|
||||
}
|
||||
ctx.strokeStyle = "#000000";
|
||||
drawSpring(1, 3, (yMass - yPos) / 18, 200, 10, xPos, yPos, 0.1);
|
||||
ctx.beginPath();
|
||||
ctx.arc(xPos, yMass, 10, 0, Math.PI * 2);
|
||||
ctx.fill();
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(xPos - 12, -c.height);
|
||||
ctx.lineTo(xPos - 12, c.height);
|
||||
ctx.stroke();
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(xPos + 12, -c.height);
|
||||
ctx.lineTo(xPos + 12, c.height);
|
||||
ctx.stroke();
|
||||
if (drawing)
|
||||
{
|
||||
console.log("Drawing");
|
||||
if (Math.sqrt(((mousePos.x / 1.5) - xPos) ** 2) <= 100)
|
||||
{
|
||||
console.log("mouse");
|
||||
yMass = mousePos.y / 1.5;
|
||||
vMass = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
setTimeout(Update, 1000/60);
|
||||
}
|
||||
|
||||
Update();
|
||||
|
||||
function drawSpring(a, b, xSize, ySize, numLoops, x, y, tStep)
|
||||
{
|
||||
//Draws coiled spring using prolate cycloid
|
||||
var tStart = Math.PI;
|
||||
var tEnd = (3 * Math.PI / 2) + (2 * Math.PI * numLoops);
|
||||
var yEnd = a * tEnd - b * Math.sin(tEnd);
|
||||
var xEnd = a + b;
|
||||
var yFactor = xSize / xEnd;
|
||||
var xFactor = ySize / yEnd;
|
||||
var xShift = x - a + b * Math.cos(Math.PI / 2);
|
||||
var yShift = y - a * (Math.PI / 2) + b * Math.sin(Math.PI / 2);
|
||||
for (t = tStart; t <= tEnd; t += tStep)
|
||||
{
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(xShift + xFactor * (a - b * Math.cos(t)), yShift + yFactor * (a * t - b * Math.sin(t)));
|
||||
ctx.lineTo(xShift + xFactor * (a - b * Math.cos(t + tStep)), yShift + yFactor * (a * (t + tStep) - b * Math.sin(t + tStep)));
|
||||
ctx.stroke();
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener('resize', function(event) {
|
||||
c.width = window.innerWidth;
|
||||
c.height = window.innerHeight;
|
||||
ctx.scale(1.5, 1.5);
|
||||
}, true);
|
||||
|
||||
|
||||
c.addEventListener("mousedown", function (e) {
|
||||
drawing = true;
|
||||
lastPos = getMousePos(c, e);
|
||||
}, false);
|
||||
c.addEventListener("mouseup", function (e) {
|
||||
drawing = false;
|
||||
}, false);
|
||||
c.addEventListener("mousemove", function (e) {
|
||||
mousePos = getMousePos(c, e);
|
||||
}, false);
|
||||
|
||||
function getMousePos(cDom, mouseEvent) {
|
||||
var rect = cDom.getBoundingClientRect();
|
||||
return {
|
||||
x: mouseEvent.clientX - rect.left,
|
||||
y: mouseEvent.clientY - rect.top
|
||||
};
|
||||
}
|
||||
|
||||
c.addEventListener("touchstart", function (e) {
|
||||
mousePos = getTouchPos(c, e);
|
||||
var touch = e.touches[0];
|
||||
var mouseEvent = new MouseEvent("mousedown", {
|
||||
clientX: touch.clientX,
|
||||
clientY: touch.clientY
|
||||
});
|
||||
c.dispatchEvent(mouseEvent);
|
||||
}, false);
|
||||
c.addEventListener("touchend", function (e) {
|
||||
var mouseEvent = new MouseEvent("mouseup", {});
|
||||
c.dispatchEvent(mouseEvent);
|
||||
}, false);
|
||||
c.addEventListener("touchmove", function (e) {
|
||||
var touch = e.touches[0];
|
||||
var mouseEvent = new MouseEvent("mousemove", {
|
||||
clientX: touch.clientX,
|
||||
clientY: touch.clientY
|
||||
});
|
||||
c.dispatchEvent(mouseEvent);
|
||||
}, false);
|
||||
|
||||
function getTouchPos(cDom, touchEvent) {
|
||||
var rect = cDom.getBoundingClientRect();
|
||||
return {
|
||||
x: touchEvent.touches[0].clientX - rect.left,
|
||||
y: touchEvent.touches[0].clientY - rect.top
|
||||
};
|
||||
}
|
||||
|
||||
document.body.addEventListener("touchstart", function (e) {
|
||||
if (e.target == c) {
|
||||
e.preventDefault();
|
||||
}
|
||||
}, false);
|
||||
document.body.addEventListener("touchend", function (e) {
|
||||
if (e.target == c) {
|
||||
e.preventDefault();
|
||||
}
|
||||
}, false);
|
||||
document.body.addEventListener("touchmove", function (e) {
|
||||
if (e.target == c) {
|
||||
e.preventDefault();
|
||||
}
|
||||
}, false);
|
||||
|
||||
</script>
|
||||
</body>
|
||||
<p xmlns:cc="http://creativecommons.org/ns#" style="font-size: 2vw; bottom: 0px; position: absolute;">
|
||||
This work is licensed under
|
||||
<a href="http://creativecommons.org/licenses/by-nc-nd/4.0/?ref=chooser-v1" target="_blank" rel="license noopener noreferrer" style="display:inline-block;">CC BY-NC-ND 4.0<img style="height:22px!important;margin-left:3px;vertical-align:text-bottom;" src="https://mirrors.creativecommons.org/presskit/icons/cc.svg?ref=chooser-v1"><img style="height:22px!important;margin-left:3px;vertical-align:text-bottom;" src="https://mirrors.creativecommons.org/presskit/icons/by.svg?ref=chooser-v1"><img style="height:22px!important;margin-left:3px;vertical-align:text-bottom;" src="https://mirrors.creativecommons.org/presskit/icons/nc.svg?ref=chooser-v1"><img style="height:22px!important;margin-left:3px;vertical-align:text-bottom;" src="https://mirrors.creativecommons.org/presskit/icons/nd.svg?ref=chooser-v1"></a></p>
|
||||
</html>
|
||||
10
index.html
10
index.html
@@ -494,6 +494,16 @@
|
||||
</t>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<a href='accelerometer.html'>Accelerometer spring</a>
|
||||
</td>
|
||||
<td>
|
||||
<t>
|
||||
<b>MOBILE ONLY</b>- lock your phone in portrait mode for best results. Displays a mass on a spring that you can control using your phone's accelerometer.
|
||||
</t>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<p xmlns:cc="http://creativecommons.org/ns#" >
|
||||
This work is licensed under
|
||||
|
||||
Reference in New Issue
Block a user