fixed the navbar and edited the themes config and edited the home page and enhancced the canves background joints and lines with more shapes
All checks were successful
Build frontend / build (push) Successful in 37s

This commit is contained in:
mouazkh
2026-01-22 17:37:39 +03:00
parent 28d089534b
commit 4ec438b9f5
8 changed files with 516 additions and 328 deletions

View File

@ -1,14 +1,14 @@
import React, { useRef, useEffect, useState } from 'react';
import './BackgroundCanvas.css';
import React, { useRef, useEffect, useState } from "react";
import "./BackgroundCanvas.css";
const BackgroundCanvas = ({ theme = 'light' }) => {
const BackgroundCanvas = ({ theme = "light" }) => {
const canvasRef = useRef(null);
const animationRef = useRef(null);
const jointsRef = useRef([]);
const cameraRef = useRef(null);
const keysRef = useRef(new Array(127).fill(0));
const worldRef = useRef({ width: 0, height: 0 });
const themeRef = useRef(theme);
const themeRef = useRef(theme);
class Camera {
constructor(position, zoom) {
@ -23,10 +23,14 @@ const BackgroundCanvas = ({ theme = 'light' }) => {
constructor(position, vector) {
this.position = position;
this.vector = vector;
this.speed = 0.5;
this.w = 2;
this.h = 2;
this.speed = Math.random() * 1.5 + 0.5;
this.bone_length = 150;
const shapes = ["circle", "triangle", "square", "pentagon"];
this.shape = shapes[Math.floor(Math.random() * shapes.length)];
this.size = Math.random() * 4 + 3;
this.angle = 0;
this.angularSpeed = (Math.random() - 0.5) * 0.1;
this.pulse = Math.random() * Math.PI * 2;
}
}
@ -41,7 +45,7 @@ const BackgroundCanvas = ({ theme = 'light' }) => {
{
x: Math.random() * 2 - 1,
y: Math.random() * 2 - 1,
}
},
);
});
return arr;
@ -52,6 +56,9 @@ const BackgroundCanvas = ({ theme = 'light' }) => {
joint.position.x += joint.vector.x * joint.speed;
joint.position.y += joint.vector.y * joint.speed;
joint.angle += joint.angularSpeed;
joint.pulse += 0.05;
if (joint.position.x < 0) joint.position.x = world.width;
if (joint.position.x > world.width) joint.position.x = 0;
if (joint.position.y < 0) joint.position.y = world.height;
@ -61,62 +68,94 @@ const BackgroundCanvas = ({ theme = 'light' }) => {
const drawJoints = (ctx, joints, camera, view, theme) => {
const len = joints.length;
let lineColor, pointColor, backgroundColor;
if (theme === 'dark') {
backgroundColor = '#446a85';
lineColor = '#FFFFFF';
pointColor = '#F5EEE6';
if (theme === "dark") {
backgroundColor = "#313131";
lineColor = "#F5EEE6";
pointColor = "#e06923";
} else {
backgroundColor = '#d3dde3';
lineColor = '#131313';
pointColor = '#041c40';
backgroundColor = "#f1f1f1ff";
lineColor = "rgba(49, 49, 49, 0.3)"; // More subtle lines
pointColor = "#041c40";
}
ctx.fillStyle = backgroundColor;
ctx.fillRect(0, 0, view.width, view.height);
for (let i = 0; i < len; i++) {
for (let j = i + 1; j < len; j += 3) {
const length = Math.hypot(
joints[j].position.x - joints[i].position.x,
joints[j].position.y - joints[i].position.y
joints[j].position.y - joints[i].position.y,
);
if (length <= joints[i].bone_length) {
ctx.beginPath();
ctx.strokeStyle = lineColor;
ctx.lineWidth = camera.zoom * (30 / length);
ctx.moveTo(
view.width / 2 + (joints[i].position.x - camera.position.x) * camera.zoom,
view.height / 2 + (joints[i].position.y - camera.position.y) * camera.zoom
view.width / 2 +
(joints[i].position.x - camera.position.x) * camera.zoom,
view.height / 2 +
(joints[i].position.y - camera.position.y) * camera.zoom,
);
ctx.lineTo(
view.width / 2 + (joints[j].position.x - camera.position.x) * camera.zoom,
view.height / 2 + (joints[j].position.y - camera.position.y) * camera.zoom
view.width / 2 +
(joints[j].position.x - camera.position.x) * camera.zoom,
view.height / 2 +
(joints[j].position.y - camera.position.y) * camera.zoom,
);
ctx.stroke();
ctx.closePath();
}
}
ctx.fillStyle = pointColor;
ctx.fillRect(
view.width / 2 + ((joints[i].position.x - camera.position.x) - joints[i].w / 2) * camera.zoom,
view.height / 2 + ((joints[i].position.y - camera.position.y) - joints[i].w / 2) * camera.zoom,
joints[i].w * camera.zoom,
joints[i].h * camera.zoom
const currentSize =
(joints[i].size + Math.sin(joints[i].pulse) * 1.5) * camera.zoom;
ctx.save();
ctx.translate(
view.width / 2 +
(joints[i].position.x - camera.position.x) * camera.zoom,
view.height / 2 +
(joints[i].position.y - camera.position.y) * camera.zoom,
);
ctx.rotate(joints[i].angle);
ctx.fillStyle = pointColor;
ctx.beginPath();
if (joints[i].shape === "circle") {
ctx.arc(0, 0, currentSize, 0, Math.PI * 2);
} else if (joints[i].shape === "triangle") {
ctx.moveTo(0, -currentSize);
ctx.lineTo(currentSize, currentSize);
ctx.lineTo(-currentSize, currentSize);
} else if (joints[i].shape === "square") {
ctx.rect(-currentSize / 2, -currentSize / 2, currentSize, currentSize);
} else if (joints[i].shape === "pentagon") {
for (let k = 0; k < 5; k++) {
ctx.lineTo(
currentSize * Math.cos((k * 2 * Math.PI) / 5 - Math.PI / 2),
currentSize * Math.sin((k * 2 * Math.PI) / 5 - Math.PI / 2),
);
}
}
ctx.fill();
ctx.closePath();
ctx.restore();
}
};
const moveCamera = (camera, keys) => {
if (keys[37]) camera.acceleration.x -= camera.speed;
if (keys[38]) camera.acceleration.y -= camera.speed;
if (keys[39]) camera.acceleration.x += camera.speed;
if (keys[40]) camera.acceleration.y += camera.speed;
if (keys[37]) camera.acceleration.x -= camera.speed;
if (keys[38]) camera.acceleration.y -= camera.speed;
if (keys[39]) camera.acceleration.x += camera.speed;
if (keys[40]) camera.acceleration.y += camera.speed;
if (keys[188]) camera.acceleration.z += 0.003;
if (keys[190]) camera.acceleration.z -= 0.003;
if (keys[190]) camera.acceleration.z -= 0.003;
camera.position.x += camera.acceleration.x;
camera.position.y += camera.acceleration.y;
@ -127,49 +166,53 @@ const BackgroundCanvas = ({ theme = 'light' }) => {
camera.acceleration.z *= 0.9;
};
const initCanvas = () => {
const canvas = canvasRef.current;
if (!canvas) return;
const initCanvas = () => {
const canvas = canvasRef.current;
if (!canvas) return;
const ctx = canvas.getContext('2d');
const view = {
width: window.innerWidth,
height: window.innerHeight,
const ctx = canvas.getContext("2d");
const view = {
width: window.innerWidth,
height: window.innerHeight,
};
canvas.width = view.width;
canvas.height = view.height;
worldRef.current = {
width: view.width * 2,
height: view.height * 2,
};
cameraRef.current = new Camera(
{
x: worldRef.current.width / 2,
y: worldRef.current.height / 2,
},
1,
);
const isMobile = window.innerWidth < 768;
const numberOfJoints = isMobile ? 150 : 600;
jointsRef.current = generateJoints(
numberOfJoints,
worldRef.current.width,
worldRef.current.height,
);
if (isMobile) {
jointsRef.current.forEach((joint) => {
joint.bone_length = 120;
joint.speed = 0.4;
});
}
};
canvas.width = view.width;
canvas.height = view.height;
worldRef.current = {
width: view.width * 2,
height: view.height * 2,
};
cameraRef.current = new Camera(
{
x: worldRef.current.width / 2,
y: worldRef.current.height / 2,
},
1
);
const isMobile = window.innerWidth < 768;
const numberOfJoints = isMobile ? 80 : 300;
jointsRef.current = generateJoints(numberOfJoints, worldRef.current.width, worldRef.current.height);
if (isMobile) {
jointsRef.current.forEach(joint => {
joint.bone_length = 120;
joint.speed = 0.4;
});
}
};
const animate = () => {
const canvas = canvasRef.current;
if (!canvas) return;
const ctx = canvas.getContext('2d');
const ctx = canvas.getContext("2d");
const view = {
width: canvas.width,
height: canvas.height,
@ -177,8 +220,14 @@ const initCanvas = () => {
moveCamera(cameraRef.current, keysRef.current);
moveJoints(jointsRef.current, worldRef.current);
drawJoints(ctx, jointsRef.current, cameraRef.current, view, themeRef.current);
drawJoints(
ctx,
jointsRef.current,
cameraRef.current,
view,
themeRef.current,
);
animationRef.current = requestAnimationFrame(animate);
};
@ -196,12 +245,12 @@ const initCanvas = () => {
keysRef.current[e.keyCode] = 0;
};
window.addEventListener('keydown', handleKeyDown);
window.addEventListener('keyup', handleKeyUp);
window.addEventListener("keydown", handleKeyDown);
window.addEventListener("keyup", handleKeyUp);
return () => {
window.removeEventListener('keydown', handleKeyDown);
window.removeEventListener('keyup', handleKeyUp);
window.removeEventListener("keydown", handleKeyDown);
window.removeEventListener("keyup", handleKeyUp);
};
}, []);
@ -219,8 +268,8 @@ const initCanvas = () => {
};
};
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
window.addEventListener("resize", handleResize);
return () => window.removeEventListener("resize", handleResize);
}, []);
useEffect(() => {
@ -232,15 +281,11 @@ const initCanvas = () => {
cancelAnimationFrame(animationRef.current);
}
};
}, []);
}, []);
return (
<canvas
ref={canvasRef}
className="background-canvas"
aria-hidden="true"
/>
<canvas ref={canvasRef} className="background-canvas" aria-hidden="true" />
);
};
export default BackgroundCanvas;
export default BackgroundCanvas;