I’m writing some code to shuffle and display a deck of cards. The deck works fine on Android, but have morphing issues on some IOS devices. Newer IOS devices seem to be fine, but especially older devices encounter the problem.
Specifically there is two diffrences on android and IOS. Firstly the choosen card morphes through the rest of the deck on ios before displaying. Secondly, it shoots way of screen when being put into the “down” pile.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script src="https://code.jquery.com/jquery-3.6.4.min.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
body {
box-sizing: border-box;
position: absolute;
left: 50px;
top: 50px;
font-family: 'Suez One';
overflow: visible;
}
/* Add a style for the overlay */
.overlay {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5); /* semi-transparent black */
justify-content: center;
align-items: center;
z-index: 1000;
backdrop-filter: blur(5px); /* Adjust the blur effect */
}
/* Style for the modal */
.modal {
background: #fff;
padding: 20px;
border-radius: 10px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
text-align: center;
}
/* Style for the close button */
.close-btn {
padding: 10px 20px;
background: #007BFF;
color: #fff;
border: none;
border-radius: 5px;
cursor: pointer;
}
.red-box {
position: absolute;
left: 50%;
transform: translateX(-50%);
top: 230px;
width: 300px;
height: 65px;
background-color: #FFCBAA;
z-index: 1000; /* Ensure the red box is in front of the cards */
}
.randomSuit {
position: absolute;
left: 50px;
top: 50px;
}
.card {
background-image: radial-gradient(#eeaeca, #94bbe9);
left: 44%;
top: 33%;
transform: rotateX(60deg) rotateY(0deg) rotateZ(-45deg) translateY(0);
position: absolute;
width: 100px;
height: 150px;
border-radius: 10px;
font-size: 0px;
transition: all 700ms, font-size 500ms, background-image 0.7s ease-in-out;
border: 2px solid #060303;
cursor: pointer;
border-bottom-color: #933;
box-shadow: -10px 40px 20px 2px rgba(0,0,0,0);
display: flex;
align-items: center;
justify-content: center;
color: #333;
white-space: normal; /* or white-space: pre-wrap; */
word-wrap: break-word;
text-align: center; /* Add this line to center the text */
}
.card:first-child {
box-shadow: 12px 12px 0px 12px rgba(0,0,0,0.3);
}
.card:last-child {
transform = translateZ(-100deg);
}
.card {
-webkit-transition: all 700ms, font-size 500ms, background-image 0.7s ease-in-out;
-moz-transition: all 700ms, font-size 500ms, background-image 0.7s ease-in-out;
-ms-transition: all 700ms, font-size 500ms, background-image 0.7s ease-in-out;
-o-transition: all 700ms, font-size 500ms, background-image 0.7s ease-in-out;
}
.cards {
height: auto;
width: auto;
}
</style>
<div class="cards">
<!-- Use JavaScript to generate all 52 cards with values -->
<script>
function displayCustomPopup() {
// Show the overlay and modal
document.querySelector('.overlay').style.display = 'flex';
}
// Function to close the custom popup
function closeCustomPopup() {
// Hide the overlay and modal
document.querySelector('.overlay').style.display = 'none';
}
// Attach the function to the window's onload event
//window.onload = displayCustomPopup;
let suits = ['H', 'S', 'R', 'K'];
let values = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13'];
let translateZValue = -40;
// Array to store the generated cards
let cards = [];
// Array to store all card values
let allCardValues = [];
// Create an array with all card values
for (let suit of suits) {
for (let value of values) {
allCardValues.push(`${value}`);
}
}
// Shuffle the array of card values
for (let i = allCardValues.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[allCardValues[i], allCardValues[j]] = [allCardValues[j], allCardValues[i]];
}
// Generate card HTML using shuffled values
for (let cardValue of allCardValues) {
const randomRotation = Math.random() * (2) - 42;
const cardHtml = `<div class="card down" style="transform: rotateX(60deg) rotateY(0deg) rotateZ(${randomRotation}deg) translateZ(${translateZValue}px) translateY(-15px);" onclick="cardClickHandler(event)"><span>${cardValue}</span></div>`;
cards.push(cardHtml);
translateZValue += 1;
}
// Append the shuffled deck to the container
const cardsContainer = document.querySelector('.cards');
cards.forEach(cardHtml => {
const cardElement = document.createElement('div');
cardElement.innerHTML = cardHtml;
cardsContainer.appendChild(cardElement.firstChild);
});
function cardClickHandler(event) {
// Get the clicked element using event.currentTarget
const clickedCard = event.currentTarget;
//alert(currentTarget);
if (clickedCard.classList.contains('down')) {
setTimeout(() => {
clickedCard.classList.remove('down');
clickedCard.classList.add('opened');
var transitionProperties="all 700ms, font-size 500ms, background-image 0.7s ease-in-out";
clickedCard.style.transition = transitionProperties;
// Set the transition properties for vendor-prefixed syntax
clickedCard.style.webkitTransition = transitionProperties;
clickedCard.style.mozTransition = transitionProperties;
clickedCard.style.msTransition = transitionProperties;
clickedCard.style.oTransition = transitionProperties;
clickedCard.style.zIndex = '999';
clickedCard.style.webkitTransform = 'scale(1.5) rotateX(0) rotateY(180deg) rotateZ(0) translateX(0) translateY(0) translateZ(-100px)';
clickedCard.style.mozTransform = 'scale(1.5) rotateX(0) rotateY(180deg) rotateZ(0) translateX(0) translateY(0) translateZ(-100px)';
clickedCard.style.msTransform = 'scale(1.5) rotateX(0) rotateY(180deg) rotateZ(0) translateX(0) translateY(0) translateZ(-100px)';
clickedCard.style.oTransform = 'scale(1.5) rotateX(0) rotateY(180deg) rotateZ(0) translateX(0) translateY(0) translateZ(-100px)';
clickedCard.style.transform = 'scale(1.5) rotateX(0) rotateY(180deg) rotateZ(0) translateX(0) translateY(0) translateZ(-100px)';
clickedCard.style.boxShadow = '0 5px 14px rgba(0,0,0,0.1)';
clickedCard.style.fontSize="14px";
clickedCard.style.backgroundImage="radial-gradient(#ffffff, #ffffff)";
const spanInsideCard = clickedCard.querySelector('span');
if (spanInsideCard) {
spanInsideCard.style.webkitTransform = 'scaleX(-1)';
spanInsideCard.style.mozTransform = 'scaleX(-1)';
spanInsideCard.style.msTransform = 'scaleX(-1)';
spanInsideCard.style.oTransform = 'scaleX(-1)';
spanInsideCard.style.transform = 'scaleX(-1)';
spanInsideCard.style.display = 'inline-block';
}
}, 100);
} else if (clickedCard.classList.contains('opened')) {
setTimeout(() => {
clickedCard.classList.add('is-removed');
clickedCard.style.webkitTransform = 'translateY(200%)';
clickedCard.style.mozTransform = 'translateY(200%)';
clickedCard.style.msTransform = 'translateY(200%)';
clickedCard.style.oTransform = 'translateY(200%)';
clickedCard.style.transform = 'translateY(200%)';
var transitionProperties="all 700ms, font-size 500ms, background-image 0.7s ease-in-out";
clickedCard.style.transition = transitionProperties;
// Set the transition properties for vendor-prefixed syntax
clickedCard.style.webkitTransition = transitionProperties;
clickedCard.style.mozTransition = transitionProperties;
clickedCard.style.msTransition = transitionProperties;
clickedCard.style.oTransition = transitionProperties;
clickedCard.style.boxShadow = '0 -5px 5px rgba(0,0,0,0.01)';
clickedCard.style.fontSize="0px";
clickedCard.style.backgroundImage="radial-gradient(#eeaeca, #94bbe9)";
clickedCard.style.height="75px";
clickedCard.style.borderRadius="10px 10px 0 0";
// Find the new top card and make it clickable
const isTopCard = document.querySelector('.card:not(.is-removed):last-child');
}, 100);
}
}
</script>
</div>
<div class="red-box"></div>
<script>
// Add click event handler
// Add click and touchend event handler
</script>
</head>
<body>
<div class="overlay">
<div class="modal">
<p>DISPLAY</p>
<button class="close-btn" onclick="closeCustomPopup()">OK</button>
</div>
</div>
</body>
</html>
</body>
</html>
I have tried adding webkit, ms, o and other support, but this does not seem to make a difference.