Spaces:
Running
Running
import { toPng } from 'https://cdn.skypack.dev/html-to-image'; | |
const durationTimer = () => { | |
const elapsedDisplay = document.querySelector('.elapsed'); | |
let duration = 0.0; | |
return () => { | |
const startTime = performance.now(); | |
const incrementSeconds = setInterval(() => { | |
duration += 0.1; | |
elapsedDisplay.textContent = duration.toFixed(1); | |
}, 100); | |
const updateDuration = (task) => { | |
if (task?.status == 'completed') { | |
duration = task.completed_at - task.created_at; | |
return; | |
} | |
duration = Number(((performance.now() - startTime) / 1_000).toFixed(1)); | |
}; | |
window.addEventListener('focus', updateDuration); | |
return { | |
cleanup: (completedTask) => { | |
updateDuration(completedTask); | |
clearInterval(incrementSeconds); | |
window.removeEventListener('focus', updateDuration); | |
elapsedDisplay.textContent = duration.toFixed(1); | |
}, | |
}; | |
}; | |
}; | |
const updateCardName = (trainerName, pokeName, useTrainerName) => { | |
const cardName = document.querySelector('.pokecard .name'); | |
if (!cardName) { | |
return; | |
} | |
let trainerString = ''; | |
if (trainerName && useTrainerName) { | |
trainerName = [...trainerName].filter((char) => char.match(/[\wÀ-ÿ '".,&+#!?:/\\()_-]/g)?.length).join(''); | |
trainerString = `${trainerName}${trainerName.match(/[sSzZ]$/g)?.length ? "' " : "'s "}`; | |
} | |
const fullName = `${trainerString}${pokeName}`; | |
cardName.innerText = fullName; | |
let nameWidth; | |
let cardWidth = document.querySelector('.pokecard').getBoundingClientRect().width; | |
let scale = 1.01; | |
do { | |
scale -= 0.01; | |
cardName.style.transform = `scaleX(${scale})`; | |
nameWidth = cardName.getBoundingClientRect().width; | |
} while (nameWidth / cardWidth > 0.62); | |
return fullName; | |
}; | |
const rotateCard = () => { | |
const RANGE = 0.1; | |
const INTERVAL = 13; // ~75 per second | |
let previousTime = 0; | |
// Throttle closure | |
return (card, containerMouseEvent) => { | |
const currentTime = performance.now(); | |
if (currentTime - previousTime > INTERVAL) { | |
previousTime = currentTime; | |
const rect = card.getBoundingClientRect(); | |
const rotateX = (containerMouseEvent.clientY - rect.y - rect.height / 2) * RANGE; | |
const rotateY = -(containerMouseEvent.clientX - rect.x - rect.width / 2) * RANGE; | |
card.style.setProperty('--card-rx', rotateX + 'deg'); | |
card.style.setProperty('--card-ry', rotateY + 'deg'); | |
} | |
}; | |
}; | |
const initialiseCardRotation = (scene) => { | |
const card = document.querySelector('.pokecard'); | |
const mousemoveHandler = rotateCard().bind(null, card); | |
scene.addEventListener('mousemove', mousemoveHandler, true); | |
return mousemoveHandler; | |
}; | |
const setOutput = (mode, state) => { | |
const output = document.querySelector('.output'); | |
output.dataset.mode = mode; | |
output.dataset.state = state; | |
}; | |
const screenshotCard = async () => { | |
const card = document.querySelector('.pokecard'); | |
const imageUrl = await toPng(card, { | |
width: 400, | |
height: 558, | |
backgroundColor: 'transparent', | |
style: { | |
transform: 'none', | |
}, | |
}); | |
return imageUrl; | |
}; | |
export { durationTimer, updateCardName, initialiseCardRotation, setOutput, screenshotCard }; | |