Compare commits

...
Author SHA1 Message Date
bflatastic 37ef8fd96a reduced image sizes even more 2025-05-27 15:06:10 +07:00
bflatastic b1446916bb changed icons to image for model picker 2025-05-27 14:55:57 +07:00
bflatastic c1c1d694ab more performant background gallery for image 2025-05-27 14:55:01 +07:00
24 changed files with 153 additions and 21 deletions
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

After

Width:  |  Height:  |  Size: 196 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 276 KiB

After

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 320 KiB

After

Width:  |  Height:  |  Size: 176 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 564 KiB

After

Width:  |  Height:  |  Size: 297 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 366 KiB

After

Width:  |  Height:  |  Size: 202 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 452 KiB

After

Width:  |  Height:  |  Size: 260 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 337 KiB

After

Width:  |  Height:  |  Size: 188 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 378 KiB

After

Width:  |  Height:  |  Size: 218 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 302 KiB

After

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 446 KiB

After

Width:  |  Height:  |  Size: 232 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 238 KiB

After

Width:  |  Height:  |  Size: 143 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 344 KiB

After

Width:  |  Height:  |  Size: 199 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

After

Width:  |  Height:  |  Size: 205 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 146 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 299 KiB

After

Width:  |  Height:  |  Size: 161 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 396 KiB

After

Width:  |  Height:  |  Size: 209 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 318 KiB

After

Width:  |  Height:  |  Size: 184 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 521 KiB

After

Width:  |  Height:  |  Size: 272 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 318 KiB

After

Width:  |  Height:  |  Size: 183 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 396 KiB

After

Width:  |  Height:  |  Size: 210 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 316 KiB

After

Width:  |  Height:  |  Size: 183 KiB

@@ -1,18 +1,92 @@
.tile-background-animation {
background-image: url("/resources/images/tilebg.png");
background-repeat: repeat;
background-size: 512px;
animation: background-animation-scrolling 60s linear infinite;
-webkit-animation: background-animation-scrolling 60s linear infinite;
filter: grayscale(100%);
-webkit-filter: grayscale(100%);
@keyframes fadeInScale {
from {
opacity: 0;
transform: scale(0.98);
}
to {
opacity: 1;
transform: scale(1);
}
}
@keyframes background-animation-scrolling {
.image-fade-in {
animation: fadeInScale 0.8s cubic-bezier(0.22, 1, 0.36, 1);
will-change: opacity, transform;
}
@keyframes floatY {
0% {
background-position: 0 0;
transform: translateY(0px) scale(1);
}
50% {
transform: translateY(-12px) scale(1.03);
}
100% {
background-position: 512px 512px;
transform: translateY(0px) scale(1);
}
}
.image-float {
animation: floatY 5s ease-in-out infinite;
will-change: transform;
}
/* Staggered delays for up to 10 images per column */
.image-float:nth-child(1) {
animation-delay: 0s;
}
.image-float:nth-child(2) {
animation-delay: 0.5s;
}
.image-float:nth-child(3) {
animation-delay: 1s;
}
.image-float:nth-child(4) {
animation-delay: 1.5s;
}
.image-float:nth-child(5) {
animation-delay: 2s;
}
.image-float:nth-child(6) {
animation-delay: 2.5s;
}
.image-float:nth-child(7) {
animation-delay: 3s;
}
.image-float:nth-child(8) {
animation-delay: 3.5s;
}
.image-float:nth-child(9) {
animation-delay: 4s;
}
.image-float:nth-child(10) {
animation-delay: 4.5s;
}
@keyframes columnUp {
0% {
transform: translateY(0);
}
100% {
transform: translateY(-40px);
}
}
@keyframes columnDown {
0% {
transform: translateY(0);
}
100% {
transform: translateY(40px);
}
}
.column-marquee-up {
animation: columnUp 8s linear infinite alternate;
will-change: transform;
}
.column-marquee-down {
animation: columnDown 8s linear infinite alternate;
will-change: transform;
}
@@ -1,14 +1,70 @@
import { useState } from "react";
import "./Background.css";
function getStaticImages(count: number) {
return Array.from({ length: count }, (_, i) => ({
id: i + 1,
src: `resources/images/generate/image${i + 1}.png`,
alt: `Generated image ${i + 1}`,
}));
}
export default function GalleryBackground() {
const [frozen] = useState(false); // change this to true to make it static if it impacts pc performance - BFlat
const [images] = useState(() => {
const imgs = getStaticImages(20);
for (let i = imgs.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[imgs[i], imgs[j]] = [imgs[j], imgs[i]];
}
return imgs;
});
// Distribute images into 5 columns
const columns = [[], [], [], [], []] as Array<typeof images>;
images.forEach((img, i) => {
columns[i % 5].push(img);
});
return (
<>
<div className="pointer-events-none fixed inset-0 z-[1] overflow-hidden bg-[radial-gradient(50%_50%_at_50%_50%,rgba(0,0,0,0.00)_49%,rgba(0,0,0,0.60)_100%)]" />
<div className="tile-background-animation fixed inset-0 z-0 overflow-hidden">
<div
className={`h-full w-full opacity-30 transition-opacity duration-1000`}
>
<div className="absolute inset-0 grid grid-cols-5 gap-6 px-6 opacity-35" />
<div className="fixed inset-0 z-0 overflow-hidden">
<div className="h-full w-full">
<div className="pointer-events-none absolute inset-0 grid grid-cols-5 gap-6 px-6 opacity-15">
{columns.map((col, colIdx) => {
// Vertical offset classes for each column
const offsetClasses = [
"-mt-20", // col 0
"mt-5", // col 1
"-mt-48", // col 2
"mt-3", // col 3
"-mt-16", // col 4
];
// Alternate marquee direction
const marqueeClass =
colIdx % 2 === 0 ? "column-marquee-up" : "column-marquee-down";
return (
<div
key={colIdx}
className={`flex flex-col gap-6 ${offsetClasses[colIdx]} ${!frozen ? marqueeClass : ""}`}
>
{col.map((image) => (
<div
key={image.id}
className="relative aspect-[4/5] w-full overflow-hidden rounded-lg shadow-lg"
>
<img
src={image.src}
alt={image.alt}
className="image-fade-in h-full w-full object-cover"
draggable={false}
/>
</div>
))}
</div>
);
})}
</div>
</div>
</div>
</>
@@ -3,7 +3,7 @@ import { JobContextType } from "libs/common/src/lib/types";
import { PromptBoxImage } from "@storyteller/ui-promptbox";
import BackgroundGallery from "./BackgroundGallery";
import { PopoverMenu, type PopoverItem } from "@storyteller/ui-popover";
import { faFilm, faClock } from "@fortawesome/pro-solid-svg-icons";
import { faClock, faImage } from "@fortawesome/pro-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
interface TextToImageProps {
@@ -13,7 +13,9 @@ interface TextToImageProps {
const TextToImage = ({ imageMediaId, imageUrl }: TextToImageProps) => {
const containerRef = useRef<HTMLDivElement>(null);
const [selectedModel, setSelectedModel] = useState<string>("GPT Image 1 (GPT-4o)");
const [selectedModel, setSelectedModel] = useState<string>(
"GPT Image 1 (GPT-4o)",
);
const [useSystemPrompt, setUseSystemPrompt] = useState(false);
const [isImageBeingProcessed, setIsImageBeingProcessed] = useState(false);
const [selectedImage, setSelectedImage] = useState<File | null>(null);
@@ -30,21 +32,21 @@ const TextToImage = ({ imageMediaId, imageUrl }: TextToImageProps) => {
const modelList: PopoverItem[] = [
{
label: "GPT Image 1 (GPT-4o)",
icon: <FontAwesomeIcon icon={faFilm} className="h-4 w-4" />,
icon: <FontAwesomeIcon icon={faImage} className="h-4 w-4" />,
selected: selectedModel === "GPT Image 1 (GPT-4o)",
description: "Slow, ultra instructive model",
badges: [{ label: "45 sec.", icon: <FontAwesomeIcon icon={faClock} /> }],
},
{
label: "Flux Pro Ultra",
icon: <FontAwesomeIcon icon={faFilm} className="h-4 w-4" />,
icon: <FontAwesomeIcon icon={faImage} className="h-4 w-4" />,
selected: selectedModel === "Flux Pro Ultra",
description: "High quality model",
badges: [{ label: "15 sec.", icon: <FontAwesomeIcon icon={faClock} /> }],
},
{
label: "Recraft 3",
icon: <FontAwesomeIcon icon={faFilm} className="h-4 w-4" />,
icon: <FontAwesomeIcon icon={faImage} className="h-4 w-4" />,
selected: selectedModel === "Recraft 3",
description: "Fast and high-quality model",
badges: [{ label: "15 sec.", icon: <FontAwesomeIcon icon={faClock} /> }],