<div class="cursor">
<div class="cursor__default">
<span class="cursor__default__inner"></span>
</div>
<div class="cursor__trace">
<span class="cursor__trace__inner"></span>
</div>
</div>
<section class="preloader shown-area">
<button class="preloader__btn">
<span class="preloader__btn_hold"></span>
</button>
</section>
<section class="header hidden-area">
Header
</section>
body {
cursor: none !important;
background-color: #1e4029;
}
.shown-area {
display: block;
opacity: 1;
}
.hidden-area {
display: none;
opacity: 0;
}
.cursor {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 9999;
pointer-events: none !important;
}
.cursor__default__inner {
position: absolute;
display:inline-block;
width: 20px;
height: 20px;
background-color: rgba(10, 27, 16, 2.5);
border: 2px solid #d5a54e;
border-radius: 50%;
transform: translate(-50%, -50%);
}
.cursor__trace__inner {
position: absolute;
display: inline-block;
width: 40px;
height: 40px;
border-radius: 50%;
background-color: rgba(0, 0, 0, .25);
transform: translate(-50%, -50%);
transition: all .04s ease;
}
.cursor--active .cursor__trace__inner {
transform: scale(0.5) translate(-100%, -100%);
transition: transform .3s ease;
}
@keyframes ripple {
0% {
transform: scale(0);
opacity: 1;
}
20% {
transform: scale(5);
opacity: 1;
}
100% {
transform: scale(10);
opacity: 0;
}
}
.ripple {
position: absolute;
display: inline-block;
width: 20px;
height: 20px;
border-radius: 50%;
background-color: #d5a54e;
animation: ripple .5s ease-out;
animation-fill-mode: forwards;
z-index: -1;
}
.preloader {
position: absolute;
top: 0;
left: 0;
background-color: #000000;
width: 100%;
height: 100%;
z-index: 999;
}
.preloader__btn {
position: absolute;
top: 50vh;
left: 50vw;
width: 120px;
height: 120px;
border-radius: 50%;
border: none;
color: rgb(213, 165, 78);
/* background-color: rgb(30, 64, 41);
*/
background: url('https://images.unsplash.com/photo-1514888286974-6c03e2ca1dba?q=80&w=2886&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D');
background-size: cover;
margin-top: -60px;
margin-left: -60px;
}
.preloader__btn_hold {
font-size: 19px;
line-height: 20px;
font-weight: 800;
letter-spacing: normal;
}
// Handle cursor movement for both mouse and touch events
function moveCursor(e) {
const cursorDefaultInner = document.querySelector(".cursor__default__inner");
const cursorTraceInner = document.querySelector(".cursor__trace__inner");
const clientX = e.clientX || (e.touches && e.touches[0].clientX);
const clientY = e.clientY || (e.touches && e.touches[0].clientY);
cursorDefaultInner.style.top = clientY + "px";
cursorDefaultInner.style.left = clientX + "px";
cursorTraceInner.style.top = clientY + "px";
cursorTraceInner.style.left = clientX + "px";
}
document.addEventListener("mousemove", moveCursor);
document.addEventListener("touchmove", moveCursor);
const cursor = document.querySelector(".cursor");
// Handle cursor active state for both mouse and touch events
function activateCursor() {
cursor.classList.add("cursor--active");
}
function deactivateCursor() {
cursor.classList.remove("cursor--active");
}
document.addEventListener("mousedown", activateCursor);
document.addEventListener("touchstart", activateCursor);
document.addEventListener("mouseup", deactivateCursor);
document.addEventListener("touchend", deactivateCursor);
document.addEventListener("touchcancel", deactivateCursor);
// Create ripple effect for both mouse and touch events
function createRipple(e) {
const clientX = e.clientX || (e.touches && e.touches[0].clientX);
const clientY = e.clientY || (e.touches && e.touches[0].clientY);
let ripple = document.createElement("span");
ripple.classList.add("ripple");
cursor.appendChild(ripple);
ripple.style.top = clientY - ripple.clientHeight / 2 + "px";
ripple.style.left = clientX - ripple.clientWidth / 2 + "px";
ripple.addEventListener("animationend", () => {
cursor.removeChild(ripple);
});
}
document.addEventListener("click", createRipple);
document.addEventListener("touchstart", (e) => {
createRipple(e);
// Prevent the default touch event to avoid issues with click handling
e.preventDefault();
});
const preloaderBtn = document.querySelector(".preloader__btn");
let scale = 1;
let intervalId = null;
const preloaderHideThreshold = 18;
const preloaderHideGap = 0.175;
// Handle preloader button scaling for both mouse and touch events
function startScaling() {
clearInterval(intervalId);
intervalId = setInterval(() => {
scale += preloaderHideGap;
console.log(scale);
preloaderBtn.style.transform = `scale(${scale})`;
if (scale >= preloaderHideThreshold) {
alert("meow");
clearInterval(intervalId);
scale = 1;
}
}, 10);
}
function stopScaling() {
clearInterval(intervalId);
intervalId = setInterval(() => {
scale -= preloaderHideGap;
console.log(scale);
preloaderBtn.style.transform = `scale(${scale})`;
if (scale <= 1) {
clearInterval(intervalId);
scale = 1;
}
}, 10);
}
preloaderBtn.addEventListener("mousedown", startScaling);
preloaderBtn.addEventListener("touchstart", (e) => {
startScaling();
// Prevent the default touch event to avoid issues with click handling
e.preventDefault();
});
preloaderBtn.addEventListener("mouseup", stopScaling);
preloaderBtn.addEventListener("touchend", stopScaling);
preloaderBtn.addEventListener("touchcancel", stopScaling);
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.