Anime News Public
PHP
Actualizado Aug 24, 2025
Archivos de Código
anime_news.php
931 líneas
<?php
function getRssFeed($url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_TIMEOUT, 10); // Añadido timeout para evitar esperas largas
$data = curl_exec($ch);
curl_close($ch);
return $data;
}
function imageToBase64($url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_TIMEOUT, 10); // Añadido timeout para evitar esperas largas
$imageData = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
// Verificar si la imagen se descargó correctamente
if ($imageData !== false && $httpCode == 200) {
// Intentar obtener el tipo MIME
$finfo = new finfo(FILEINFO_MIME_TYPE);
$mimeType = $finfo->buffer($imageData);
if (!$mimeType) {
// Si no se puede determinar, intentar con getimagesizefromstring
$imgInfo = @getimagesizefromstring($imageData);
$mimeType = $imgInfo['mime'] ?? 'image/jpeg'; // Valor predeterminado si falla
}
$base64 = base64_encode($imageData);
return "data:$mimeType;base64,$base64";
}
// Imagen de respaldo en base64 (una imagen pequeña de "no disponible")
return 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMDAiIGhlaWdodD0iMTUwIiB2aWV3Qm94PSIwIDAgMjAwIDE1MCIgZmlsbD0ibm9uZSI+PHJlY3Qgd2lkdGg9IjIwMCIgaGVpZ2h0PSIxNTAiIGZpbGw9IiMzMzMiLz48dGV4dCB4PSIzMCIgeT0iODAiIGZvbnQtZmFtaWx5PSJBcmlhbCIgZm9udC1zaXplPSIxNiIgZmlsbD0iI2ZmZiI+SW1hZ2VuIG5vIGRpc3BvbmlibGU8L3RleHQ+PC9zdmc+';
}
// Limitar la descripción a un número específico de caracteres
function limitarDescripcion($texto, $limite = 150) {
$texto = strip_tags($texto); // Eliminar etiquetas HTML
if (strlen($texto) > $limite) {
$texto = substr($texto, 0, $limite) . '...';
}
return $texto;
}
$rss_url = "https://ramenparados.com/category/noticias/anime/feed/";
$rss_content = getRssFeed($rss_url);
$noticias = [];
$max_noticias = 9; // Limitar a 9 noticias para mejor rendimiento en Discord
if ($rss_content !== false) {
$rss = @simplexml_load_string($rss_content);
if ($rss) {
$contador = 0;
foreach ($rss->channel->item as $item) {
if ($contador >= $max_noticias) break; // Limitar cantidad de noticias
// Buscar imagen en la descripción
preg_match('/<img.*?src=["\'](.*?)["\']/i', $item->description, $matches);
$imagenUrl = $matches[1] ?? 'https://via.placeholder.com/800x400?text=No+Image';
// Convertir la imagen a Base64
$imagenBase64 = imageToBase64($imagenUrl);
// Limpiar y limitar la descripción
$descripcion_limpia = limitarDescripcion((string)$item->description, 120);
// Formatear la fecha
$fecha = date("d/m/Y", strtotime($item->pubDate));
$noticias[] = [
'titulo' => (string) $item->title,
'link' => (string) $item->link,
'descripcion' => $descripcion_limpia,
'fecha' => $fecha,
'imagen' => $imagenBase64
];
$contador++;
}
}
}
?>
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Noticias de Anime</title>
<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=Poppins:wght@300;400;500;600;700&display=swap" rel="stylesheet">
<style>
:root {
--bg-primary: #1a1a1a;
--bg-secondary: #2c2c2c;
--bg-card: #2c2c2c;
--text-primary: #ffffff;
--text-secondary: #b3b3b3;
--accent-primary: #ff6b9d; /* Rosa principal */
--accent-secondary: #d44a87; /* Rosa oscuro */
--accent-hover: #ff8fb1; /* Rosa claro */
--border-radius: 12px;
--card-shadow: 0 8px 16px rgba(0, 0, 0, 0.4);
--transition-speed: 0.3s;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html {
height: 100%;
overflow-x: hidden;
scroll-behavior: smooth;
}
body {
font-family: 'Poppins', 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background-color: var(--bg-primary);
color: var(--text-primary);
line-height: 1.6;
min-height: 100%;
position: relative;
perspective: 1000px;
overflow-x: hidden;
}
body::before {
content: '';
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: radial-gradient(circle at top right, rgba(255, 107, 157, 0.1), transparent 60%),
radial-gradient(circle at bottom left, rgba(212, 74, 135, 0.1), transparent 60%);
z-index: -1;
pointer-events: none;
}
/* Pantalla de carga */
#loadingScreen {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: var(--bg-primary);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
z-index: 9999;
transition: opacity 0.5s ease-out, visibility 0.5s ease-out;
}
.loading-container {
text-align: center;
position: relative;
}
.loading-text {
font-size: 1.5rem;
font-weight: 600;
margin-top: 2rem;
background: linear-gradient(90deg, var(--text-primary), var(--accent-primary));
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
animation: pulse 1.5s infinite;
}
@keyframes pulse {
0% { opacity: 0.6; }
50% { opacity: 1; }
100% { opacity: 0.6; }
}
.loading-spinner {
width: 120px;
height: 120px;
position: relative;
}
.loading-spinner::before,
.loading-spinner::after {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border-radius: 50%;
border: 5px solid transparent;
border-top-color: var(--accent-primary);
animation: spin 1.5s linear infinite;
}
.loading-spinner::before {
border-top-color: var(--accent-primary);
z-index: 100;
}
.loading-spinner::after {
border-top-color: var(--accent-secondary);
border-right-color: var(--accent-secondary);
animation-duration: 2s;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.loading-anime-icon {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 60px;
height: 60px;
animation: float 3s ease-in-out infinite;
}
@keyframes float {
0% { transform: translate(-50%, -50%); }
50% { transform: translate(-50%, -60%); }
100% { transform: translate(-50%, -50%); }
}
.loading-progress {
width: 200px;
height: 6px;
background-color: var(--bg-secondary);
border-radius: 3px;
margin-top: 1.5rem;
overflow: hidden;
position: relative;
}
.loading-progress-bar {
height: 100%;
background: linear-gradient(90deg, var(--accent-primary), var(--accent-secondary));
width: 0%;
border-radius: 3px;
transition: width 0.3s ease-out;
}
.loading-tips {
margin-top: 1.5rem;
color: var(--text-secondary);
font-size: 0.9rem;
max-width: 300px;
text-align: center;
}
/* Contenido principal (oculto durante la carga) */
#mainContent {
opacity: 0;
transition: opacity 0.5s ease-out;
display: none;
}
#mainContent.visible {
opacity: 1;
display: block;
}
header {
background-color: var(--bg-secondary);
padding: 2rem 0;
text-align: center;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
position: relative;
overflow: hidden;
transform-style: preserve-3d;
transform: translateZ(0);
}
header::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(135deg, rgba(255, 107, 157, 0.2), rgba(212, 74, 135, 0.2));
z-index: -1;
}
h1 {
margin: 0;
font-size: 2.5rem;
font-weight: 700;
background: linear-gradient(90deg, var(--text-primary), var(--accent-primary));
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
text-transform: uppercase;
letter-spacing: 3px;
position: relative;
display: inline-block;
transform-style: preserve-3d;
transform: translateZ(20px);
text-shadow: 0 10px 20px rgba(0, 0, 0, 0.2);
}
h1::after {
content: '';
position: absolute;
bottom: -10px;
left: 50%;
transform: translateX(-50%);
width: 100px;
height: 4px;
background: linear-gradient(90deg, var(--accent-primary), var(--accent-secondary));
border-radius: 2px;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 2rem;
transform-style: preserve-3d;
}
.noticias-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 2rem;
perspective: 1000px;
}
.noticia {
background-color: var(--bg-card);
border-radius: var(--border-radius);
overflow: hidden;
box-shadow: var(--card-shadow);
transition: transform 0.5s ease, box-shadow 0.5s ease;
position: relative;
transform-style: preserve-3d;
opacity: 0;
transform: translateY(50px) rotateX(10deg);
animation: card-appear 0.6s forwards;
animation-play-state: paused;
cursor: default;
}
@keyframes card-appear {
0% {
opacity: 0;
transform: translateY(50px) rotateX(10deg);
}
100% {
opacity: 1;
transform: translateY(0) rotateX(0);
}
}
.noticia::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 4px;
background: linear-gradient(90deg, var(--accent-primary), var(--accent-secondary));
z-index: 1;
transform: translateZ(10px);
}
.noticia-image-container {
position: relative;
overflow: hidden;
height: 200px;
transform-style: preserve-3d;
}
.noticia img {
width: 100%;
height: 100%;
object-fit: cover;
transition: transform 0.5s ease;
transform-style: preserve-3d;
transform: translateZ(5px);
}
.noticia:hover img {
transform: translateZ(5px) scale(1.1);
}
.noticia-content {
padding: 1.5rem;
transform-style: preserve-3d;
position: relative;
z-index: 2;
}
.noticia h2 {
font-size: 1.3rem;
margin: 0 0 0.8rem 0;
font-weight: 600;
transform: translateZ(15px);
transition: transform 0.3s ease;
}
.noticia:hover h2 {
transform: translateZ(25px);
}
.noticia h2 a {
color: var(--accent-primary);
text-decoration: none;
transition: color var(--transition-speed) ease;
}
.noticia h2 a:hover {
color: var(--accent-hover);
}
.noticia p {
color: var(--text-secondary);
font-size: 0.95rem;
margin-bottom: 1.2rem;
transform: translateZ(10px);
transition: transform 0.3s ease;
}
.noticia:hover p {
transform: translateZ(20px);
}
.noticia .fecha {
font-size: 0.8rem;
color: #888;
margin-bottom: 0.8rem;
display: flex;
align-items: center;
transform: translateZ(5px);
}
.noticia .fecha::before {
content: '📅';
margin-right: 0.5rem;
}
/* Modificado para Discord - Mostrar el enlace como texto */
.noticia .link-info {
font-size: 0.8rem;
color: var(--accent-primary);
margin-top: 0.5rem;
display: block;
word-break: break-all;
}
/* Botón adaptado para Discord */
.noticia .btn-container {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 1rem;
}
.noticia a.btn {
display: inline-block;
padding: 0.6rem 1.2rem;
background: linear-gradient(135deg, var(--accent-primary), var(--accent-secondary));
color: white;
text-decoration: none;
border-radius: 30px;
font-weight: 500;
transition: all var(--transition-speed);
box-shadow: 0 4px 10px rgba(255, 107, 157, 0.3);
position: relative;
overflow: hidden;
z-index: 1;
transform: translateZ(20px);
}
.noticia a.btn::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
transition: left 0.7s;
z-index: -1;
}
.noticia a.btn:hover::before {
left: 100%;
}
.noticia a.btn:hover {
background: linear-gradient(135deg, var(--accent-hover), var(--accent-primary));
transform: translateZ(30px) translateY(-2px);
box-shadow: 0 6px 15px rgba(255, 107, 157, 0.4);
}
/* Efecto de brillo 3D en las tarjetas */
.noticia::after {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(135deg,
rgba(255, 255, 255, 0.05) 0%,
rgba(255, 255, 255, 0) 60%);
pointer-events: none;
z-index: 2;
opacity: 0;
transition: opacity 0.3s ease;
}
.noticia:hover::after {
opacity: 1;
}
/* Anime-themed particles */
#anime-particles {
position: fixed;
width: 100%;
height: 100%;
top: 0;
left: 0;
z-index: -1;
pointer-events: none;
}
.sakura, .star, .anime-icon {
position: absolute;
pointer-events: none;
opacity: 0;
animation: float-particle 15s linear infinite;
}
.sakura {
width: 20px;
height: 20px;
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="%23ff6b9d"><path d="M12 2C7.58 2 4 5.58 4 10c0 2.03.76 3.87 2 5.28V16c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2v-.72c1.24-1.41 2-3.25 2-5.28 0-4.42-3.58-8-8-8zm-4 12.28c-.6.35-1.1.78-1.5 1.27-.4-.49-.9-.92-1.5-1.27.6-.35 1.1-.78 1.5-1.27.4.49.9.92 1.5 1.27zm4 0c-.6.35-1.1.78-1.5 1.27-.4-.49-.9-.92-1.5-1.27.6-.35 1.1-.78 1.5-1.27.4.49.9.92 1.5 1.27zm4 0c-.6.35-1.1.78-1.5 1.27-.4-.49-.9-.92-1.5-1.27.6-.35 1.1-.78 1.5-1.27.4.49.9.92 1.5 1.27z"/></svg>');
background-size: contain;
background-repeat: no-repeat;
}
.star {
width: 15px;
height: 15px;
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="%23ffffff"><path d="M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z"/></svg>');
background-size: contain;
background-repeat: no-repeat;
}
.anime-icon {
width: 25px;
height: 25px;
background-size: contain;
background-repeat: no-repeat;
}
.anime-icon.katana {
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="%23ff6b9d"><path d="M21.5 2v2h-19l-.5 1 17 17 1-.5v-19h2l-1-1z"/></svg>');
}
.anime-icon.shuriken {
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="%23ff6b9d"><path d="M12 2l2 5h5l-4 4 4 4h-5l-2 5-2-5H5l4-4-4-4h5z"/></svg>');
}
@keyframes float-particle {
0% {
opacity: 0;
transform: translateY(-100%) rotate(0deg);
}
10% {
opacity: 0.7;
}
90% {
opacity: 0.7;
}
100% {
opacity: 0;
transform: translateY(100vh) rotate(360deg);
}
}
/* Mensaje de no hay noticias */
.no-noticias {
text-align: center;
padding: 3rem;
background-color: var(--bg-card);
border-radius: var(--border-radius);
box-shadow: var(--card-shadow);
animation: fadeIn 0.5s ease-out;
position: relative;
overflow: hidden;
}
.no-noticias::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 4px;
background: linear-gradient(90deg, var(--accent-primary), var(--accent-secondary));
}
.no-noticias p {
font-size: 1.2rem;
color: var(--text-secondary);
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
@media (max-width: 768px) {
.noticias-grid {
grid-template-columns: 1fr;
}
h1 {
font-size: 2rem;
}
.container {
padding: 1rem;
}
.loading-text {
font-size: 1.2rem;
}
.loading-spinner {
width: 100px;
height: 100px;
}
.loading-anime-icon {
width: 50px;
height: 50px;
}
.loading-progress {
width: 180px;
}
}
</style>
</head>
<body>
<!-- Pantalla de carga -->
<div id="loadingScreen">
<div class="loading-container">
<div class="loading-spinner">
<img src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHZpZXdCb3g9JzAgMCAyNCAyNCcgZmlsbD0nI2ZmNmI5ZCc+PHBhdGggZD0nTTEyIDJsMiA1aDVsLTQgNCA0IDRoLTVsLTIgNS0yLTVINWw0LTQtNC00aDV6Jy8+PC9zdmc+" class="loading-anime-icon" alt="Loading">
</div>
<div class="loading-text">Cargando noticias de anime...</div>
<div class="loading-progress">
<div class="loading-progress-bar" id="progressBar"></div>
</div>
<div class="loading-tips" id="loadingTip">
¿Sabías que? El anime más largo de la historia es Sazae-san, con más de 7,500 episodios desde 1969.
</div>
</div>
</div>
<!-- Contenido principal (inicialmente oculto) -->
<div id="mainContent">
<div id="anime-particles"></div>
<header>
<h1>Noticias de Anime</h1>
</header>
<div class="container">
<div class="noticias-grid" id="noticiasGrid">
<?php if (!empty($noticias)): ?>
<?php foreach ($noticias as $index => $noticia): ?>
<div class="noticia" style="animation-delay: <?php echo ($index * 0.15); ?>s;">
<div class="noticia-image-container">
<img src="<?php echo $noticia['imagen']; ?>" alt="Imagen de noticia">
</div>
<div class="noticia-content">
<h2>
<?php echo htmlspecialchars($noticia['titulo']); ?>
</h2>
<p class="fecha">Publicado el <?php echo $noticia['fecha']; ?></p>
<p><?php echo htmlspecialchars($noticia['descripcion']); ?></p>
<!-- Contenedor para botón y enlace (adaptado para Discord) -->
<div class="btn-container">
<a class="btn" href="<?php echo htmlspecialchars($noticia['link']); ?>" target="_blank">Leer más</a>
</div>
<span class="link-info">Enlace: <?php echo htmlspecialchars($noticia['link']); ?></span>
</div>
</div>
<?php endforeach; ?>
<?php else: ?>
<div class="no-noticias">
<p>No se encontraron noticias en este momento.</p>
</div>
<?php endif; ?>
</div>
</div>
</div>
<script>
// Prevenir scroll durante la carga
document.body.style.overflow = 'hidden';
// Datos para los consejos de carga
const animeTips = [
"¿Sabías que? El anime más largo de la historia es Sazae-san, con más de 7,500 episodios desde 1969.",
"El término 'anime' proviene de la abreviación japonesa de 'animation'.",
"Studio Ghibli ha ganado un Oscar por 'El viaje de Chihiro' en 2003.",
"Pokémon es la franquicia de medios más rentable de todos los tiempos.",
"Naruto realizó 'la carrera Naruto' mucho antes de que se convirtiera en un meme.",
"One Piece tiene el récord Guinness por 'mayor número de copias publicadas para una serie de cómics por un solo autor'.",
"La primera serie de anime en color fue Astro Boy en 1963.",
"Dragon Ball Z ha sido doblado en más de 30 idiomas diferentes.",
"Hayao Miyazaki ha salido de su retiro varias veces para crear nuevas películas."
];
// Simulación de carga
document.addEventListener('DOMContentLoaded', function() {
const loadingScreen = document.getElementById('loadingScreen');
const mainContent = document.getElementById('mainContent');
const progressBar = document.getElementById('progressBar');
const loadingTip = document.getElementById('loadingTip');
const noticias = document.querySelectorAll('.noticia');
// Cambiar consejos aleatoriamente durante la carga
let tipIndex = 0;
const tipInterval = setInterval(() => {
tipIndex = (tipIndex + 1) % animeTips.length;
loadingTip.style.opacity = 0;
setTimeout(() => {
loadingTip.textContent = animeTips[tipIndex];
loadingTip.style.opacity = 1;
}, 200);
}, 3000);
// Simular progreso de carga de manera más suave para evitar problemas
let progress = 0;
const loadingInterval = setInterval(() => {
progress += Math.random() * 10; // Incremento más pequeño para evitar saltos bruscos
if (progress > 100) progress = 100;
progressBar.style.width = `${progress}%`;
if (progress === 100) {
clearInterval(loadingInterval);
clearInterval(tipInterval);
// Mostrar contenido principal y ocultar pantalla de carga
setTimeout(() => {
loadingScreen.style.opacity = '0';
setTimeout(() => {
loadingScreen.style.display = 'none';
mainContent.style.display = 'block';
// Pequeño retraso para asegurar que el DOM se actualice
setTimeout(() => {
mainContent.classList.add('visible');
// Permitir scroll después de la carga
document.body.style.overflow = '';
// Activar animaciones de las tarjetas
noticias.forEach(noticia => {
noticia.style.animationPlayState = 'running';
});
// Iniciar partículas después de la carga
createAnimeParticles();
// Inicializar efecto 3D en tarjetas
initCardTiltEffect();
}, 50);
}, 500);
}, 300);
}
}, 200);
});
// Efecto de inclinación 3D para las tarjetas
function initCardTiltEffect() {
const cards = document.querySelectorAll('.noticia');
cards.forEach(card => {
card.addEventListener('mousemove', handleCardTilt);
card.addEventListener('mouseleave', resetCardTilt);
});
}
function handleCardTilt(e) {
const card = this;
const rect = card.getBoundingClientRect();
const x = e.clientX - rect.left; // Posición X del mouse dentro de la tarjeta
const y = e.clientY - rect.top; // Posición Y del mouse dentro de la tarjeta
// Calcular la posición relativa (0-1) dentro de la tarjeta
const xPercent = x / rect.width;
const yPercent = y / rect.height;
// Calcular el ángulo de rotación (máximo ±15 grados)
const tiltX = (0.5 - yPercent) * 15; // Invertido para que se incline hacia el cursor
const tiltY = (xPercent - 0.5) * 15;
// Aplicar transformación con efecto de suavizado
card.style.transition = 'transform 0.1s ease-out';
card.style.transform = `perspective(1000px) rotateX(${tiltX}deg) rotateY(${tiltY}deg) scale3d(1.02, 1.02, 1.02)`;
// Efecto de paralaje para elementos internos
const title = card.querySelector('h2');
const desc = card.querySelector('p:not(.fecha)');
const btn = card.querySelector('.btn');
const img = card.querySelector('img');
if (title) title.style.transform = `translateZ(25px) translateX(${tiltY * 0.5}px) translateY(${tiltX * -0.5}px)`;
if (desc) desc.style.transform = `translateZ(15px) translateX(${tiltY * 0.3}px) translateY(${tiltX * -0.3}px)`;
if (btn) btn.style.transform = `translateZ(30px) translateX(${tiltY * 0.7}px) translateY(${tiltX * -0.7}px)`;
if (img) img.style.transform = `translateZ(5px) scale(1.1) translateX(${tiltY * -0.3}px) translateY(${tiltX * 0.3}px)`;
// Efecto de brillo dinámico
const glare = card.querySelector('.card-glare') || document.createElement('div');
if (!glare.classList.contains('card-glare')) {
glare.className = 'card-glare';
glare.style.position = 'absolute';
glare.style.top = '0';
glare.style.left = '0';
glare.style.width = '100%';
glare.style.height = '100%';
glare.style.pointerEvents = 'none';
glare.style.background = 'radial-gradient(circle at ' + xPercent * 100 + '% ' + yPercent * 100 + '%, rgba(255,255,255,0.15), transparent 50%)';
glare.style.zIndex = '3';
card.appendChild(glare);
} else {
glare.style.background = 'radial-gradient(circle at ' + xPercent * 100 + '% ' + yPercent * 100 + '%, rgba(255,255,255,0.15), transparent 50%)';
}
}
function resetCardTilt(e) {
const card = this;
// Restablecer la transformación con una transición suave
card.style.transition = 'transform 0.5s ease-out';
card.style.transform = 'perspective(1000px) rotateX(0) rotateY(0) scale3d(1, 1, 1)';
// Restablecer elementos internos
const title = card.querySelector('h2');
const desc = card.querySelector('p:not(.fecha)');
const btn = card.querySelector('.btn');
const img = card.querySelector('img');
if (title) title.style.transform = 'translateZ(15px)';
if (desc) desc.style.transform = 'translateZ(10px)';
if (btn) btn.style.transform = 'translateZ(20px)';
if (img) img.style.transform = 'translateZ(5px)';
// Eliminar el efecto de brillo
const glare = card.querySelector('.card-glare');
if (glare) {
glare.remove();
}
}
// Crear partículas temáticas de anime con rendimiento optimizado
function createAnimeParticles() {
const particlesContainer = document.getElementById('anime-particles');
const particleTypes = ['sakura', 'star', 'anime-icon katana', 'anime-icon shuriken'];
const maxParticles = 20; // Reducido para mejor rendimiento
let activeParticles = 0;
// Crear partículas iniciales
for (let i = 0; i < maxParticles; i++) {
createParticle();
}
function createParticle() {
if (activeParticles >= maxParticles) return;
activeParticles++;
const particle = document.createElement('div');
const randomType = particleTypes[Math.floor(Math.random() * particleTypes.length)];
particle.className = randomType;
// Posición aleatoria
const posX = Math.random() * 100;
particle.style.left = `${posX}%`;
// Tamaño aleatorio
const size = 10 + Math.random() * 20;
particle.style.width = `${size}px`;
particle.style.height = `${size}px`;
// Duración aleatoria
const duration = 15 + Math.random() * 15;
particle.style.animationDuration = `${duration}s`;
// Retraso aleatorio
const delay = Math.random() * 10;
particle.style.animationDelay = `${delay}s`;
particlesContainer.appendChild(particle);
// Eliminar y recrear la partícula cuando termine la animación
setTimeout(() => {
particle.remove();
activeParticles--;
createParticle();
}, (duration + delay) * 1000);
}
}
</script>
</body>
</html>
Comentarios (2)
Inicia sesión para comentar
uff si funciona
obvio