Skip to content

Commit

Permalink
add particles class
Browse files Browse the repository at this point in the history
  • Loading branch information
Aron-Lomner committed Nov 6, 2023
1 parent 77fb176 commit 76cf0ca
Show file tree
Hide file tree
Showing 5 changed files with 165 additions and 49 deletions.
36 changes: 6 additions & 30 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@
href="https://fonts.googleapis.com/css2?family=Orbitron&display=swap"
rel="stylesheet"
/>
<link
href="https://fonts.googleapis.com/css2?family=Roboto+Mono&display=swap"
rel="stylesheet"
/>

<title>Aron Lomner</title>
</head>
Expand All @@ -23,36 +27,7 @@
<div id="resume"><a href="">Resume</a></div>
</div>
</div>
<div id="asci-art">
<pre>
_ __ __
| | / /__ / /________ ____ ___ ___
| | /| / / _ \/ / ___/ __ \/ __ `__ \/ _ \
| |/ |/ / __/ / /__/ /_/ / / / / / / __/
|__/|__/\___/_/\___/\____/_/ /_/ /_/\___/
</pre>
<pre>
__
/ /_____
/ __/ __ \
/ /_/ /_/ /
\__/\____/
</pre>
<pre>
___ _
/ | _________ ____ ( )_____
/ /| | / ___/ __ \/ __ \|// ___/
/ ___ |/ / / /_/ / / / / (__ )
/_/ |_/_/ \____/_/ /_/ /____/
</pre>
<pre>
_ __ __ _ __ ______
| | / /__ / /_ _____(_) /____ / / / /
| | /| / / _ \/ __ \/ ___/ / __/ _ \/ / / /
| |/ |/ / __/ /_/ (__ ) / /_/ __/_/_/_/
|__/|__/\___/_.___/____/_/\__/\___(_|_|_)
</pre>
</div>
<div id="welcome"></div>
<div id="cover">
<img id="me" src="/assets/images/me.png" />
<div id="container">
Expand All @@ -62,5 +37,6 @@
</div>
</div>
</body>
<script type="module" src="/js/particles.js"></script>
<script type="module" src="/js/main.js"></script>
</html>
30 changes: 20 additions & 10 deletions js/main.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,28 @@
import { typeWrighter } from "./utils.js";
import { typeWrighter, sleep } from './utils.js';
import {Particles} from './particles.js';

async function initialize(){
let greeting = document.getElementById("greeting")
let pause = typeWrighter(greeting, "Hello, I'm")
let greeting = document.getElementById('greeting')
let pause = typeWrighter(greeting, 'Hello, I\'m')
await sleep(pause);
let name = document.getElementById("name");
pause = typeWrighter(name, "Aron Lomner");
let name = document.getElementById('name');
pause = typeWrighter(name, 'Aron Lomner');
await sleep(pause);
let occupation = document.getElementById("occupation")
typeWrighter(occupation, "Fullstack developer");
let occupation = document.getElementById('occupation')
typeWrighter(occupation, 'Fullstack developer');
}

initialize();

async function sleep(time) {
return new Promise((resolve) => setTimeout(resolve, time));
}
let container = document.getElementById('welcome');
let data = {
isText: true,
color: '#39FF14',
font: '18px Verdana',
text: 'Welcome!'
};

document.fonts.ready.then(() => {
console.log('eady')
new Particles(container, data, 5, 30);
})
130 changes: 130 additions & 0 deletions js/particles.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
class Particle {
constructor(x, y, color){
this.posX = x,
this.posY = y;
this.orginalX = x;
this.orginalY = y;
this.color = color;
this.size = 1;
this.weight = 15;
}

draw(ctx) {
ctx.fillStyle = this.color;
ctx.beginPath();
ctx.arc(this.posX, this.posY, this.size, 0, Math.PI * 2);
ctx.closePath();
ctx.fill();
}

update(mouse) {
let dX = mouse.x - this.posX;
let dY = mouse.y - this.posY;
let distance = Math.sqrt(dX*dX + dY * dY);
let velocityX = dX / distance;
let velocityY = dY / distance;
let maxDistance = mouse.radius;
let velocity = (maxDistance - distance) / maxDistance;
if (distance < mouse.radius) {
this.posX -= velocityX * velocity * this.weight;
this.posY -= velocityY * velocity * this.weight;
} else {
if (this.posX!=this.orginalX) {
this.posX -= (this.posX - this.orginalX) / 10;
}
if (this.posY!=this.orginalY){
this.posY -= (this.posY - this.orginalY) /10;
}
}
}
}

export class Particles {
constructor(container, data, scale, mouseRadius) {
this.data = data;
this.particles = [];
this.canvas = document.createElement('canvas');
let canvasSize;
if (data.isText) {
canvasSize = this.getTextSize(data.text, data.font);
}
this.canvas.width = canvasSize.width * scale;
this.canvas.height = canvasSize.height * scale;
container.appendChild(this.canvas);
this.ctx = this.canvas.getContext('2d');

this.mouse = {
x: null,
y: null,
radius: mouseRadius
}
window.addEventListener('mousemove',(event) => {
const rect = this.canvas.getBoundingClientRect();
this.mouse.x = event.x - rect.left;
this.mouse.y = event.y - rect.top;
});


this.particles = this.imageDataToParticles(this.getImageData(), scale);


this.animate = () => {
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
for (let i=0; i < this.particles.length; i++) {
this.particles[i].draw(this.ctx);
this.particles[i].update(this.mouse);
}
requestAnimationFrame(this.animate);
}
this.animate();
}

getTextSize(text, font) {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
ctx.font = font;
const textMetrics = ctx.measureText(text);

const width = textMetrics.width;
const height = textMetrics.fontBoundingBoxAscent + textMetrics.fontBoundingBoxDescent;
return {width, height};
}
getImageData() {
if (this.data.isText) {
const offScreenCanvas = document.createElement('canvas');
let canvasSize = this.getTextSize(this.data.text, this.data.font);
offScreenCanvas.width = canvasSize.width; // Width of your text canvas
offScreenCanvas.height = canvasSize.height; // Height of your text canvas
const offScreenCtx = offScreenCanvas.getContext('2d');

offScreenCtx.fillStyle = 'white';
offScreenCtx.font = this.data.font;
offScreenCtx.textAlign = 'left';
offScreenCtx.textBaseline = 'top';
offScreenCtx.fillText(this.data.text, 0, 0);

return offScreenCtx.getImageData(0, 0, offScreenCanvas.width, offScreenCanvas.height);
}
}
/**
* Converts an image data object into an array of particles.
* @param {ImageData} imageData - The image data object containing pixel information.
* @param {number} percentage between 50 & 100, the percentage of pixels to keep. 100 -> all pixels; 50 -> half of pixels;
* @param {Boolean} random if true each pixel has the chance of being kept based on the percentage you passed, otherwise it is: the first percentage out of 100 is kept then the rest ignored, percentage kept rest ignored...
*/
imageDataToParticles(imageData, scale) {
let arr = [];
//for every row of pixels
for (let row = 0; row < imageData.height; row++) {
//for every pixel in row
for (let pixel = 0; pixel < imageData.width; pixel++) {
const alpha = imageData.data[(row * imageData.width * 4) + (pixel * 4) + 3];
if(alpha > 0) {
arr.push(new Particle(pixel * scale, row * scale, this.data.color));
}
}
}console.log(arr);
return arr;
}
}

3 changes: 3 additions & 0 deletions js/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,7 @@ export function typeWrighter(element, message) {
}
loop(0);
return message.length * 100;
}
export async function sleep(time) {
return new Promise((resolve) => setTimeout(resolve, time));
}
15 changes: 6 additions & 9 deletions styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
body {
background-color: black;
color: #39FF14;
font-family: "Roboto Mono";
}
#navbar{
font-family: "Orbitron";
display: flex;
justify-content: space-between;
align-items: center;
Expand Down Expand Up @@ -41,15 +41,12 @@ body {
color: inherit;
text-decoration: none;
}
#asci-art {
/* Welcome */
#welcome {
display: flex;
flex-wrap: wrap;
margin-left: auto;
margin-right: auto;
}
pre {
display: inline-block;
margin: 5px;
justify-content: center;
align-items: center;
margin-top: 25px;
}
/* Cover */
#cover {
Expand Down

0 comments on commit 76cf0ca

Please sign in to comment.