`
A code project with no squishy text.Using the sping-mass model,the text is converted to a particle seperated by springs.The particle should behave like soft body physics as springs.
The i simply no output of the spring.
What I have tried:
I have tried to reposition the text.
``html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Squishy Text</title>
<script src="./index.js" type="module" defer></script>
</head>
<body>
<div id="canvas-container">
<canvas id="canvas"></canvas>
</div>
</body>
</html>
```
```js
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
const width = canvas.width = window.innerWidth;
const height = canvas.height = window.innerHeight;
const particles = [];
const springs = [];
const point = [0, 0];
const particleRadius = 3;
const springLength = 100;
const springK = 0.1;
ctx.font = "152px serif";
ctx.fillStyle = "red";
const options = {
text: {
data: "Squishy"
}
}
const tracedPoints = [];
const tracedData = ctx.getImageData(0, 0, ctx.measureText(options.text.data).width, 152);
for (let y = 0; y < tracedData.height; y++) {
for (let x = 0; x < tracedData.width; x++) {
const index = (y * tracedData.width + x) * 4;
if (tracedData.data[index + 3] > 0) {
tracedPoints.push([x, y]);
}
}
}
function drawSpring(context, pointA, pointB, stiffness, damping, amplitude, frequency) {
const dx = pointB.x - pointA.x;
const dy = pointB.y - pointA.y;
const distance = Math.sqrt(dx * dx + dy * dy);
const springLength = distance;
const springForce = (distance - springLength) * stiffness;
const dampingForce = damping * (pointB.vx - pointA.vx);
const totalForce = springForce + dampingForce;
const accelerationA = { x: (springForce * dx / distance - dampingForce * pointA.vx) / pointA.mass, y: (springForce * dy / distance - dampingForce * pointA.vy) / pointA.mass };
const accelerationB = { x: -totalForce / pointB.mass, y: -totalForce / pointB.mass };
pointA.vx += accelerationA.x;
pointA.vy += accelerationA.y;
pointB.vx += accelerationB.x;
pointB.vy += accelerationB.y;
pointA.x += pointA.vx;
pointA.y += pointA.vy;
pointB.x += pointB.vx;
pointB.y += pointB.vy;
context.beginPath();
context.moveTo(pointA.x, pointA.y);
const numSegments = 20;
const segmentLength = distance / numSegments;
for (let i = 1; i < numSegments; i++) {
const x = pointA.x + dx / distance * i * segmentLength;
const y = pointA.y + dy / distance * i * segmentLength + amplitude * Math.sin(i * 0.5 * frequency);
context.lineTo(x, y);
context.lineTo(pointB.x, pointB.y);
}
context.stroke();
context.closePath()
}
for (let i = 0; i < tracedPoints.length; i++) {
const point = tracedPoints[i];
const particle = {
x: point[0],
y: point[1],
vx: 0,
vy: 0
};
particles.push(particle);
for (let j = i + 1; j < tracedPoints.length; j++) {
const otherPoint = tracedPoints[j];
const dx = otherPoint[0] - point[0];
const dy = otherPoint[1] - point[1];
const distance = Math.sqrt(dx * dx + dy * dy);
if (distance < springLength) {
springs.push({
particleA: particle,
particleB: particles[j],
length: distance,
k: springK
});
}
}
}
function animate() {
ctx.clearRect(0, 0, width, height);
for (let i = 0; i < particles.length; i++) {
const particle = particles[i];
ctx.beginPath();
ctx.arc(particle.x, particle.y, particleRadius, 0, 2 * Math.PI);
ctx.fillStyle = "white";
ctx.fill();
}
if (springs.length > 0) {
for (let i = 0; i < springs.length; i++) {
const spring = springs[i];
if (spring.particleA && spring.particleB) {
drawSpring(ctx, spring.particleA, spring.particleB, spring.k, 0);
}
}
} else {
for (const spring of springs) {
drawSpring(ctx, spring.particleA, spring.particleB, spring.k, 0);
}
}
requestAnimationFrame(animate);
}
animate()
```