Ir al artículo
Aniq-UI

3D LandingHazlo tuyo

Hazlo tuyo

Cambia el texto, los sabores y sus latas 3D, los colores, las imágenes, las fuentes y el título de la página.

Dónde está cada cosa

QuéDónde
Todos los textos, en los dos idiomasmessages/en.json y messages/ar.json
Título y descripción de la páginalas claves metadata en esos mismos dos archivos
Los sabores y sus latas 3Dsrc/features/carousel/constants/juiceCans.ts, modelos en public/assets/3d/can/
Los colores de cada saborsrc/features/product-showcase/constants/themes.ts
Iluminación de las lataspublic/assets/hdri/forest_slope_1k.hdr, nombrado en src/features/carousel/constants/environment.ts
Imágenes de frutaspublic/assets/images/fruit/, listadas en src/features/floating-fruits/constants/fruitImages.ts
Cubitos de hielo, hojas, gota de aguapublic/assets/images/ice/, public/assets/images/leaf/, public/assets/images/drop.png
Artículos de ejemplo del carritosrc/features/navigation/constants/sampleCartItems.ts, imágenes en public/assets/images/can/
Tamaños de botellasrc/features/product-showcase/constants/sizes.ts
Enlaces de contactosrc/features/product-showcase/constants/contactLinks.ts
Elementos del menúsrc/features/navigation/constants/navItems.ts
Fuentessrc/app/[locale]/layout.tsx y src/app/globals.css
Faviconsrc/app/favicon.ico

Ejecuta yarn dev mientras trabajas: la página se recarga cada vez que guardas.

Texto

Cada palabra de la página viene de messages/en.json y messages/ar.json. Cambia el valor, nunca la clave, y mantén las mismas claves en los dos archivos.

ClaveQué es
brand.nameEl nombre al principio de la barra de menú
brand.wordmarkLa palabra gigante detrás de las latas
juices.<id>.name, juices.<id>.descriptionEl título y el texto de cada sabor
nav.itemsLas etiquetas del menú
cart.itemsLos nombres de los productos en el panel del carrito
scroll.firstLine, scroll.secondLineLas dos palabras del botón redondo de abajo, que abre el menú de contacto
contactEl título del menú de contacto y las etiquetas de sus enlaces
metadataEl título y la descripción de la página

La palabra gigante se dibuja con la fuente Thunder, en mayúsculas, y es JUICY en los dos idiomas. Mantenla en letras latinas, o cambia también su fuente.

Cambia un sabor

Un sabor es un id que une una lata 3D, un tema de color, una imagen de fruta y su texto. Los pasos siguientes sustituyen Mango Burst por un sabor nuevo, Peach Fizz, con el id peachFizz. Haz lo mismo con cualquiera de los cuatro.

La rueda tiene exactamente cuatro latas: cuatro posiciones en src/features/carousel/constants/positionConfigs.ts, y un cuarto de vuelta por paso. Sustituye un sabor en lugar de añadir un quinto.

  1. Cambia el id

    En src/types/juice.ts, sustituye el id antiguo por el nuevo. A partir de aquí, TypeScript señala cada archivo que todavía usa el id antiguo.

    src/types/juice.ts
    export type JuiceId =
      | "lemonGinger"
      | "blueberryAcai"
      | "peachFizz"
      | "raspberryRose";
  2. Crea el modelo de la lata

    Cada lata es un archivo .glb con una malla y dos materiales: M_Aluminum, el cuerpo metálico, y M_Cola, la etiqueta. La etiqueta es una sola imagen que envuelve la lata, de 2048 por 958 píxeles, guardada dentro del .glb. Para crear tu lata, abre una existente en Blender (File > Import > glTF 2.0), sustituye la imagen del material M_Cola por tu propia etiqueta del mismo tamaño y expórtala con File > Export > glTF 2.0, formato glTF Binary (.glb). Mantén el tamaño y la posición del modelo para que quede en la rueda como las demás.

    Guárdala como public/assets/3d/can/peach.glb. El código convierte todos los materiales en metal brillante al cargar el modelo (metalness y roughness en src/features/carousel/hooks/useCanModel.ts), así que cambia el acabado ahí y no en Blender.

  3. Apunta la rueda al modelo

    En src/features/carousel/constants/juiceCans.ts, cambia la entrada. El orden de esta lista es el orden en la rueda, y la primera lata es con la que se abre la página.

    src/features/carousel/constants/juiceCans.ts
    { id: "peachFizz", model: "/assets/3d/can/peach.glb" },
  4. Dale sus colores

    En src/features/product-showcase/constants/themes.ts, renombra la entrada y define sus colores. Lo que pinta cada uno está en Colores.

    src/features/product-showcase/constants/themes.ts
    peachFizz: {
      mainBgColor: "#F4A27B",
      blurColor: "#FFE1D2",
      textColor: "white",
      accentColor: "rgba(255, 255, 255, 0.9)",
      buttonBgColor: "white",
      buttonTextColor: "#F4A27B",
    },
  5. Añade su imagen de fruta

    Pon un PNG con fondo transparente en public/assets/images/fruit/, de 400 por 600 píxeles como los demás, y nómbralo en src/features/floating-fruits/constants/fruitImages.ts. La página lo muestra cuatro veces alrededor de la lata, con distintos tamaños y ángulos.

    src/features/floating-fruits/constants/fruitImages.ts
    peachFizz: "peach.png",
  6. Escribe su texto

    Tanto en messages/en.json como en messages/ar.json, renombra las claves del sabor en juices y cart.items y escribe el texto nuevo.

    messages/en.json
    "juices": {
      "peachFizz": {
        "name": "Peach Fizz",
        "description": "Ripe peaches and a light sparkle, cold from the can."
      }
    }
  7. Actualiza el carrito, si el sabor está en él

    El panel del carrito muestra los artículos de src/features/navigation/constants/sampleCartItems.ts: Lemon Ginger y Blueberry Açai. Si el tuyo es uno de ellos, cambia su juiceId, su price y su image, una foto de la lata en public/assets/images/can/.

  8. Comprueba

    Terminalen juicy
    yarn typecheck
    yarn dev

    Resultado esperado: yarn typecheck no informa de errores, y la lata nueva gira hasta su sitio con sus colores, su fruta y su texto.

    ¿Tienes problemas?

Cuando sustituyas el primer sabor, Lemon Ginger, cambia también DEFAULT_JUICE_ID al final de themes.ts, y el background de body en src/app/globals.css a su mainBgColor. Ese color se ve un instante antes de que la página termine de cargar.

Colores

Cada sabor tiene un tema en src/features/product-showcase/constants/themes.ts. La página pasa suavemente de un tema al siguiente mientras gira la rueda.

CampoQué pinta
mainBgColorEl fondo de la página, los botones de tamaño no seleccionados y los botones de los paneles del carrito, de la cuenta y de contacto
blurColorEl brillo suave detrás de la lata
buttonBgColorEl relleno del botón See More y del tamaño seleccionado
buttonTextColorEl texto del botón See More

textColor y accentColor forman parte de cada tema, pero ningún componente los lee. El texto de la página es blanco.

Mientras la página funciona, useBodyBackground en src/features/landing/hooks/ pinta el fondo de la página con el mainBgColor del sabor activo. El fondo de body en src/app/globals.css, #82AF38, solo se ve un momento antes de que cargue la página, así que cámbialo junto con el primer sabor.

La luz que reflejan las latas viene de public/assets/hdri/forest_slope_1k.hdr, la imagen Forest Slope de Poly Haven (CC0). Para cambiarla, pon otro archivo .hdr en esa carpeta e indica su nombre en src/features/carousel/constants/environment.ts.

Imágenes

Sustituye un archivo por el tuyo con el mismo nombre, o cambia el nombre donde indica la tabla.

ImagenArchivoNombrada en
Frutaspublic/assets/images/fruit/*.pngsrc/features/floating-fruits/constants/fruitImages.ts
Cubito de hielopublic/assets/images/ice/cube.webpsrc/features/ice-cubes/utils/getImagePath.ts
Hojaspublic/assets/images/leaf/1.png, 2.pngsrc/features/ice-cubes/utils/getImagePath.ts
Onda de aguapublic/assets/images/drop.pngsrc/features/landing/constants/stage.ts
Latas del carritopublic/assets/images/can/*.webpsrc/features/navigation/constants/sampleCartItems.ts

El número de cubitos de hielo y de hojas, en móviles y en pantallas más grandes, se define en src/features/ice-cubes/constants/layout.ts.

Fuentes

  • Thunder, la palabra gigante: sus archivos están en src/app/fonts/ y src/app/[locale]/layout.tsx los carga con localFont. Para usar otra fuente, pon sus archivos ahí y cambia las rutas src.
  • Cairo, el texto en árabe: se carga desde Google Fonts en el mismo archivo con next/font/google. Sustituye Cairo por otra fuente de Google que tenga el subconjunto arabic.
  • El texto latino usa Arial, definida en body en src/app/globals.css.

Partes de la página

La página es un solo archivo, src/app/[locale]/page.tsx, que coloca cada parte. Para quitar una, borra su elemento ahí.

ElementoQué es
<IceCubes>Los cubitos de hielo y las hojas a los lados
<NavBar>La barra de menú, con el cambio de idioma, la cuenta y el carrito
<WaterWaveStage>La onda de agua bajo el puntero, alrededor de todo lo demás
<ProductLogo>La palabra gigante detrás de las latas
<JuiceCarousel>La rueda 3D, sus flechas y las frutas flotantes
<SizeSelector>Los botones redondos de tamaño
<ProductInfo>El título del sabor, su texto y el botón See More
<ScrollDownButton>El botón redondo de abajo que abre el menú de contacto

Los enlaces del menú de contacto están en src/features/product-showcase/constants/contactLinks.ts. Cada uno tiene un id, una url y un icon de react-icons, y su etiqueta está en contact.links.<id> en los archivos de mensajes. Sustituye los dos enlaces de ejemplo por los tuyos.

src/features/product-showcase/constants/contactLinks.ts
import { FaInstagram } from "react-icons/fa6";

{ id: "instagram", url: "https://www.instagram.com/your-brand", icon: FaInstagram },
  • Los elementos del menú se listan por id en src/features/navigation/constants/navItems.ts, con sus etiquetas en nav.items. Por ahora son solo etiquetas y no llevan a ningún sitio: para enlazar uno, renderiza un <a> con tu dirección en src/features/navigation/components/NavLinks.tsx.
  • See More, Checkout y View Cart todavía no tienen acción. Añade un onClick o conviértelos en enlaces donde se dibujan: src/features/product-showcase/components/ProductInfo.tsx y src/features/navigation/components/CartSummary.tsx.
  • El formulario de inicio de sesión valida sus campos y luego los vacía. Para iniciar la sesión de los usuarios, envía los valores desde onSubmit en src/features/navigation/hooks/useSignInForm.ts a tu propio back-end.

Tamaños de botella

Los botones redondos de tamaño vienen de src/features/product-showcase/constants/sizes.ts. Al pulsar uno, queda seleccionado; selected: true marca el que está elegido al abrir la página. La etiqueta de la unidad está en units en los archivos de mensajes.

src/features/product-showcase/constants/sizes.ts
{ value: "355", unit: "ml", selected: true },

Título de la página, descripción y buscadores

El título de la pestaña del navegador y la descripción que muestran los buscadores son metadata.title y metadata.description en cada archivo de mensajes, así que cada idioma tiene los suyos. El icono de la pestaña es src/app/favicon.ico: sustitúyelo por el tuyo con el mismo nombre.

La plantilla no define dirección del sitio, imagen para compartir en redes, sitemap ni robots.txt. Cuando sepas tu dominio, añádelos en generateMetadata en src/app/[locale]/layout.tsx, por ejemplo:

src/app/[locale]/layout.tsx
return {
  metadataBase: new URL("https://www.your-domain.com"),
  title: t("title"),
  description: t("description"),
  openGraph: { images: "/og.png" },
};

Pon la imagen para compartir en public/og.png, de 1200 por 630 píxeles.

¿Te atascaste en un paso?

Busca una solución antes de empezar de nuevo.

Solución de problemas

Preferencias de Cookies

Utilizamos cookies para mejorar tu experiencia de navegación, analizar el tráfico del sitio y personalizar el contenido. Al hacer clic en "Aceptar Todo", consientes nuestro uso de cookies para análisis y publicidad personalizada.