Skip to content

Instantly share code, notes, and snippets.

@gnat
Last active July 7, 2024 01:55
Show Gist options
  • Save gnat/f094e947b3a785e1ed6b7def979132ae to your computer and use it in GitHub Desktop.
Save gnat/f094e947b3a785e1ed6b7def979132ae to your computer and use it in GitHub Desktop.
3D Card (Surreal + CSS Scope Inline)
<html>
<head>
<script src="https://gnat.github.io/css-scope-inline/script.js"></script>
<script src="https://gnat.github.io/surreal/surreal.js"></script>
</head>
<body>
<style>
* { box-sizing: border-box; }
html, body { width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; }
body { font-family: system-ui, sans-serif; perspective: 1500px; background: linear-gradient(#666, #222); }
</style>
<div>
3D Card
<div></div>
<style>
me {
position: relative; width: 300px; height: 400px; padding: 1em;
font-weight: bold; text-align: right; text-shadow: 0 0 4px #000; color: #ddd;
box-shadow: 0 1px 5px #00000099; border-radius: 10px; background: url(https://i.postimg.cc/MHKFqnq6/1679116297740936.png) center; background-size: cover;
transition-duration: 300ms; transition-property: transform, box-shadow; transition-timing-function: ease-out; transform: rotate3d(0);
}
me:hover { transition-duration: 150ms; box-shadow: 0 5px 20px 5px #00000044; }
me > div { position: absolute; width: 100%; height: 100%; left: 0; top: 0; border-radius: 10px; background-image: radial-gradient(circle at 90% -20%, #ffffff33, #0000000f); }
</style>
<script>
me().on('mouseenter', (ev) => {
let e = me(ev)
e.bounds = e.getBoundingClientRect()
e.on('mousemove', e.rotateToMouse)
})
me().on('mouseleave', (ev) => {
let e = me(ev)
e.off('mousemove', e.rotateToMouse)
e.style.transform = ''
e.style.background = ''
})
me().rotateToMouse = (ev) => {
let e = me(ev)
let mouseX = ev.clientX
let mouseY = ev.clientY
let leftX = mouseX - e.bounds.x
let topY = mouseY - e.bounds.y
let center = { x: leftX - e.bounds.width / 2, y: topY - e.bounds.height / 2 }
let distance = Math.sqrt(center.x**2 + center.y**2)
e.style.transform = `scale3d(1.07, 1.07, 1.0) rotate3d(${center.y / 100}, ${-center.x / 100}, 0, ${Math.log(distance)* 2}0deg)`
me('div', e).style.backgroundImage = `radial-gradient(circle at ${center.x * 2 + e.bounds.width/2}px ${center.y * 2 + e.bounds.height/2}px, #ffffff55, #0000000f)`
}
</script>
</div>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment