summaryrefslogtreecommitdiff
path: root/script.js
diff options
context:
space:
mode:
authorAnthony Wang2024-01-29 23:38:39 +0000
committerAnthony Wang2024-04-13 04:32:14 +0000
commit04d15f2b1dbe2bf5d051569917acdef4baa724dc (patch)
tree15a396aff50e2bd284a5f6a5a8e03fbd0e6609b8 /script.js
parent389eeeb48d5bc1ca6eb04517152b60450e7705b5 (diff)
Support different sized SVGs, center picture
Diffstat (limited to 'script.js')
-rw-r--r--script.js57
1 files changed, 35 insertions, 22 deletions
diff --git a/script.js b/script.js
index 7018f86..8e9bea7 100644
--- a/script.js
+++ b/script.js
@@ -7,23 +7,37 @@ document.querySelectorAll("svg").forEach(function(svg) {
})
let rad = 10 // Stroke radius
-let size = 200 // SVG width and height
let A = [] // Objects
-let cnt = 0
-let rowsize = Math.floor(window.innerWidth / 1.1 / size)
+let idcnt = 0
+let ix = 0
+let iy = 0
+let ny = 0
document.querySelectorAll("svg").forEach(function(svg) {
- // Move objects so they aren't overlapping
- svg.style.left = 1.1 * size * (cnt % rowsize) + "px"
- svg.style.top = 1.1 * size * Math.floor(cnt / rowsize) + "px"
- cnt++
+ // Position objects so they aren't overlapping
+ if (ix + svg.width.baseVal.value > window.innerWidth) {
+ ix = 0
+ iy += ny
+ ny = 0
+ }
+ svg.style.left = ix + "px"
+ svg.style.top = iy + "px"
+ ix += svg.width.baseVal.value
+ ny = Math.max(svg.height.baseVal.value, ny)
+ svg.id = idcnt++
+ const rect = svg.getBoundingClientRect()
let a = {
id: svg.id, // Unique ID
p: [], // Collision circles
- cm: svg.createSVGPoint(), // Center of mass
+ cm: svg.createSVGPoint(), // Position of center of mass relative to top left corner
+ x: rect.x, // x position of center of mass
+ y: rect.y, // y position of center of mass
vx: Math.random(), // x velocity
vy: Math.random(), // y velocity
th: 0, // Angular position
- w: Math.random() / 100 // Angular velocity
+ w: Math.random() / 100, // Angular velocity
+ m: 0, // Mass
+ mi: 0, // Moment of inertia
+ r: 0 // Distance to farthest point from center of mass
}
svg.querySelectorAll("path").forEach(function(path) {
// Get circles on path for collision checking
@@ -45,17 +59,16 @@ document.querySelectorAll("svg").forEach(function(svg) {
a.cm.x /= a.p.length
a.cm.y /= a.p.length
// Change origin to center of mass
- const rect = svg.getBoundingClientRect()
- a.x = rect.x + a.cm.x // Position of center of mass
- a.y = rect.y + a.cm.y // Position of center of mass
+ a.x += a.cm.x
+ a.y += a.cm.y
for (const p of a.p) {
p.x -= a.cm.x
p.y -= a.cm.y
}
svg.style.transformOrigin = a.cm.x + "px " + a.cm.y + "px"
- a.m = a.p.length // Mass
- a.mi = 0 // Moment of inertia
+ a.m = a.p.length
for (const p of a.p) a.mi += p.x ** 2 + p.y ** 2
+ for (const p of a.p) a.r = Math.max(Math.sqrt(p.x ** 2 + p.y ** 2), a.r)
A.push(a)
})
@@ -100,7 +113,7 @@ function collide(a, b, c, n) {
// Collision of object a with wall at position k and direction d
function wallCollide(a, k, d) {
- if ((d == 0 && Math.abs(a.x - k) < size) || (d == 1 && Math.abs(a.y - k) < size)) {
+ if ((d == 0 && Math.abs(a.x - k) < a.r) || (d == 1 && Math.abs(a.y - k) < a.r)) {
let c = {x: 0, y: 0, cnt: 0}
for (const p of a.p.map(x => rot(a, x))) {
if ((d == 0 && Math.abs(p.x - k) < rad) || (d == 1 && Math.abs(p.y - k) < rad)) {
@@ -122,7 +135,7 @@ function wallCollide(a, k, d) {
// Collision of object a with object b
function objectsCollide(a, b) {
- if (ds(a, b) < 2 * (size + 2 * rad) ** 2) {
+ if (ds(a, b) < (a.r + b.r + 2 * rad) ** 2) {
// Objects are close
let c = {x: 0, y: 0, cnt: 0}
let n = {x: 0, y: 0}
@@ -131,10 +144,10 @@ function objectsCollide(a, b) {
let aa = []
let bb = []
for (const p of a.p.map(x => rot(a, x))) {
- if (ds(p, b) < 2 * (size + 2 * rad) ** 2) aa.push(p)
+ if (ds(p, b) < (a.r + b.r + 2 * rad) ** 2) aa.push(p)
}
for (const p of b.p.map(x => rot(b, x))) {
- if (ds(p, a) < 2 * (size + 2 * rad) ** 2) bb.push(p)
+ if (ds(p, a) < (a.r + b.r + 2 * rad) ** 2) bb.push(p)
}
for (const p of aa) {
for (const q of bb) {
@@ -187,9 +200,9 @@ function tick() {
}
}
// Render every 10ms
- cnt++
- if (cnt == 10) {
- cnt = 0
+ tickcnt++
+ if (tickcnt == 10) {
+ tickcnt = 0
for (a of A) {
let e = document.getElementById(a.id)
e.style.left = a.x - a.cm.x + "px"
@@ -220,6 +233,6 @@ function updatev(event) {
}, 1000)
}
-cnt = 0
+let tickcnt = 0
setInterval(tick, 1)
document.addEventListener("click", updatev)