Reputation: 79
So I've been reading this post which I found is the closest to what I want. Basically, I want two different text elements (two different words) moving around the page randomly and also bouncing off each other when they come in contact.
I have tried to edit the code so that it's black and have only one text element. However how can I also include a second text element (a different word) moving randomly as well?
Also how can I change it to Roboto Mono font?
// Return random RGB color string:
function randomColor() {
var hex = Math.floor(Math.random() * 0x1000000).toString(16);
return "#" + ("000000" + hex).slice(0);
}
// Poor man's box physics update for time step dt:
function doPhysics(boxes, width, height, dt) {
for (let i = 0; i < boxes.length; i++) {
var box = boxes[i];
// Update positions:
box.x += box.dx * dt;
box.y += box.dy * dt;
// Handle boundary collisions:
if (box.x < 0) {
box.x = 0;
box.dx = -box.dx;
} else if (box.x + box.width > width) {
box.x = width - box.width;
box.dx = -box.dx;
}
if (box.y < 0) {
box.y = 0;
box.dy = -box.dy;
} else if (box.y + box.height > height) {
box.y = height - box.height;
box.dy = -box.dy;
}
}
// Handle box collisions:
for (let i = 0; i < boxes.length; i++) {
for (let j = i + 1; j < boxes.length; j++) {
var box1 = boxes[i];
var box2 = boxes[j];
var dx = Math.abs(box1.x - box2.x);
var dy = Math.abs(box1.y - box2.y);
// Check for overlap:
if (2 * dx < (box1.width + box2.width ) &&
2 * dy < (box1.height + box2.height)) {
// Swap dx if moving towards each other:
if ((box1.x > box2.x) == (box1.dx < box2.dx)) {
var swap = box1.dx;
box1.dx = box2.dx;
box2.dx = swap;
}
// Swap dy if moving towards each other:
if ((box1.y > box2.y) == (box1.dy < box2.dy)) {
var swap = box1.dy;
box1.dy = box2.dy;
box2.dy = swap;
}
}
}
}
}
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
// Initialize random boxes:
var boxes = [];
for (var i = 0; i < 1; i++) {
var box = {
x: Math.floor(Math.random() * canvas.width),
y: Math.floor(Math.random() * canvas.height),
width: 50,
height: 20,
dx: (Math.random() - 0.5) * 0.3,
dy: (Math.random() - 0.5) * 0.3
};
boxes.push(box);
}
// Initialize random color and set up interval:
var color = randomColor();
setInterval(function() {
color = randomColor();
}, 450);
// Update physics at fixed rate:
var last = performance.now();
setInterval(function(time) {
var now = performance.now();
doPhysics(boxes, canvas.width, canvas.height, now - last);
last = now;
}, 50);
// Draw animation frames at optimal frame rate:
function draw(now) {
context.clearRect(0, 0, canvas.width, canvas.height);
for (let i = 0; i < boxes.length; i++) {
var box = boxes[i];
// Interpolate position:
var x = box.x + box.dx * (now - last);
var y = box.y + box.dy * (now - last);
context.beginPath();
context.fillStyle = color;
context.font = "40px 'Roboto Mono'";
context.textBaseline = "hanging";
context.fillText("motion", x, y);
context.closePath();
}
requestAnimationFrame(draw);
}
requestAnimationFrame(draw);
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
<!DOCTYPE html>
<html>
<body>
<head>
<link rel="stylesheet" href="test.css">
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title></title>
</head>
<canvas id="canvas"></canvas>
<script src="test.js"></script>
</body>
</html>
Upvotes: 0
Views: 421
Reputation: 4985
Multiple text boxes is easy :
Change the initialize boxes part to include more than one.
// Initialize random boxes:
var boxes = [];
var boxCount = 2
for (var i = 0; i < boxCount; i++) {
Second your random color is flawed , try this :
function randomColor() {
var hex = Math.floor(Math.random() * 0x1000000).toString(16);
return "#" + ("000000" + hex).substr(hex.length);
}
I don't think that roboto is available in the canvas element. (I could be wrong)
monospace
is available though.
Edit
If you want different words you could use another array for them:
var words = ['motion','designer']
for (var i = 0; i < words.length; i++) {
as you create boxes use the words array.
You can't hard code the size of the box if you want have the words to collide. Height should be at least the font height 40px
and if you want to get the width of the text box there is a context helping function :
box.width = context.measureText(words[i]).width;
See the snippet for usage :
// Return random RGB color string:
function randomColor() {
var hex = Math.floor(Math.random() * 0x1000000).toString(16);
return "#" + ("000000" + hex).substr(hex.length);
}
// Poor man's box physics update for time step dt:
function doPhysics(boxes, width, height, dt) {
for (let i = 0; i < boxes.length; i++) {
var box = boxes[i];
// Update positions:
box.x += box.dx * dt;
box.y += box.dy * dt;
// Handle boundary collisions:
if (box.x < 0) {
box.x = 0;
box.dx = -box.dx;
} else if (box.x + box.width > width) {
box.x = width - box.width;
box.dx = -box.dx;
}
if (box.y < 0) {
box.y = 0;
box.dy = -box.dy;
} else if (box.y + box.height > height) {
box.y = height - box.height;
box.dy = -box.dy;
}
}
// Handle box collisions:
for (let i = 0; i < boxes.length; i++) {
for (let j = i + 1; j < boxes.length; j++) {
var box1 = boxes[i];
var box2 = boxes[j];
var dx = Math.abs(box1.x - box2.x);
var dy = Math.abs(box1.y - box2.y);
// Check for overlap:
if (2 * dx < (box1.width + box2.width ) &&
2 * dy < (box1.height + box2.height)) {
// Swap dx if moving towards each other:
if ((box1.x > box2.x) == (box1.dx < box2.dx)) {
var swap = box1.dx;
box1.dx = box2.dx;
box2.dx = swap;
}
// Swap dy if moving towards each other:
if ((box1.y > box2.y) == (box1.dy < box2.dy)) {
var swap = box1.dy;
box1.dy = box2.dy;
box2.dy = swap;
}
}
}
}
}
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
// Initialize random boxes:
var boxes = [];
var words = ["designer","motion","hi"]
for (var i = 0; i < words.length; i++) {
var box = {
x: Math.floor(Math.random() * canvas.width),
y: Math.floor(Math.random() * canvas.height),
width: 50, // Will be dynamic
height: 42,
dx: (Math.random() - 0.5) * 0.3,
dy: (Math.random() - 0.5) * 0.3
};
boxes.push(box);
}
// Initialize random color and set up interval:
var color = randomColor();
setInterval(function() {
color = randomColor();
}, 450);
// Update physics at fixed rate:
var last = performance.now();
setInterval(function(time) {
var now = performance.now();
doPhysics(boxes, canvas.width, canvas.height, now - last);
last = now;
}, 50);
// Draw animation frames at optimal frame rate:
function draw(now) {
context.clearRect(0, 0, canvas.width, canvas.height);
for (let i = 0; i < boxes.length; i++) {
var box = boxes[i];
// Interpolate position:
var x = box.x + box.dx * (now - last);
var y = box.y + box.dy * (now - last);
box.width = context.measureText(words[i]).width;
context.beginPath();
context.fillStyle = color;
context.font = "normal 40px monospace";
context.textBaseline = "hanging";
context.fillText(words[i], x, y);
context.closePath();
}
requestAnimationFrame(draw);
}
requestAnimationFrame(draw);
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
<!DOCTYPE html>
<html>
<body>
<head>
<link rel="stylesheet" href="test.css">
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title></title>
</head>
<canvas id="canvas"></canvas>
<script src="test.js"></script>
</body>
</html>
Upvotes: 2