A Pen by lilgreenland on CodePen.
Last active
March 9, 2016 02:31
-
-
Save lilgreenland/7898fd740c4730d10097 to your computer and use it in GitHub Desktop.
magnetic field particle motion
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<canvas id="myCanvas" style="position : fixed;"> </canvas> |
A Pen by lilgreenland on CodePen.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var canvas = document.getElementById("myCanvas"); | |
var ctx = canvas.getContext("2d"); | |
ctx.canvas.width = window.innerWidth; | |
ctx.canvas.height = window.innerHeight; | |
var physics = { | |
B: -0.2, // Magnetic field directed into or outof screen | |
friction: 1, //slows particles 1 is off 0.99 is a bit | |
totalStars: 0, //spawns stars at start | |
pause: false, // pauses the simulation | |
} | |
var addStar = 0; | |
var container = { | |
x: 0, | |
y: 0, | |
width: canvas.width, | |
height: canvas.height | |
}; | |
var stars = []; | |
var mousePos = { | |
x: container.width * 0.5, | |
y: container.height * 0.5 | |
}; | |
window.onresize = function(event) { | |
ctx.canvas.width = window.innerWidth; | |
ctx.canvas.height = window.innerHeight; | |
container.height = window.innerHeight; | |
container.width = window.innerWidth; | |
}; | |
//adds a new star objects to array stars | |
function pushStar() { | |
stars.push({ | |
x: mousePos.x + 20 * (Math.random() - 0.5), | |
y: mousePos.y + 20 * (Math.random() - 0.5), | |
Vx: (Math.random() - 0.5) * 10, | |
Vy: (Math.random() - 0.5) * 10, | |
r: 20 * Math.random() + 3, // mass, and radius of circle | |
color: '#' + Math.floor(Math.random() * 16777216).toString(16), //random color | |
charge: (Math.round(Math.random()) * 2 - 1) * Math.ceil(Math.random() * 3), //1,2,3 or -1,-2,-3 | |
}); | |
} | |
//spawns stars at the start | |
for (var i = 0; i < physics.totalStars; i++) { | |
pushStar(); | |
} | |
//looks for key presses and logs them | |
var keys = []; | |
document.body.addEventListener("keydown", function(e) { | |
keys[e.keyCode] = true; | |
}); | |
document.body.addEventListener("keyup", function(e) { | |
keys[e.keyCode] = false; | |
}); | |
function keyChecks() { | |
if (keys[38]) { | |
physics.B += 0.005; | |
} else if (keys[40]) { | |
physics.B -= 0.005; | |
} | |
if (keys[32]) { | |
togglePause(); | |
} | |
} | |
function togglePause() { | |
if (physics.pause) { | |
physics.pause = false; | |
} else { | |
physics.pause = true; | |
} | |
} | |
document.addEventListener("mousedown", function() { | |
/*//push away if mouse down | |
for (var i = 0; i < stars.length; i++) { | |
stars[i].Vx += 3 * Math.cos(Math.atan2(stars[i].y - mousePos.y, stars[i].x - mousePos.x)); | |
stars[i].Vy += 3 * Math.sin(Math.atan2(stars[i].y - mousePos.y, stars[i].x - mousePos.x)); | |
}*/ | |
//if mouse in upper right corner delete all stars | |
if (mousePos.x > container.width - 20 && mousePos.y < 20) { | |
togglePause() | |
} else { | |
addStar = 1; | |
} | |
//if mouse in upper right corner delete all stars | |
if (mousePos.x < 20 && mousePos.y < 20) { | |
addStar = -1; | |
} | |
}); | |
//gets mouse position | |
function getMousePos(canvas, evt) { | |
var rect = canvas.getBoundingClientRect(); | |
return { | |
x: evt.clientX - rect.left, | |
y: evt.clientY - rect.top | |
}; | |
} | |
// waits for mouse move and then updates position | |
document.addEventListener('mousemove', function(evt) { | |
mousePos = getMousePos(canvas, evt); | |
}, false); | |
function attractedToMouse(i) { | |
// attraction to the mouse | |
stars[i].Vx += -0.03 * Math.cos(Math.atan2(stars[i].y - mousePos.y, stars[i].x - mousePos.x)); | |
stars[i].Vy += -0.03 * Math.sin(Math.atan2(stars[i].y - mousePos.y, stars[i].x - mousePos.x)); | |
} | |
var pause = false; | |
var fontSize = 20; | |
ctx.font = "20px Georgia"; | |
ctx.textAlign = "center"; | |
function printVariables(i) { | |
ctx.fillStyle = "#000000"; | |
ctx.font = "15px Arial"; | |
if (i === 0) { | |
ctx.fillText("B = " + physics.B.toFixed(5).substring(0, 5), container.width * 0.5, fontSize); | |
} | |
ctx.fillText("x = " + stars[i].x.toFixed(5).substring(0, 5) + "px", stars[i].x, stars[i].y + stars[i].r + fontSize); | |
ctx.fillText("y = " + stars[i].y.toFixed(5).substring(0, 5) + "px", stars[i].x, stars[i].y + stars[i].r + fontSize * 2); | |
//ctx.fillText("Vx = "+Math.round(stars[i].Vx),stars[i].x,stars[i].y+stars[i].r+fontSize*3); | |
//ctx.fillText("Vy = "+Math.round(stars[i].Vy),stars[i].x,stars[i].y+stars[i].r+fontSize*4); | |
var speed = Math.sqrt(stars[i].Vx * stars[i].Vx + stars[i].Vy * stars[i].Vy); | |
ctx.fillText("speed = " + speed.toFixed(5).substring(0, 5), stars[i].x, stars[i].y + stars[i].r + fontSize * 3); | |
ctx.fillText("q = " + Math.round(stars[i].charge), stars[i].x, stars[i].y + stars[i].r + fontSize * 4); | |
ctx.fillText("KE = " + (0.5 * stars[i].r * speed * speed).toFixed(5).substring(0, 5), stars[i].x, stars[i].y + stars[i].r + fontSize * 5); | |
ctx.fillText("p = " + (stars[i].r * speed).toFixed(5).substring(0, 5), stars[i].x, stars[i].y + stars[i].r + fontSize * 6); | |
} | |
function wallBounce(i) { | |
if (stars[i].x > container.width - stars[i].r) { | |
stars[i].Vx *= -physics.friction; | |
stars[i].x = container.width - stars[i].r; | |
} else if (stars[i].x < stars[i].r) { | |
stars[i].Vx *= -physics.friction; | |
stars[i].x = stars[i].r; | |
} | |
if (stars[i].y > container.height - stars[i].r) { | |
stars[i].Vy *= -physics.friction; | |
stars[i].y = container.height - stars[i].r; | |
} else if (stars[i].y < stars[i].r) { | |
stars[i].Vy *= -physics.friction; | |
stars[i].y = stars[i].r; | |
} | |
} | |
function magneticForce(i) { | |
var dir = Math.atan2(stars[i].Vy, stars[i].Vx); | |
var speed = Math.sqrt(stars[i].Vx * stars[i].Vx + stars[i].Vy * stars[i].Vy); | |
stars[i].Vx = speed * Math.cos(dir - physics.B * stars[i].charge / stars[i].r); | |
stars[i].Vy = speed * Math.sin(dir - physics.B * stars[i].charge / stars[i].r); | |
} | |
function drawMagField() { | |
ctx.fillStyle = "grey"; | |
var text | |
if (physics.B < 0) { | |
ctx.font = "10px Arial"; | |
text = "X" | |
} else if (physics.B > 0) { | |
ctx.font = "30px Arial"; | |
text = "." | |
} else { | |
text = " " | |
} | |
for (var i = 0; i < container.width; i += 10 / Math.abs(physics.B)) { | |
for (var j = 0; j < container.height; j += 10 / Math.abs(physics.B)) { | |
ctx.fillText(text, i, j); | |
} | |
} | |
} | |
function moveStar(i) { | |
//change position, velocity, size of object elements for each location in array | |
stars[i].x += stars[i].Vx; | |
stars[i].y += stars[i].Vy; | |
//friction slows velocity | |
stars[i].Vx *= physics.friction; | |
stars[i].Vy *= physics.friction; | |
} | |
//recursive draw function | |
function draw() { | |
keyChecks(); | |
ctx.globalCompositeOperation = 'source-over'; | |
ctx.clearRect(container.x, container.y, container.width, container.height); | |
// show where you can clear particles | |
ctx.fillStyle = "#00FFFF"; | |
ctx.fillRect(container.width - 20, 0, 20, 20); | |
//show where you can draw info | |
ctx.fillStyle = "#FF0000"; | |
ctx.fillRect(0, 0, 20, 20); | |
//trails | |
//ctx.fillStyle = "rgba(0, 0, 0, 0.15)"; //background color | |
//ctx.fillRect(container.x, container.y, container.width, container.height); | |
//ctx.globalCompositeOperation = 'lighter'; | |
drawMagField() | |
for (var i = 0; i < stars.length; i++) { | |
//draw a circle | |
ctx.beginPath(); | |
ctx.arc(stars[i].x, stars[i].y, stars[i].r, 0, 2 * Math.PI, true); | |
ctx.fillStyle = stars[i].color; | |
ctx.fill(); | |
//if mouse close to star show info | |
if ((stars[i].y - mousePos.y)*(stars[i].y - mousePos.y)+ (stars[i].x - mousePos.x)*(stars[i].x - mousePos.x) < stars[i].r*stars[i].r+2000){ | |
printVariables(i) | |
} | |
//if pause show info else move and spply forces to star | |
if (physics.pause) { | |
printVariables(i) | |
} else { | |
moveStar(i) | |
magneticForce(i) | |
//attractedToMouse(i); | |
//wallBounce(i) | |
} | |
} | |
//add a star or remove | |
if (addStar == 1) { | |
pushStar(); | |
addStar = 0; | |
} else if (addStar == -1) { | |
stars = []; | |
} | |
requestAnimationFrame(draw); | |
} | |
requestAnimationFrame(draw); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
body { | |
font: 15px arial, sans-serif; | |
background-color: white; | |
} | |
canvas { | |
position: absolute; | |
left: 0; | |
top: 0; | |
z-index: -1; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment