Add new blog posts and update existing content
- Created "My 2023 Coding Edition" post detailing projects and experiences in Rust and game development. - Added "My 2024 and 2025 roadmap" outlining goals and projects for the upcoming years. - Introduced "Python Tutorial - Introduction" and "Python - Variables" posts to teach Python programming basics. - Published "ROADMAP for 2023" to outline initial goals for the year. - Added "My Rust little adventure" post summarizing various Rust projects undertaken. - Released "Spanish Inquisition - 3.0.1 UPDATE" detailing the latest game update and features. - Added multiple background images in AVIF format for website use. - Removed unused SVG files to clean up the public directory.
This commit is contained in:
25
components/cursor-effect.tsx
Normal file
25
components/cursor-effect.tsx
Normal file
@@ -0,0 +1,25 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect } from "react";
|
||||
|
||||
export default function CursorEffect() {
|
||||
useEffect(() => {
|
||||
let cursor: any;
|
||||
let isMounted = true;
|
||||
|
||||
import("cursor-effects").then((mod) => {
|
||||
if (isMounted && mod?.trailingCursor) {
|
||||
const TrailingCursor = mod.trailingCursor as any;
|
||||
cursor = new TrailingCursor();
|
||||
}
|
||||
});
|
||||
return () => {
|
||||
isMounted = false;
|
||||
if (cursor && typeof cursor.destroy === "function") {
|
||||
cursor.destroy();
|
||||
}
|
||||
};
|
||||
}, []);
|
||||
|
||||
return null;
|
||||
}
|
51
components/switching-background.tsx
Normal file
51
components/switching-background.tsx
Normal file
@@ -0,0 +1,51 @@
|
||||
"use client"; // This must be a client component to use React hooks
|
||||
|
||||
import React, { useState, useEffect } from "react";
|
||||
import Image from "next/image";
|
||||
|
||||
// --- Configuration ---
|
||||
// Add the paths to your 5 background images here.
|
||||
// Make sure they are in the `public/backgrounds` directory.
|
||||
const images = [
|
||||
"/backgrounds/1.avif",
|
||||
"/backgrounds/2.avif",
|
||||
"/backgrounds/3.avif",
|
||||
"/backgrounds/4.avif",
|
||||
"/backgrounds/5.avif",
|
||||
];
|
||||
|
||||
const SWITCH_INTERVAL = 60000; // 60 seconds
|
||||
|
||||
export default function SwitchingBackground() {
|
||||
const [currentImageIndex, setCurrentImageIndex] = useState(0);
|
||||
|
||||
useEffect(() => {
|
||||
// Set up an interval to switch the image
|
||||
const timer = setInterval(() => {
|
||||
setCurrentImageIndex((prevIndex) => (prevIndex + 1) % images.length);
|
||||
}, SWITCH_INTERVAL);
|
||||
|
||||
// Clear the interval when the component unmounts to prevent memory leaks
|
||||
return () => clearInterval(timer);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="fixed inset-0 -z-10 h-full w-full">
|
||||
{images.map((src, index) => (
|
||||
<Image
|
||||
key={src}
|
||||
src={src}
|
||||
alt={`Background image ${index + 1}`}
|
||||
fill
|
||||
className={`object-cover blur-md scale-105 transition-opacity duration-1000 ease-in-out ${
|
||||
index === currentImageIndex ? "opacity-100" : "opacity-0"
|
||||
}`}
|
||||
// Preload the next image for a smoother transition
|
||||
priority={index === (currentImageIndex + 1) % images.length}
|
||||
/>
|
||||
))}
|
||||
{/* Adds a subtle glossy overlay effect */}
|
||||
<div className="absolute inset-0 bg-gradient-to-t from-transparent via-transparent to-white/10" />
|
||||
</div>
|
||||
);
|
||||
}
|
76
components/window.tsx
Normal file
76
components/window.tsx
Normal file
@@ -0,0 +1,76 @@
|
||||
import React from "react";
|
||||
|
||||
const CloseIcon = () => (
|
||||
<svg
|
||||
width="12"
|
||||
height="12"
|
||||
viewBox="0 0 12 12"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M1 1L11 11M1 11L11 1"
|
||||
stroke="white"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
const MaximizeIcon = () => (
|
||||
<svg
|
||||
width="12"
|
||||
height="12"
|
||||
viewBox="0 0 12 12"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<rect x="1" y="1" width="10" height="10" stroke="white" strokeWidth="2" />
|
||||
</svg>
|
||||
);
|
||||
const MinimizeIcon = () => (
|
||||
<svg
|
||||
width="12"
|
||||
height="12"
|
||||
viewBox="0 0 12 12"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path d="M1 6H11" stroke="white" strokeWidth="2" strokeLinecap="round" />
|
||||
</svg>
|
||||
);
|
||||
|
||||
interface WindowProps {
|
||||
title: string;
|
||||
children: React.ReactNode;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export default function Window({
|
||||
title,
|
||||
children,
|
||||
className = "",
|
||||
}: WindowProps) {
|
||||
return (
|
||||
<div
|
||||
className={`rounded-lg border border-white/30 bg-white/70 shadow-window backdrop-blur-xl ${className}`}
|
||||
>
|
||||
{/* Title Bar with gradient and controls */}
|
||||
<div className="flex select-none items-center justify-between rounded-t-md bg-gradient-to-b from-blue-500 to-window-title px-4 py-1.5 font-bold text-white text-sm">
|
||||
<span>{title}</span>
|
||||
<div className="flex items-center space-x-2">
|
||||
<div className="flex h-4 w-4 items-center justify-center opacity-80">
|
||||
<MinimizeIcon />
|
||||
</div>
|
||||
<div className="flex h-4 w-4 items-center justify-center opacity-80">
|
||||
<MaximizeIcon />
|
||||
</div>
|
||||
<div className="flex h-4 w-4 items-center justify-center opacity-80">
|
||||
<CloseIcon />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* Content Area */}
|
||||
<div className="p-6">{children}</div>
|
||||
</div>
|
||||
);
|
||||
}
|
Reference in New Issue
Block a user