<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>
<link rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<title>Game Cards App</title>
<link rel="icon" type="image/png" href="https://cdn1.iconfinder.com/data/icons/entertainment-events-hobbies/24/card-game-cards-hold-512.png">
<style>
#main-content {
display: none;
}
* {
box-sizing: border-box;
}
body {
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
flex-flow: column wrap;
background: radial-gradient(circle, rgba(7, 50, 22, 255) 0%, rgba(0, 0, 0, 255) 100%);
animation: shine 4s linear infinite;
color: white;
font-family: "Lato";
-webkit-font-smoothing: antialiased;
text-rendering: optimizeLegibility;
}
ul {
margin: 0;
padding: 0;
list-style-type: none;
max-width: 800px;
width: 100%;
margin: 0 auto;
padding: 15px;
text-align: center;
overflow-x: hidden;
}
.card {
float: left;
position: relative;
width: calc(33.33% - 30px + 9.999px);
height: 340px;
margin: 0 30px 30px 0;
perspective: 1000;
}
.card:first-child .card__front {
background:#5271C2;
}
.card__front img {
width: 100%;
height: 100%;
object-fit: cover;
}
.card:first-child .card__num {
text-shadow: 1px 1px rgba(52, 78, 147, 0.8)
}
.card:nth-child(2) .card__front {
background:#35a541;
}
.card:nth-child(2) .card__num {
text-shadow: 1px 1px rgba(34, 107, 42, 0.8);
}
.card:nth-child(3) {
margin-right: 0;
}
.card:nth-child(3) .card__front {
background: #bdb235;
}
.card:nth-child(3) .card__num {
text-shadow: 1px 1px rgba(129, 122, 36, 0.8);
}
.card:nth-child(4) .card__front {
background: #db6623;
}
.card:nth-child(4) .card__num {
text-shadow: 1px 1px rgba(153, 71, 24, 0.8);
}
.card:nth-child(5) .card__front {
background: #3e5eb3;
}
.card:nth-child(5) .card__num {
text-shadow: 1px 1px rgba(42, 64, 122, 0.8);
}
.card:nth-child(6) .card__front {
background: #aa9e5c;
}
.card:nth-child(6) .card__num {
text-shadow: 1px 1px rgba(122, 113, 64, 0.8);
}
.card:last-child {
margin-right: 0;
}
.card__flipper {
cursor: pointer;
transform-style: preserve-3d;
transition: all 0.6s cubic-bezier(0.23, 1, 0.32, 1);
border: 3.5px solid rgba(255, 215, 0, 0.6);
background-image: linear-gradient(45deg, rgba(255, 215, 0, 0.5), transparent, rgba(255, 215, 0, 0.5));
}
.card__front, .card__back {
position: absolute;
backface-visibility: hidden;
top: 0;
left: 0;
width: 100%;
height: 340px;
}
.card__front {
transform: rotateY(0);
z-index: 2;
overflow: hidden;
}
.card__back {
transform: rotateY(180deg) scale(1.1);
background: linear-gradient(45deg, #483D8B, #301934, #483D8B, #301934);
display: flex;
flex-flow: column wrap;
align-items: center;
justify-content: center;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
}
.card__back span {
font-weight: bold; /* Metni kalın yap */
color: white; /* Beyaz renk */
font-size: 16px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.card__name {
font-size: 32px;
line-height: 0.9;
font-weight: 700;
}
.card__name span {
font-size: 14px;
}
.card__num {
font-size: 100px;
margin: 0 8px 0 0;
font-weight: 700;
}
@media (max-width: 700px) {
.card__num {
font-size: 70px;
}
}
@media (max-width: 700px) {
.card {
width: 100%;
height: 290px;
margin-right: 0;
float: none;
}
.card .card__front,
.card .card__back {
height: 290px;
overflow: hidden;
}
}
/* Demo */
main {
text-align: center;
}
main h1, main p {
margin: 0 0 12px 0;
}
main h1 {
margin-top: 12px;
font-weight: 300;
}
.fa-github {
color: white;
font-size: 50px;
margin-top: 8px;
}
.tm-container {
display: flex;
justify-content: center;
align-items: center;
}
.tm-letter {
display:inline-block;
font-size:30px;
margin: 0 5px;
margin-top: 10px;
opacity: 0;
transform: translateY(0);
animation: letter-animation 6s ease-in-out infinite;
}
@keyframes letter-animation {
0%, 100% {
opacity: 1;
transform: translateY(0);
}
10%, 40%, 60%, 90% {
opacity: 1;
transform: translateY(-10px);
}
20%, 80% {
opacity: 1;
transform: translateY(0);
}
}
#m-letter {
animation-delay: 1.5s;
}
a {
position: relative;
display: inline-block;
padding: 0px;
}
a::before {
content: '';
position: absolute;
top: 50%; /* Orta konumu */
left: 50%; /* Orta konumu */
transform: translate(-50%, -50%);
width: 50px;
height: 45px;
border-radius: 50%; /* Eğer bir daire şeklinde efekt isteniyorsa */
box-shadow: 0 0 8px 4px rgba(110, 110, 110, 0.8);
filter: blur(4px) brightness(1.5);
opacity: 0;
transition: opacity 0.3s ease, transform 0.3s ease;
z-index: -1;
}
a:hover::before {
opacity: 1;
}
body.hoverEffect {
background: radial-gradient(circle at center, #000000, #000033, #000066, #1a1a1a);
}
#gameCard {
width: 300px;
height: 450px;
margin: 50px auto;
padding: 20px;
border-radius: 15px;
box-shadow:
0 0 50px 10px #FFD700,
0 0 100px 20px #0000FF,
0 0 150px 30px #000033;
background: rgba(0,0,0,0.7);
color:#FFD700;
text-align: center;
border: 3px solid #FFD700;
}
#gameCardLink span {
font-size: 18px;
margin-right: 5px;
font-weight: bold;
}
#gameCardLink span:last-child {
font-size: 0.79em;
vertical-align: super;
opacity: 0.9;
font-weight: bold;
text-shadow: 2px 2px 2px rgba(0, 0, 0, 0.5);
}
#loading-animation {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image:url();
background-repeat: no-repeat;
background-size: cover ;
display: flex;
justify-content: center;
align-items: center;
z-index: 9999;
}
.loader {
border-top: 9px solid #00a2ed;
border-radius: 80%;
width: 12vw;
height: 12vw;
animation: spin 2s linear infinite;
position: absolute;
left: 44%;
top: 46%; /
transform: translate(-50%, -50%) rotate(0deg); /* Yuvarlak halkanın tam ortasında olması için bu dönüşümü kullanın. */
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
</style>
</head>
<body>
<div id="loading-animation">
<div class="loader"></div>
</div>
<div id="main-content">
<div class="tm-container">
<div class="tm-letter" id="t-letter">T</div>
<div class="tm-letter" id="m-letter">M</div>
</div>
<audio id="flipSound" preload="auto">
<source src="https://cdn.freesound.org/previews/321/321114_2776777-lq.ogg" type="audio/wav">
</audio>
<main>
<div id="gameCardLink">
<span>G</span>
<span>a</span>
<span>m</span>
<span>e</span>
<span> </span> <!-- Boşluk eklemek için span ekledik -->
<span> </span>
<span>C</span>
<span> </span>
<span>a</span>
<span> </span>
<span>r</span>
<span> </span>
<span>d</span>
<span> </span>
<span>s</span>
<span>®</span>
</div>
<p><a href="https://github.com/murattasci06"><i class="fab fa-github"></i></a></p>
</main>
<ul>
<li id='spider' class="card" >
<div class="card__flipper">
<div class="card__front">
<img src="https://gecbunlari.com/wp-content/uploads/2021/12/Spiderman-No-Way-Home.jpg" alt="Spiderman">
<p class="card__name"><span>Marvel</span><br>Spiderman</p>
<p class="card__num">1</p>
</div>
<iframe class="frame"
width="225"
height="340"
src="https://www.youtube.com/embed/JfVOs4VSpmA?autoplay=1&mute=1&vq=hd1080"
title="YouTube video player"
frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
allowfullscreen
></iframe>
<div class="card__back">
<svg height="180" width="180">
<circle cx="90" cy="90" r="65" stroke="#514d9b" stroke-width="35" />
<!-- Dış dairenin kenarı (yeşil) -->
<circle cx="90" cy="90" r="83" fill="none" stroke="rgba(7, 50, 22, 255)" stroke-width="1" />
</svg>
<span>1.89 Bil. $</span>
</div>
</div>
</li>
<li id='batman' class="card">
<div class="card__flipper">
<div class="card__front">
<img src="https://i.pinimg.com/736x/1e/f1/3d/1ef13dfa4b7b8c131302e242d1ec48d7.jpg" alt="Batman">
<p class="card__name"><span>DC</span><br>Batman</p>
<p class="card__num">2</p>
</div>
<iframe class="frame"
width="225"
height="340"
src="https://www.youtube.com/embed/mqqft2x_Aa4?autoplay=1&mute=1&vq=hd1080"
title="YouTube video player"
frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
allowfullscreen
></iframe>
<div class="card__back">
<svg height="180" width="180">
<circle cx="90" cy="90" r="65" stroke="#35a541" stroke-width="35"/>
<!-- Dış dairenin kenarı (yeşil) -->
<circle cx="90" cy="90" r="83" fill="none" stroke="rgba(7, 50, 22, 255)" stroke-width="1" />
</svg>
<span>771 Mil. $</span>
</div>
</div>
</li>
<li id='guard' class="card">
<div class="card__flipper">
<div class="card__front">
<img src="https://wallpapercave.com/wp/wp12279011.jpg" alt="Guardians_of_the_Galaxy_Vol_3">
<p class="card__name"><span>Marvel</span><br>Guardians_of_the_Galaxy_Vol_3</p>
<p class="card__num">3</p>
</div>
<iframe class="frame"
width="225"
height="340"
src="https://www.youtube.com/embed/u3V5KDHRQvk?autoplay=1&mute=1&vq=hd1080"
title="YouTube video player"
frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
allowfullscreen
></iframe>
<div class="card__back">
<svg height="180" width="180">
<circle cx="90" cy="90" r="65" stroke="#bdb235" stroke-width="35"/>
<!-- Dış dairenin kenarı (yeşil) -->
<circle cx="90" cy="90" r="83" fill="none" stroke="rgba(7, 50, 22, 255)" stroke-width="1" />
</svg>
<span>845.4 Mil. $</span>
</div>
</div>
</li>
<li id='shazam' class="card">
<div class="card__flipper">
<div class="card__front">
<img src="https://wallpaperaccess.com/full/8940499.jpg" alt="Shazam">
<p class="card__name"><span>DC</span><br>Shazam2</p>
<p class="card__num">4</p>
</div>
<iframe class="frame"
width="225"
height="340"
src="https://www.youtube.com/embed/AIc671o9yCI?autoplay=1&mute=1&vq=hd1080"
title="YouTube video player"
frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
allowfullscreen
></iframe>
<div class="card__back">
<svg height="180" width="180">
<circle cx="90" cy="90" r="65" stroke="#db6623" stroke-width="35"/>
<!-- Dış dairenin kenarı (yeşil) -->
<circle cx="90" cy="90" r="83" fill="none" stroke="rgba(7, 50, 22, 255)" stroke-width="1" />
</svg>
<span>462.5 Mil. $</span>
</div>
</div>
</li>
<li id='flash' class="card">
<div class="card__flipper">
<div class="card__front">
<img src="https://images2.alphacoders.com/131/1316679.jpeg" alt="Flash">
<p class="card__name"><span>DC</span><br>Flash</p>
<p class="card__num">5</p>
</div>
<iframe class="frame"
width="225"
height="340"
src="https://www.youtube.com/embed/hebWYacbdvc?autoplay=1&mute=1&vq=hd1080"
title="YouTube video player"
frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
allowfullscreen
></iframe>
<div class="card__back">
<svg height="180" width="180">
<circle cx="90" cy="90" r="65" stroke="#3e5eb3" stroke-width="35"/>
<!-- Dış dairenin kenarı (yeşil) -->
<circle cx="90" cy="90" r="83" fill="none" stroke="rgba(7, 50, 22, 255)" stroke-width="1" />
</svg>
<span>560.2 Mil. $</span>
</div>
</div>
</li>
<li id='strange' class="card">
<div class="card__flipper">
<div class="card__front">
<img src=" https://images3.alphacoders.com/121/1213553.jpg" alt="Dr_Strange_2">
<p class="card__name"><span>Marvel</span><br>Dr_Strange_2</p>
<p class="card__num">6</p>
</div>
<iframe class="frame"
width="225"
height="340"
src="https://www.youtube.com/embed/aWzlQ2N6qqg?autoplay=1&mute=1&vq=hd1080"
title="YouTube video player"
frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
allowfullscreen
></iframe>
<div class="card__back">
<svg height="180" width="180">
<circle cx="90" cy="90" r="65" stroke="#aa9e5c" stroke-width="35"/>
<!-- Dış dairenin kenarı (yeşil) -->
<circle cx="90" cy="90" r="83" fill="none" stroke="rgba(7, 50, 22, 255)" stroke-width="1" />
</svg>
<span>955.8 Mil. $</span>
</div>
</div>
</li>
</ul>
</div>
</body>
<script>
var Flipper = (function() {
var card = $('.card');
var flipper = card.find('.card__flipper');
var win = $(window);
var flip = function() {
var thisCard = $(this);
var thisFlipper = thisCard.find('.card__flipper');
var offset = thisCard.offset();
var xc = win.width() / 2;
var yc = win.height() / 2;
var docScroll = $(document).scrollTop();
var cardW = thisCard.outerWidth() / 2;
var cardH = thisCard.height() / 2;
var transX = xc - offset.left - cardW;
var transY = docScroll + yc - offset.top - cardH;
// if (offset.top > card.height()) transY = docScroll - offset.top + cardH;
if (win.width() <= 700) transY = 0;
if (card.hasClass('active')) unflip();
thisCard.css({'z-index': '3'}).addClass('active');
thisFlipper.css({
'transform': 'translate3d(' + transX + 'px,' + transY + 'px, 0) rotateY(180deg) scale(1)',
'-webkit-transform': 'translate3d(' + transX + 'px,' + transY + 'px, 0) rotateY(180deg) scale(1)',
'-ms-transform': 'translate3d(' + transX + 'px,' + transY + 'px, 0) rotateY(180deg) scale(1)'
}).addClass('active');
return false;
};
var unflip = function(e) {
card.css({'z-index': '1'}).removeClass('active');
flipper.css({
'transform': 'none',
'-webkit-transform': 'none',
'-ms-transform': 'none'
}).removeClass('active');
};
var bindActions = function() {
card.on('click', flip);
win.on('click', unflip);
}
var init = function() {
bindActions();
};
return {
init: init
};
}());
Flipper.init();
</script>
<script>
<!-- HOVER FOR TRAILER -->
var hoverTimeout;
function onHover() {
const currentCard = $(this);
hoverTimeout = setTimeout(() => {
currentCard.find('.card__front').hide();
currentCard.find('.iframe').show();
var src = currentCard.find('.iframe').attr("src");
currentCard.find('.iframe').attr("src", src);
currentCard.find('.iframe').on('click', function() {
$(this).requestFullscreen();
});
}, 5000); // 5000 milliseconds (5 seconds)
}
function onHoverTime() {
clearTimeout(hoverTimeout); // Clear the timeout to prevent actions if the user moves away before 5 seconds
$(this).find('.card__front').show();
$(this).find('.iframe').hide();
var src = $(this).find('.iframe').attr("src");
if (src) {
$(this).find('.iframe').attr("src", src.replace('?autoplay=1', ''));
}
};
function setupHoverEffect(cardId) {
console.log(`setupHoverEffect function is called for ${cardId}`);
$(`#${cardId}`).hover(function() {
// Call the existing onHover function when the mouse hovers over the card
onHover.call(this);
}, function() {
// Call the existing onHoverTime function when the mouse leaves the card
onHoverTime.call(this);
});
}
setupHoverEffect("batman");
setupHoverEffect("flash");
setupHoverEffect("spider");
setupHoverEffect("shazam");
setupHoverEffect("flash");
setupHoverEffect("strange");
</script>
<script>
var cardFlags = {};
$(document).ready(function() {
var flipSound = document.getElementById("flipSound");
$(".card__front").click(function() {
flipSound.currentTime = 0;
flipSound.play();
});
$(".card").click(function() {
var card = $(this);
var cardId = card.find(".card__num").text();
// Check if the card is not already flipping to avoid multiple flips
if (!card.hasClass('flipping')) {
card.addClass('flipping');
// Check if the front side is facing the viewer
if (!card.hasClass("flipped")) {
if (!cardFlags[cardId]) {
startAnimation(div);
cardFlags[cardId] = true;
card.addClass("flipped");
}
// Adding canvas to back-side
var div = document.querySelector('.flipped .card__flipper.active .card__back');
var canvas = document.getElementsByClassName('p5Canvas')[0];
if (div && canvas) {
div.appendChild(canvas);
canvas.style.position = 'absolute';
}
} else {
card.removeClass("flipped");
}
setTimeout(function() {
card.removeClass('flipping');
}, 1000);
}
});
// Prevent sound on back side click
$(".card__back").click(function(e) {
e.stopPropagation();
});
});
</script>
<script>
// Body's hoover effect
document.getElementById("gameCardLink").addEventListener("mouseover", function() {
document.body.classList.add("hoverEffect");
});
document.getElementById("gameCardLink").addEventListener("mouseout", function() {
document.body.classList.remove("hoverEffect");
});
</script>
<script>
// Portal effect
</script>
<script>
// Hiding and showing of loading animation
function hideLoadingAnimation() {
var loadingAnimation = document.getElementById("loading-animation");
var mainContent = document.getElementById("main-content");
loadingAnimation.style.display = "none";
mainContent.style.display = "block";
}
window.onload = function() {
hideLoadingAnimation();
};
</script>
<script>
// The conditions of the hover function.
$('.card').on( "mouseenter", onHover).on( "mouseleave", onHoverTime );
// hover events removing and assigning
$(document.body).on('click', function(){
if ($("#batman").off( "mouseenter", onHover)){
$('#batman, #flash').hover(onHover, onHoverTime);
console.log('yes');
} })
// overlap boundary conditions for hover on off
$(".card").click(function(){
let cord = document.getElementsByClassName('active')[1].style.transform;
[cx,cy,...rest]= cord.slice(12).split('px, ');
console.log(`cx: ${cx}, cy: ${cy}`);
if ((cy<=300)&&(cy>=100)||((cy>(-300))&&(cy<(-60)))){
$("#batman").off( "mouseenter", onHover);
$("#flash").off( "mouseenter", onHover);
console.log('offed');
let hoverTimeout;
}
else{
console.log('on');
$('#batman, #flash').hover(onHover, onHoverTime);
}
});
</script>
</html>
I currently have 6 cards with ids: spider, batman, guard, shazam, flash, strange. (I plan to increase the number) For these cards, I have common onHover() and onHoverTime() functions that play video trailers with hover and reset them. I want it to work independently for each card.
If I need to give a little more detail, I can say that the trailer is played when you wait 5 seconds with the mouse on the front of each card, but the longer you wait on a card, the more the trailer progresses on that card when the hover event occurs on another card. So they work as a whole.
However, what I want is for each card's hover trailer functions to work card-specific and not affect each other. (The trailer should restart from 0:00 on every hover event of each card.)
I thought adding of the following approach but it doesn't work the way I want:
function setupHoverEffect(cardId) {
console.log(`setupHoverEffect function is called for ${cardId}`);
$(`#${cardId}`).hover(function() {
// Call the existing onHover function when the mouse hovers over the card
onHover.call(this);
}, function() {
// Call the existing onHoverTime function when the mouse leaves the card
onHoverTime.call(this);
});
}
setupHoverEffect("spider");
setupHoverEffect("batman");
setupHoverEffect("guard");
setupHoverEffect("shazam");
setupHoverEffect("flash");
setupHoverEffect("strange");
Additionally, I thought it wouldn't be unmanageable if the number of cards increased so much. It may not be correct to repeat setupHoverEffect() for new cards added. How can I solve this problem?
The link of full code: https://drive.google.com/file/d/1ptX0FanoKVRUC6ni5J7_2TYUNyYuNEl_/view
visual representation of the problem:


There are so many issues happening, but I will try to address the most important ones. First thing I notice is that all the videos are set to be autoplay by default, so they all run when the page is loaded:
In the above code, see that there is query params in the src attribute
autoplay=1, we should first remove them from all the iframes.The next problem is that you query the DOM wrong:
The class
.iframedoesn't exist, since you assigned the iframes with.frameclass instead. But to fix this, we can just select the DOM by its tag name, e.g.:And then, since we have removed the autoplay query params, we need to readd them when
hoverevent happens, we can trigger the play by appendingautoplay=1to the query params, but whenhoverevent happens like this inside theonHover()function:Then finally, we need to fix the
clearTimeout, it seems like thesetTimeouts are triggered multiple times, i'm not sure why, but basically we can store thetimeoutid to an object so that we can store and clear all of them:And then update the
onHover()function:Finally, we can update the
onHoverTimefunction to this, so we can clear the timeout ids correctly:Here is the working fiddle.