Cryptunes Tech Stack & Architecture
Architecture Flow: where design meets functionality
React-powered Core
Code Snippet: Rendering Audio and Visual Elements
import React, { useMemo } from "react";
import Image from "next/image";
import cn from "classnames";
const renderAudioElements = useMemo(
() =>
attributes?.map((attribute, index) => (
<audio
src={attribute.music}
id={`music-${attribute.id}`}
key={index}
onEnded={() => setIsRunning(false)}
/>
)),
[attributes]
);
const renderCharacters = useMemo(
() =>
characters.map((character, index) => (
<div
id={`character-selection-item-${index}`}
className="relative -mb-1 -ml-16"
key={index}
>
<button
onClick={() =>
character.assignedAttributeId
? handleRemoveAttribute(character.id)
: setSelected({
characterId: character.id,
attributeId: selected?.attributeId ?? 0,
})
}
>
<Image
src={character.images[currentImageIndexes[index]]}
width={400}
height={400}
alt={`Character ${character.id}`}
className={cn(
"h-auto w-auto",
character.assignedAttributeId
? "scale-100"
: selected
? "mb-2 scale-110"
: "scale-100"
)}
/>
</button>
{character.assignedAttributeId && !character.isPlaying && (
<div className="absolute bottom-4 left-0 w-full">
<div className="flex items-center justify-center gap-2">
<div className="relative">
<div className="h-[8px] w-[100px] rounded bg-white/50"></div>
<div
className="absolute left-0 top-0 h-[8px] rounded bg-white"
style={{
width: `${progress}%`,
}}
></div>
</div>
</div>
</div>
)}
</div>
)),
[characters, currentImageIndexes, handleRemoveAttribute, progress, selected]
);
Tailwind CSS: utility-first vibes for next-level design
Code Snippet: Styled Attribute Buttons
React-joyride: onboarding made fun
Code Snippet: Joyride Configuration
Last updated