| <!DOCTYPE html> |
| <html lang="vi"> |
| <head> |
| <meta charset="UTF-8" /> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
| <meta |
| name="description" |
| content="ANIVIETDB — Vương Tầm Thế Giới. Một trang web, vô vàn thế giới nội dung anime, manga, light novel." |
| /> |
| <meta name="theme-color" content="#151515" /> |
| <link |
| rel="icon" |
| href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><rect width='100' height='100' rx='22' fill='%23151515'/><text x='50' y='68' font-size='52' font-family='Arial' font-weight='bold' fill='%23ff5e00' text-anchor='middle'>A</text></svg>" |
| /> |
| <link rel="preconnect" href="https://fonts.googleapis.com" /> |
| <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> |
| <link |
| href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&family=Space+Grotesk:wght@400;500;600;700&display=swap" |
| rel="stylesheet" |
| /> |
| <link |
| href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" |
| rel="stylesheet" |
| /> |
| <title>ANIVIETDB · Vươn Tầm Thế Giới</title> |
| <style> |
| :root { |
| --cr-bg: #151515; |
| --cr-ink: #ffffff; |
| --cr-muted: #8c8c8c; |
| --cr-subtle: #bbbbbb; |
| --cr-border: #2a2a2a; |
| --cr-orange: #ff5e00; |
| --cr-orange-hover: #ff7a2a; |
| --cr-accent: #2abdbb; |
| } |
| html, |
| body { |
| height: 100%; |
| overflow-x: hidden; |
| } |
| body { |
| background: var(--cr-bg); |
| color: var(--cr-ink); |
| font-family: "Inter", system-ui, -apple-system, sans-serif; |
| -webkit-font-smoothing: antialiased; |
| } |
| #bg3d { |
| position: fixed; |
| inset: 0; |
| z-index: 0; |
| pointer-events: none; |
| } |
| |
| |
| .cr-hero { |
| position: relative; |
| z-index: 1; |
| min-height: 100vh; |
| display: flex; |
| flex-direction: column; |
| justify-content: center; |
| padding: 6.5rem 0 8rem; |
| background: var(--cr-bg); |
| } |
| |
| .cr-wall { |
| position: absolute; |
| inset: 0; |
| z-index: 0; |
| overflow: hidden; |
| will-change: transform; |
| } |
| .cr-grid { |
| position: absolute; |
| inset: -8px; |
| display: grid; |
| grid-template-columns: repeat(8, 1fr); |
| grid-template-rows: repeat(3, 1fr); |
| gap: 2px; |
| } |
| .cr-cell { |
| overflow: hidden; |
| } |
| .cr-cell img { |
| display: block; |
| width: 100%; |
| height: 100%; |
| object-fit: cover; |
| filter: brightness(0.42) saturate(0.65); |
| opacity: 0.9; |
| } |
| .cr-wall::after { |
| content: ""; |
| position: absolute; |
| inset: 0; |
| background: |
| linear-gradient(180deg, rgba(21, 21, 21, 0.2), rgba(21, 21, 21, 0.72) 68%, #151515 100%), |
| radial-gradient(120% 90% at 50% 0%, rgba(21, 21, 21, 0) 42%, rgba(21, 21, 21, 0.55) 100%); |
| } |
| |
| .cr-hero-inner { |
| position: relative; |
| z-index: 2; |
| } |
| |
| .cr-badge { |
| display: inline-flex; |
| align-items: center; |
| gap: 0.5rem; |
| border-radius: 999px; |
| border: 1px solid rgba(255, 255, 255, 0.16); |
| background: rgba(255, 255, 255, 0.05); |
| backdrop-filter: blur(8px); |
| padding: 0.4rem 0.95rem; |
| font-size: 0.75rem; |
| font-weight: 500; |
| letter-spacing: 0.03em; |
| color: var(--cr-subtle); |
| } |
| .cr-badge .dot { |
| width: 6px; |
| height: 6px; |
| border-radius: 50%; |
| background: var(--cr-orange); |
| animation: cr-pulse 1.6s ease-in-out infinite; |
| } |
| @keyframes cr-pulse { |
| 0%, |
| 100% { |
| opacity: 1; |
| transform: scale(1); |
| } |
| 50% { |
| opacity: 0.45; |
| transform: scale(0.75); |
| } |
| } |
| |
| .cr-title { |
| font-family: "Space Grotesk", "Inter", sans-serif; |
| font-weight: 700; |
| letter-spacing: -0.025em; |
| font-size: clamp(2.7rem, 9vw, 6rem); |
| line-height: 1.02; |
| color: var(--cr-ink); |
| } |
| .cr-title .hero-letter { |
| display: inline-block; |
| will-change: transform; |
| } |
| .cr-title .grad { |
| background: linear-gradient(92deg, var(--cr-orange) 0%, #ff9a5a 45%, #f0abfc 100%); |
| -webkit-background-clip: text; |
| background-clip: text; |
| color: transparent; |
| } |
| |
| .cr-sub { |
| margin-top: 1.25rem; |
| max-width: 42rem; |
| font-size: 1.05rem; |
| line-height: 1.7; |
| color: var(--cr-muted); |
| } |
| |
| .cr-cta-row { |
| margin-top: 2.25rem; |
| display: flex; |
| flex-wrap: wrap; |
| gap: 0.9rem; |
| } |
| |
| .cr-marquee { |
| position: absolute; |
| inset-inline: 0; |
| bottom: 0; |
| z-index: 3; |
| border-top: 1px solid rgba(255, 255, 255, 0.08); |
| background: rgba(21, 21, 21, 0.55); |
| backdrop-filter: blur(12px); |
| padding: 0.95rem 0; |
| overflow: hidden; |
| } |
| .cr-marquee-track { |
| display: flex; |
| gap: 2.5rem; |
| white-space: nowrap; |
| animation: cr-marquee 30s linear infinite; |
| will-change: transform; |
| } |
| .cr-marquee-item { |
| display: inline-flex; |
| align-items: center; |
| gap: 2.5rem; |
| font-size: 0.85rem; |
| font-weight: 500; |
| letter-spacing: 0.04em; |
| color: var(--cr-muted); |
| } |
| .cr-marquee-item .sep { |
| width: 6px; |
| height: 6px; |
| border-radius: 50%; |
| background: var(--cr-orange); |
| opacity: 0.75; |
| } |
| @keyframes cr-marquee { |
| to { |
| transform: translateX(-50%); |
| } |
| } |
| |
| |
| .btn-cr { |
| display: inline-flex; |
| align-items: center; |
| justify-content: center; |
| gap: 0.5rem; |
| border-radius: 999px; |
| font-weight: 600; |
| font-size: 0.9375rem; |
| line-height: 1.5; |
| padding: 0.625rem 1.5rem; |
| border: 1px solid transparent; |
| cursor: pointer; |
| transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease, |
| box-shadow 0.2s ease, transform 0.2s ease; |
| text-decoration: none; |
| white-space: nowrap; |
| user-select: none; |
| } |
| .btn-cr:focus-visible { |
| outline: none; |
| box-shadow: 0 0 0 2px var(--cr-bg), 0 0 0 4px var(--cr-orange); |
| } |
| .btn-cr:disabled { |
| opacity: 0.5; |
| pointer-events: none; |
| } |
| .btn-cr:hover { |
| transform: translateY(-1px); |
| } |
| .btn-cr-default { |
| background: var(--cr-orange); |
| color: #000; |
| box-shadow: 0 10px 28px rgba(255, 94, 0, 0.32); |
| } |
| .btn-cr-default:hover { |
| background: var(--cr-orange-hover); |
| color: #000; |
| box-shadow: 0 12px 32px rgba(255, 94, 0, 0.42); |
| } |
| .btn-cr-outline { |
| border-color: rgba(255, 255, 255, 0.32); |
| color: var(--cr-ink); |
| background: transparent; |
| } |
| .btn-cr-outline:hover { |
| border-color: rgba(255, 255, 255, 0.9); |
| background: rgba(255, 255, 255, 0.07); |
| color: var(--cr-ink); |
| } |
| .btn-cr-lg { |
| height: 3rem; |
| padding-inline: 2.1rem; |
| font-size: 1rem; |
| border-radius: 999px; |
| } |
| |
| |
| .cr-features { |
| position: relative; |
| z-index: 1; |
| background: var(--cr-bg); |
| padding: 5.5rem 0 6rem; |
| } |
| .cr-features-head { |
| text-align: left; |
| margin-bottom: 2.5rem; |
| } |
| .cr-features-head h2 { |
| font-family: "Space Grotesk", sans-serif; |
| font-weight: 700; |
| font-size: clamp(1.8rem, 4vw, 2.8rem); |
| letter-spacing: -0.02em; |
| color: var(--cr-ink); |
| } |
| .cr-features-head h2 .grad { |
| background: linear-gradient(92deg, var(--cr-orange) 0%, #ff9a5a 60%, #f0abfc 100%); |
| -webkit-background-clip: text; |
| background-clip: text; |
| color: transparent; |
| } |
| .cr-features-head p { |
| margin-top: 0.6rem; |
| color: var(--cr-muted); |
| font-size: 0.95rem; |
| } |
| .cr-feature-row { |
| display: grid; |
| grid-template-columns: repeat(5, minmax(0, 1fr)); |
| gap: 1.25rem; |
| } |
| .cr-feature-box { |
| position: relative; |
| border-radius: 16px; |
| overflow: hidden; |
| aspect-ratio: 2 / 3; |
| background: #1e1e1e; |
| border: 1px solid rgba(255, 255, 255, 0.08); |
| cursor: pointer; |
| text-decoration: none; |
| display: flex; |
| flex-direction: column; |
| justify-content: flex-end; |
| will-change: transform; |
| transition: transform 0.25s ease, box-shadow 0.25s ease, border-color 0.25s ease; |
| } |
| .cr-feature-box:hover { |
| transform: translateY(-6px); |
| box-shadow: 0 18px 40px rgba(255, 94, 0, 0.2); |
| border-color: rgba(255, 94, 0, 0.45); |
| } |
| .cr-feature-box img { |
| position: absolute; |
| inset: 0; |
| width: 100%; |
| height: 100%; |
| object-fit: cover; |
| transition: transform 0.35s ease; |
| } |
| .cr-feature-box:hover img { |
| transform: scale(1.06); |
| } |
| .cr-feature-box .shade { |
| position: absolute; |
| inset: 0; |
| background: linear-gradient(to top, rgba(21, 21, 21, 0.95) 8%, rgba(21, 21, 21, 0.25) 55%, transparent); |
| } |
| .cr-feature-box .info { |
| position: relative; |
| padding: 1rem 0.9rem; |
| color: #fff; |
| } |
| .cr-feature-box .tag { |
| display: inline-block; |
| border-radius: 999px; |
| background: var(--cr-orange); |
| color: #000; |
| font-size: 0.6rem; |
| font-weight: 700; |
| letter-spacing: 0.04em; |
| padding: 0.18rem 0.55rem; |
| margin-bottom: 0.4rem; |
| } |
| .cr-feature-box .t { |
| font-family: "Space Grotesk", sans-serif; |
| font-weight: 600; |
| font-size: 1rem; |
| line-height: 1.25; |
| margin: 0; |
| } |
| .cr-feature-box .s { |
| color: rgba(255, 255, 255, 0.7); |
| font-size: 0.72rem; |
| margin-top: 0.2rem; |
| } |
| .cr-feature-box.fade-in { |
| opacity: 0; |
| transform: translateY(28px); |
| } |
| .cr-feature-box.fade-in.visible { |
| opacity: 1; |
| transform: translateY(0); |
| transition: opacity 0.6s ease, transform 0.6s ease, box-shadow 0.25s ease, |
| border-color 0.25s ease; |
| } |
| |
| |
| .cr-shop { |
| position: relative; |
| z-index: 1; |
| background: linear-gradient(180deg, var(--cr-bg) 0%, #171719 100%); |
| padding: 5.5rem 0 6rem; |
| } |
| .cr-shop-head { |
| text-align: center; |
| margin-bottom: 2.5rem; |
| } |
| .cr-shop-head h2 { |
| font-family: "Space Grotesk", sans-serif; |
| font-weight: 700; |
| font-size: clamp(1.8rem, 4vw, 2.8rem); |
| letter-spacing: -0.02em; |
| color: var(--cr-ink); |
| } |
| .cr-shop-head h2 .grad { |
| background: linear-gradient(92deg, var(--cr-orange) 0%, #ff9a5a 60%, #f0abfc 100%); |
| -webkit-background-clip: text; |
| background-clip: text; |
| color: transparent; |
| } |
| .cr-shop-head p { |
| margin-top: 0.6rem; |
| color: var(--cr-muted); |
| font-size: 0.95rem; |
| } |
| .cr-shop-row { |
| display: grid; |
| grid-template-columns: repeat(4, minmax(0, 1fr)); |
| gap: 1.25rem; |
| } |
| .cr-shop-card { |
| border-radius: 16px; |
| overflow: hidden; |
| background: #1d1d1f; |
| border: 1px solid rgba(255, 255, 255, 0.08); |
| text-decoration: none; |
| display: flex; |
| flex-direction: column; |
| transition: transform 0.25s ease, box-shadow 0.25s ease, border-color 0.25s ease; |
| cursor: pointer; |
| } |
| .cr-shop-card:hover { |
| transform: translateY(-6px); |
| box-shadow: 0 18px 40px rgba(255, 94, 0, 0.18); |
| border-color: rgba(255, 94, 0, 0.45); |
| } |
| .cr-shop-card .pic { |
| position: relative; |
| aspect-ratio: 1 / 1; |
| background: #141416; |
| overflow: hidden; |
| } |
| .cr-shop-card .pic img { |
| width: 100%; |
| height: 100%; |
| object-fit: cover; |
| transition: transform 0.35s ease; |
| } |
| .cr-shop-card:hover .pic img { |
| transform: scale(1.07); |
| } |
| .cr-shop-card .pic .cat { |
| position: absolute; |
| top: 0.6rem; |
| left: 0.6rem; |
| border-radius: 999px; |
| background: rgba(21, 21, 21, 0.75); |
| color: var(--cr-orange); |
| font-size: 0.62rem; |
| font-weight: 700; |
| letter-spacing: 0.04em; |
| padding: 0.2rem 0.6rem; |
| backdrop-filter: blur(4px); |
| } |
| .cr-shop-card .pic .price { |
| position: absolute; |
| bottom: 0.6rem; |
| right: 0.6rem; |
| border-radius: 10px; |
| background: var(--cr-orange); |
| color: #000; |
| font-weight: 800; |
| font-size: 0.8rem; |
| padding: 0.3rem 0.65rem; |
| } |
| .cr-shop-card .meta { |
| padding: 0.9rem 1rem 1.1rem; |
| } |
| .cr-shop-card .meta .t { |
| font-family: "Space Grotesk", sans-serif; |
| font-weight: 600; |
| font-size: 0.95rem; |
| color: #fff; |
| margin: 0 0 0.15rem; |
| } |
| .cr-shop-card .meta .s { |
| color: var(--cr-muted); |
| font-size: 0.75rem; |
| } |
| .cr-shop-card.fade-in { |
| opacity: 0; |
| transform: translateY(28px); |
| } |
| .cr-shop-card.fade-in.visible { |
| opacity: 1; |
| transform: translateY(0); |
| transition: opacity 0.6s ease, transform 0.6s ease, box-shadow 0.25s ease, |
| border-color 0.25s ease; |
| } |
| .cr-shop-cta { |
| margin-top: 2.75rem; |
| text-align: center; |
| } |
| |
| |
| .cr-footer { |
| position: relative; |
| z-index: 1; |
| border-top: 1px solid rgba(255, 255, 255, 0.08); |
| background: var(--cr-bg); |
| padding: 3.25rem 1.5rem 3rem; |
| text-align: center; |
| } |
| .cr-footer p { |
| max-width: 46rem; |
| margin-inline: auto; |
| color: var(--cr-muted); |
| font-size: 0.85rem; |
| line-height: 1.7; |
| } |
| .cr-footer p + p { |
| margin-top: 0.35rem; |
| color: var(--cr-subtle); |
| font-size: 0.8rem; |
| } |
| .cr-footer .brand { |
| font-family: "Space Grotesk", sans-serif; |
| font-weight: 700; |
| font-size: 1rem; |
| letter-spacing: 0.06em; |
| color: var(--cr-ink); |
| margin-bottom: 0.9rem; |
| } |
| .cr-footer .brand span { |
| color: var(--cr-orange); |
| } |
| |
| @media (max-width: 767.98px) { |
| .cr-hero { |
| padding-top: 5rem; |
| } |
| .cr-grid { |
| grid-template-columns: repeat(4, 1fr); |
| grid-template-rows: repeat(6, 1fr); |
| } |
| .cr-feature-row { |
| grid-template-columns: repeat(2, minmax(0, 1fr)); |
| gap: 0.9rem; |
| } |
| .cr-shop-row { |
| grid-template-columns: repeat(2, minmax(0, 1fr)); |
| gap: 0.9rem; |
| } |
| } |
| </style> |
| </head> |
| <body> |
| <div id="root"></div> |
|
|
| <script src="https://unpkg.com/react@18.3.1/umd/react.production.min.js"></script> |
| <script src="https://unpkg.com/react-dom@18.3.1/umd/react-dom.production.min.js"></script> |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script> |
| <script src="https://cdn.jsdelivr.net/npm/gsap@3.12.5/dist/gsap.min.js"></script> |
|
|
| <script> |
| (function () { |
| var React = window.React; |
| var ReactDOM = window.ReactDOM; |
| var e = React.createElement; |
| var useRef = React.useRef; |
| var useEffect = React.useEffect; |
| |
| var POSTERS = [ |
| "https://phim.nguonc.com/public/images/Film/76.jpg", |
| "https://phim.nguonc.com/public/images/Film/666.jpg", |
| "https://phim.nguonc.com/public/images/Film/77.jpg", |
| "https://phim.nguonc.com/public/images/Film/667.jpg", |
| "https://phim.nguonc.com/public/images/Film/259.jpg", |
| "https://phim.nguonc.com/public/images/Film/2738.jpg", |
| "https://phim.nguonc.com/public/images/Film/3485.jpg", |
| "https://phim.nguonc.com/public/images/Film/141438.jpg", |
| "https://phim.nguonc.com/public/images/Film/date-a-bullet-thumb.jpg", |
| "https://phim.nguonc.com/public/images/Film/3103.jpg", |
| "https://phim.nguonc.com/public/images/Post/5/aishiteru-game-wo-owarasetai.jpg", |
| "https://phim.nguonc.com/public/images/Film/541.jpg", |
| "https://phim.nguonc.com/public/images/Film/536.jpg", |
| "https://phim.nguonc.com/public/images/Film/56167.jpg", |
| "https://phim.nguonc.com/public/images/Film/56643.jpg", |
| "https://phim.nguonc.com/public/images/Film/538.jpg", |
| "https://phim.nguonc.com/public/images/Film/540.jpg", |
| "https://phim.nguonc.com/public/images/Film/60351.jpg", |
| "https://phim.nguonc.com/public/images/Film/2607.jpg", |
| "https://phim.nguonc.com/public/images/Film/2661.jpg", |
| "https://phim.nguonc.com/public/images/Film/5MgMCnslrxQfOfaq6T5ndkLlcCk.jpg", |
| "https://phim.nguonc.com/public/images/Film/134808.jpg", |
| "https://phim.nguonc.com/public/images/Film/138379.jpg", |
| "https://phim.nguonc.com/public/images/Post/9/seishun-buta-yarou-wa-santa-claus-no-yume-wo-minai-1.jpg" |
| ]; |
| |
| var MARQUEE = [ |
| "Anime", |
| "Manga", |
| "Manhwa", |
| "Manhua", |
| "Light Novel", |
| "Sưu tầm", |
| "Vô vàn thế giới" |
| ]; |
| |
| var FEATURES = [ |
| { name: "Death Note", sub: "37 tập", tag: "Anime", page: "sfw/anime/universal/death-note/", img: "https://phim.nguonc.com/public/images/Film/244.jpg" }, |
| { name: "Tensei Slime", sub: "24 tập", tag: "Anime", page: "sfw/anime/universal/tensei-slime/phan-1/", img: "https://phim.nguonc.com/public/images/Film/2658.jpg" }, |
| { name: "JoJo Phần 1", sub: "26 tập", tag: "Anime", page: "sfw/anime/universal/jojo/phan-1/", img: "https://phim.nguonc.com/public/images/Film/40409.jpg" }, |
| { name: "Fate/Zero", sub: "13 tập", tag: "Anime", page: "sfw/anime/multiversal/fate/fate-zero/phan-1/", img: "https://phim.nguonc.com/public/images/Film/117644.jpg" }, |
| { name: "Bocchi the Rock!", sub: "12 tập", tag: "Anime", page: "sfw/anime/universal/bocchi-the-rock/phan-1/", img: "https://phim.nguonc.com/public/images/Film/127956.jpg" } |
| ]; |
| |
| var SHOP_PRODUCTS = [ |
| { name: "Figure Gojo Satoru", anime: "Jujutsu Kaisen", cat: "Figure", price: "1.290.000đ", img: "https://phim.nguonc.com/public/images/Film/76.jpg" }, |
| { name: "Figure Luffy Gear 5", anime: "One Piece", cat: "Figure", price: "1.450.000đ", img: "https://phim.nguonc.com/public/images/Film/666.jpg" }, |
| { name: "Plushie Anya Forger", anime: "Spy x Family", cat: "Plushie", price: "350.000đ", img: "https://phim.nguonc.com/public/images/Film/3485.jpg" }, |
| { name: "Mug Steins;Gate", anime: "Steins;Gate", cat: "Mug", price: "185.000đ", img: "https://phim.nguonc.com/public/images/Film/536.jpg" } |
| ]; |
| |
| function cx() { |
| return Array.prototype.filter.call(arguments, Boolean).join(" "); |
| } |
| |
| function Button(props) { |
| var className = cx( |
| "btn-cr", |
| "btn-cr-" + (props.variant || "default"), |
| (props.size || "default") === "lg" ? "btn-cr-lg" : "", |
| props.className |
| ); |
| var p = {}; |
| for (var k in props) { |
| if (k === "variant" || k === "size" || k === "className" || k === "children") continue; |
| p[k] = props[k]; |
| } |
| return e("button", Object.assign({}, p, { className: className }), props.children); |
| } |
| |
| function ThreeBackground() { |
| var ref = useRef(null); |
| useEffect(function () { |
| var canvas = ref.current; |
| var renderer = new THREE.WebGLRenderer({ |
| canvas: canvas, |
| alpha: true, |
| antialias: true |
| }); |
| renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2)); |
| var w = window.innerWidth; |
| var h = window.innerHeight; |
| var scene = new THREE.Scene(); |
| var camera = new THREE.PerspectiveCamera(70, w / h, 0.1, 40); |
| camera.position.z = 1; |
| |
| function onResize() { |
| w = window.innerWidth; |
| h = window.innerHeight; |
| renderer.setSize(w, h); |
| camera.aspect = w / h; |
| camera.updateProjectionMatrix(); |
| } |
| onResize(); |
| window.addEventListener("resize", onResize); |
| |
| var COUNT = 1400; |
| var positions = new Float32Array(COUNT * 3); |
| for (var i = 0; i < COUNT * 3; i++) positions[i] = (Math.random() - 0.5) * 4; |
| var geo = new THREE.BufferGeometry(); |
| geo.setAttribute("position", new THREE.BufferAttribute(positions, 3)); |
| var mat = new THREE.PointsMaterial({ |
| color: 0xffffff, |
| size: 0.004, |
| transparent: true, |
| opacity: 0.65, |
| sizeAttenuation: true |
| }); |
| var stars = new THREE.Points(geo, mat); |
| scene.add(stars); |
| |
| var glow = new THREE.Mesh( |
| new THREE.SphereGeometry(0.16, 32, 32), |
| new THREE.MeshBasicMaterial({ |
| color: 0xff5e00, |
| transparent: true, |
| opacity: 0.16 |
| }) |
| ); |
| glow.position.set(0.9, 0.55, -0.6); |
| scene.add(glow); |
| |
| var raf; |
| var mx = 0; |
| var my = 0; |
| function onMouse(e2) { |
| mx = (e2.clientX / w - 0.5) * 2; |
| my = (e2.clientY / h - 0.5) * 2; |
| } |
| window.addEventListener("mousemove", onMouse); |
| |
| function tick() { |
| stars.rotation.y += 0.00022; |
| stars.rotation.x += 0.00008; |
| camera.position.x += (mx * 0.05 - camera.position.x) * 0.04; |
| camera.position.y += (-my * 0.05 - camera.position.y) * 0.04; |
| camera.lookAt(0, 0, 0); |
| renderer.render(scene, camera); |
| raf = requestAnimationFrame(tick); |
| } |
| tick(); |
| |
| return function () { |
| cancelAnimationFrame(raf); |
| window.removeEventListener("resize", onResize); |
| window.removeEventListener("mousemove", onMouse); |
| renderer.dispose(); |
| }; |
| }, []); |
| return e("canvas", { id: "bg3d", ref: ref }); |
| } |
| |
| function Hero() { |
| var wallRef = useRef(null); |
| useEffect(function () { |
| var letters = gsap.utils.toArray(".hero-letter"); |
| var reveals = gsap.utils.toArray(".cr-reveal"); |
| gsap.set(letters, { yPercent: 115, opacity: 0 }); |
| gsap.set(reveals, { y: 26, opacity: 0 }); |
| var tl = gsap.timeline({ defaults: { ease: "power3.out" } }); |
| tl.to(letters, { yPercent: 0, opacity: 1, stagger: 0.05, duration: 0.85 }, 0.2) |
| .to(reveals, { y: 0, opacity: 1, stagger: 0.1, duration: 0.6 }, 0.6) |
| .fromTo( |
| wallRef.current, |
| { scale: 1.22 }, |
| { scale: 1.02, duration: 2.4, ease: "power2.out" }, |
| 0 |
| ); |
| return function () { |
| tl.kill(); |
| }; |
| }, []); |
| |
| var brand = "ANIVIETDB".split(""); |
| var heroLetters = brand.map(function (c, i) { |
| return e("span", { className: "hero-letter", key: i }, c); |
| }); |
| |
| return e( |
| "section", |
| { className: "cr-hero" }, |
| e( |
| "div", |
| { className: "cr-wall", ref: wallRef }, |
| e( |
| "div", |
| { className: "cr-grid" }, |
| POSTERS.map(function (u, i) { |
| return e( |
| "div", |
| { className: "cr-cell", key: i }, |
| e("img", { src: u, alt: "", loading: "lazy" }) |
| ); |
| }) |
| ) |
| ), |
| e( |
| "div", |
| { className: "cr-hero-inner container" }, |
| e( |
| "div", |
| { className: "row" }, |
| e( |
| "div", |
| { className: "col-12 col-lg-9 col-xl-8" }, |
| e( |
| "span", |
| { className: "cr-badge cr-reveal" }, |
| e("span", { className: "dot" }), |
| " Giới thiệu · Vươn Tầm Thế Giới" |
| ), |
| e( |
| "h1", |
| { className: "cr-title" }, |
| heroLetters, |
| e( |
| "span", |
| { className: "d-block" }, |
| e("span", { className: "grad" }, "Vươn Tầm Thế Giới") |
| ) |
| ), |
| e( |
| "p", |
| { className: "cr-sub cr-reveal" }, |
| "Nơi hội tụ anime, manga, webtoon và light novel — một trang web, vô vàn thế giới." |
| ), |
| e( |
| "div", |
| { className: "cr-cta-row cr-reveal" }, |
| e( |
| Button, |
| { size: "lg", onClick: function () { openSfwWithLoginCheck(); } }, |
| "Bắt đầu" |
| ), |
| e( |
| Button, |
| { |
| size: "lg", |
| variant: "outline", |
| onClick: function () { |
| var el = document.getElementById("featureStage"); |
| if (el) el.scrollIntoView({ behavior: "smooth" }); |
| } |
| }, |
| "Xem phim nổi bật" |
| ) |
| ) |
| ) |
| ) |
| ), |
| e( |
| "div", |
| { className: "cr-marquee" }, |
| e( |
| "div", |
| { className: "cr-marquee-track" }, |
| MARQUEE.concat(MARQUEE).map(function (w, i) { |
| return e( |
| "span", |
| { className: "cr-marquee-item", key: i }, |
| w, |
| e("span", { className: "sep" }) |
| ); |
| }) |
| ) |
| ) |
| ); |
| } |
| |
| function FeatureStage() { |
| var secRef = useRef(null); |
| useEffect(function () { |
| var boxes = secRef.current ? secRef.current.querySelectorAll(".cr-feature-box.fade-in") : []; |
| if (!("IntersectionObserver" in window)) { |
| Array.prototype.forEach.call(boxes, function (b) { b.classList.add("visible"); }); |
| return; |
| } |
| var io = new IntersectionObserver( |
| function (entries) { |
| entries.forEach(function (en) { |
| if (en.isIntersecting) { |
| en.target.classList.add("visible"); |
| io.unobserve(en.target); |
| } |
| }); |
| }, |
| { threshold: 0.15 } |
| ); |
| Array.prototype.forEach.call(boxes, function (b) { io.observe(b); }); |
| return function () { io.disconnect(); }; |
| }, []); |
| |
| return e( |
| "section", |
| { id: "featureStage", className: "cr-features", ref: secRef }, |
| e( |
| "div", |
| { className: "container" }, |
| e( |
| "div", |
| { className: "cr-features-head" }, |
| e("h2", null, "Phim nổi bật ", e("span", { className: "grad" }, "Feature")), |
| e( |
| "p", |
| null, |
| "Những tựa anime đáng xem nhất, cập nhật liên tục từ ANIVIETDB." |
| ) |
| ), |
| e( |
| "div", |
| { className: "cr-feature-row" }, |
| FEATURES.map(function (f, i) { |
| return e( |
| "a", |
| { |
| key: i, |
| href: f.page, |
| className: "cr-feature-box fade-in", |
| style: { transitionDelay: i * 0.08 + "s" } |
| }, |
| e("img", { src: f.img, alt: f.name, loading: "lazy" }), |
| e("div", { className: "shade" }), |
| e( |
| "div", |
| { className: "info" }, |
| e("span", { className: "tag" }, f.tag), |
| e("p", { className: "t" }, f.name), |
| e("p", { className: "s" }, f.sub) |
| ) |
| ); |
| }) |
| ) |
| ) |
| ); |
| } |
| |
| function openWithLoginCheck(url) { |
| function go() { window.location.href = url; } |
| function showPopup() { |
| var m = document.getElementById("loginReqPopup"); |
| m.classList.add("active"); |
| } |
| if (window.AuthSystem) { |
| window.AuthSystem.me().then(function (user) { |
| if (user) { go(); } else { showPopup(); } |
| }).catch(function () { showPopup(); }); |
| return; |
| } |
| var s = document.createElement("script"); |
| s.src = "signup-loginsystem.js"; |
| s.onload = function () { |
| if (window.AuthSystem) { |
| window.AuthSystem.me().then(function (user) { |
| if (user) { go(); } else { showPopup(); } |
| }).catch(function () { showPopup(); }); |
| } else { |
| showPopup(); |
| } |
| }; |
| s.onerror = function () { showPopup(); }; |
| document.head.appendChild(s); |
| } |
| function openShopWithLoginCheck() { openWithLoginCheck("shop/index.html"); } |
| function openSfwWithLoginCheck() { |
| function go() { window.location.href = "sfw/index.html"; } |
| function goLogin() { window.location.href = "login.html"; } |
| function check() { |
| window.AuthSystem.me().then(function (user) { |
| if (user) { go(); } else { goLogin(); } |
| }).catch(function () { goLogin(); }); |
| } |
| if (window.AuthSystem) { check(); return; } |
| var s = document.createElement("script"); |
| s.src = "signup-loginsystem.js"; |
| s.onload = function () { if (window.AuthSystem) { check(); } else { goLogin(); } }; |
| s.onerror = function () { goLogin(); }; |
| document.head.appendChild(s); |
| } |
| |
| function ShopStage() { |
| var secRef = useRef(null); |
| useEffect(function () { |
| var cards = secRef.current ? secRef.current.querySelectorAll(".cr-shop-card.fade-in") : []; |
| if (!("IntersectionObserver" in window)) { |
| Array.prototype.forEach.call(cards, function (b) { b.classList.add("visible"); }); |
| return; |
| } |
| var io = new IntersectionObserver( |
| function (entries) { |
| entries.forEach(function (en) { |
| if (en.isIntersecting) { |
| en.target.classList.add("visible"); |
| io.unobserve(en.target); |
| } |
| }); |
| }, |
| { threshold: 0.15 } |
| ); |
| Array.prototype.forEach.call(cards, function (b) { io.observe(b); }); |
| return function () { io.disconnect(); }; |
| }, []); |
| |
| return e( |
| "section", |
| { id: "shopStage", className: "cr-shop", ref: secRef }, |
| e( |
| "div", |
| { className: "container" }, |
| e( |
| "div", |
| { className: "cr-shop-head" }, |
| e("h2", null, "Figure Shop ", e("span", { className: "grad" }, "ANIVIETDB")), |
| e( |
| "p", |
| null, |
| "Figure, plushie, manga, Blu-ray và đồ lưu niệm sưu tầm — khám phá ngay, đặt mua tại cửa hàng." |
| ) |
| ), |
| e( |
| "div", |
| { className: "cr-shop-row" }, |
| SHOP_PRODUCTS.map(function (f, i) { |
| return e( |
| "a", |
| { |
| key: i, |
| href: "shop/index.html", |
| className: "cr-shop-card fade-in", |
| style: { transitionDelay: i * 0.08 + "s" } |
| }, |
| e( |
| "div", |
| { className: "pic" }, |
| e("span", { className: "cat" }, f.cat), |
| e("img", { src: f.img, alt: f.name, loading: "lazy" }), |
| e("span", { className: "price" }, f.price) |
| ), |
| e( |
| "div", |
| { className: "meta" }, |
| e("p", { className: "t" }, f.name), |
| e("p", { className: "s" }, f.anime) |
| ) |
| ); |
| }) |
| ), |
| e( |
| "div", |
| { className: "cr-shop-cta" }, |
| e( |
| Button, |
| { |
| size: "lg", |
| onClick: function () { openShopWithLoginCheck(); } |
| }, |
| "Khám phá shop" |
| ) |
| ) |
| ) |
| ); |
| } |
| |
| function Footer() { |
| return e( |
| "footer", |
| { className: "cr-footer" }, |
| e( |
| "p", |
| { className: "brand" }, |
| "ANIVIETDB ", |
| e("span", null, "·"), |
| " Vươn Tầm Thế Giới" |
| ), |
| e( |
| "p", |
| null, |
| "© 2026 ANIVIETDB. Tất cả nội dung Anime, Manga, Manhwa, Manhua và Light Novel được sưu tầm và thuộc bản quyền của chủ sở hữu tương ứng." |
| ), |
| e( |
| "p", |
| null, |
| "Trang web sưu tầm cá nhân - Phi thương mại. Mọi quyền được bảo lưu." |
| ) |
| ); |
| } |
| |
| function App() { |
| return e( |
| "main", |
| { className: "position-relative" }, |
| e(ThreeBackground), |
| e(Hero), |
| e(FeatureStage), |
| e(ShopStage), |
| e(Footer) |
| ); |
| } |
| |
| ReactDOM.createRoot(document.getElementById("root")).render(e(App)); |
| })(); |
| </script> |
|
|
| <div class="login-req-overlay" id="loginReqPopup"> |
| <div class="login-req-popup"> |
| <h3>🔒 Bạn chưa đăng nhập</h3> |
| <p>Hãy đăng nhập để khám phá cửa hàng ANIVIETDB và đặt mua sản phẩm.</p> |
| <div class="login-req-actions"> |
| <button class="login-req-btn" id="loginReqGo">Bắt đầu đăng nhập</button> |
| <button class="login-req-btn login-req-ghost" id="loginReqClose">Để sau</button> |
| </div> |
| </div> |
| </div> |
|
|
| <style> |
| .login-req-overlay { position: fixed; inset: 0; background: rgba(0,0,0,.7); display: none; align-items: center; justify-content: center; z-index: 10000; backdrop-filter: blur(4px); } |
| .login-req-overlay.active { display: flex; } |
| .login-req-popup { background: #1d1d1d; border: 1px solid var(--cr-border); border-radius: 16px; padding: 30px 36px; text-align: center; color: var(--cr-ink); font-family: "Inter", system-ui, sans-serif; max-width: 380px; box-shadow: 0 20px 60px rgba(0,0,0,.6); } |
| .login-req-popup h3 { margin: 0 0 10px; font-size: 20px; font-weight: 700; } |
| .login-req-popup p { margin: 0 0 22px; color: var(--cr-muted); font-size: 14px; line-height: 1.6; } |
| .login-req-actions { display: flex; flex-direction: column; gap: 10px; } |
| .login-req-btn { background: var(--cr-orange); color: #fff; border: none; padding: 12px 20px; border-radius: 10px; font-weight: 600; font-size: 15px; cursor: pointer; transition: background .15s; } |
| .login-req-btn:hover { background: var(--cr-orange-hover); } |
| .login-req-btn.login-req-ghost { background: none; color: var(--cr-muted); border: 1px solid var(--cr-border); } |
| .login-req-btn.login-req-ghost:hover { color: #fff; border-color: #555; } |
| </style> |
|
|
| <script> |
| (function () { |
| var overlay = document.getElementById("loginReqPopup"); |
| var goBtn = document.getElementById("loginReqGo"); |
| var closeBtn = document.getElementById("loginReqClose"); |
| if (goBtn) goBtn.addEventListener("click", function () { |
| window.location.href = "login.html"; |
| }); |
| if (closeBtn) closeBtn.addEventListener("click", function () { |
| overlay.classList.remove("active"); |
| }); |
| if (overlay) overlay.addEventListener("click", function (e) { |
| if (e.target === overlay) overlay.classList.remove("active"); |
| }); |
| })(); |
| </script> |
| </body> |
| </html> |