(function () {
let target = null
let holdTimer = null
let pick = null
let crack = null
let startTime = null
const mineTime = 3000
const pickaxe = "https://freepngimg.com/thumb/minecraft/94806-square-angle-pocket-edition-pickaxe-minecraft.png"
const breakImg = "https://www.onlygfx.com/wp-content/uploads/2018/02/crack-3.png"
function avgColor(el) {
const r = el.getBoundingClientRect()
const c = document.createElement("canvas")
c.width = Math.max(1, r.width)
c.height = Math.max(1, r.height)
const ctx = c.getContext("2d")
try {
ctx.drawImage(el, 0, 0, c.width, c.height)
const data = ctx.getImageData(0, 0, c.width, c.height).data
let rSum = 0, gSum = 0, bSum = 0
for (let i = 0; i < data.length; i += 4) {
rSum += data[i]
gSum += data[i + 1]
bSum += data[i + 2]
}
const count = data.length / 4
return `rgb(${rSum / count}, ${gSum / count}, ${bSum / count})`
} catch (e) {
const cs = getComputedStyle(el)
return cs.backgroundColor || "gray"
}
}
function spawnDebris(el, intense = false) {
const r = el.getBoundingClientRect()
const baseColor = avgColor(el)
const amount = intense ? 15 : 3
for (let i = 0; i < amount; i++) {
const d = document.createElement("div")
d.style.position = "fixed"
d.style.width = "6px"
d.style.height = "6px"
d.style.background = baseColor
d.style.left = (r.left + r.width / 2) + "px"
d.style.top = (r.top + r.height / 2) + "px"
d.style.pointerEvents = "none"
d.style.borderRadius = "2px"
d.style.transition = "opacity 0.6s linear"
document.body.appendChild(d)
const angle = Math.random() * Math.PI * 2
const dist = intense ? 60 : 25
const x = Math.cos(angle) * dist
const y = Math.sin(angle) * dist
setTimeout(() => {
d.style.transform = `translate(${x}px, ${y}px)`
d.style.opacity = "0"
}, 10)
setTimeout(() => d.remove(), 700)
}
}
function spawnPick(x, y) {
pick = document.createElement("img")
pick.src = pickaxe
pick.style.position = "fixed"
pick.style.left = x + "px"
pick.style.top = y + "px"
pick.style.width = "60px"
pick.style.pointerEvents = "none"
pick.style.transformOrigin = "bottom center"
pick.style.transition = "transform 0.1s ease-in-out"
document.body.appendChild(pick)
let flip = false
pick._int = setInterval(() => {
flip = !flip
pick.style.transform = flip ? "rotate(90deg)" : "rotate(0deg)"
}, 100)
}
function spawnCrack(el) {
crack = document.createElement("img")
crack.src = breakImg
crack.style.position = "absolute"
const r = el.getBoundingClientRect()
crack.style.left = r.left + "px"
crack.style.top = r.top + "px"
crack.style.width = r.width + "px"
crack.style.height = r.height + "px"
crack.style.pointerEvents = "none"
crack.style.opacity = "1"
crack.style.transition = "opacity 0.1s linear"
document.body.appendChild(crack)
}
function updateCrack() {
if (!crack || startTime === null) return
const elapsed = Date.now() - startTime
const progress = Math.min(elapsed / mineTime, 1)
crack.style.opacity = String(1 - progress)
if (progress < 1) {
spawnDebris(target, false)
requestAnimationFrame(updateCrack)
}
}
function removePick() {
if (pick) {
clearInterval(pick._int)
pick.remove()
pick = null
}
}
function removeCrack() {
if (crack) {
crack.remove()
crack = null
}
}
document.addEventListener("mousedown", e => {
target = e.target
spawnPick(e.clientX, e.clientY)
spawnCrack(target)
startTime = Date.now()
updateCrack()
holdTimer = setTimeout(() => {
spawnDebris(target, true)
if (target) target.remove()
removePick()
removeCrack()
target = null
startTime = null
}, mineTime)
})
document.addEventListener("mouseup", () => {
clearTimeout(holdTimer)
removePick()
removeCrack()
target = null
startTime = null
})
})()