Skip to content

Instantly share code, notes, and snippets.

@dayitv89
Last active September 6, 2022 12:44
Show Gist options
  • Save dayitv89/63c8d3796dce69ef09dbd6ddde0bb974 to your computer and use it in GitHub Desktop.
Save dayitv89/63c8d3796dce69ef09dbd6ddde0bb974 to your computer and use it in GitHub Desktop.
Harry Potter stick as luminous effect (prakashit bhava)
<html>
<head>
<style>
html,
body {
width: 100%;
height: 100%;
margin: 0;
}
*,
*:before,
*:after {
box-sizing: border-box;
position: relative;
}
.luminus-block {
cursor: none;
width: 100%;
height: 100%;
display: grid;
background-color: #000000;
/* extra content to be removed */
display: flex;
justify-content: center;
align-items: center;
}
.luminus-content {
--x-px: calc(var(--x) * 1px);
--y-px: calc(var(--y) * 1px);
overflow: hidden;
}
.luminus-content:before,
.luminus-content:after {
content: "";
display: block;
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
inset: 0px;
border-radius: inherit;
background: radial-gradient(200px circle at var(--x-px) var(--y-px), rgba(255, 255, 255, 0.2), transparent 50%);
}
.luminus-content:before {
z-index: 1;
}
.luminus-content:after {
opacity: 0;
z-index: 2;
transition: opacity 0.4s ease;
}
.luminus-content:hover:after {
opacity: 1;
}
.features {
width: 75vw;
height: 50vh;
display: grid;
grid-column-gap: 0.3rem;
grid-row-gap: 0.3rem;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(2, 1fr);
}
.feature {
--border: 2px;
background: rgba(255, 255, 255, 0.125);
border-radius: 0.5rem;
overflow: hidden;
}
.feature-content {
background: #131315;
border-radius: inherit;
color: white;
text-decoration: none;
z-index: 1;
position: absolute;
inset: var(--border);
display: grid;
grid-template-rows: 1fr 1fr;
grid-row-gap: 0.5rem;
padding: 0 1rem 0 2rem;
}
.feature-content>strong {
align-self: self-end;
font-size: 125%;
}
.feature-content>span {
opacity: 0.7;
}
</style>
</head>
<body>
<div class="luminus-block luminus-content">
<div class="features">
<div class="feature">
<a href="#" class="feature-content">
<strong>Some feature</strong>
<span>Description of the awesome feature</span>
</a>
</div>
<div class="feature">
<a href="#" class="feature-content">
<strong>Some feature</strong>
<span>Description of the awesome feature</span>
</a>
</div>
<div class="feature">
<a href="#" class="feature-content">
<strong>Some feature</strong>
<span>Description of the awesome feature</span>
</a>
</div>
<div class="feature">
<a href="#" class="feature-content">
<strong>Some feature</strong>
<span>Description of the awesome feature</span>
</a>
</div>
<div class="feature">
<a href="#" class="feature-content">
<strong>Some feature</strong>
<span>Description of the awesome feature</span>
</a>
</div>
<div class="feature">
<a href="#" class="feature-content">
<strong>Some feature</strong>
<span>Description of the awesome feature</span>
</a>
</div>
</div>
</div>
<script>
console.clear();
const luminusBlockEl = document.querySelector(".luminus-block");
const luminusContentEl = document.querySelector(".luminus-content");
luminusBlockEl.addEventListener("pointermove", (ev) => {
const rect = luminusContentEl.getBoundingClientRect();
luminusContentEl.style.setProperty("--x", ev.clientX - rect.left);
luminusContentEl.style.setProperty("--y", ev.clientY - rect.top);
});
</script>
</body>
</html>
<html>
<head>
<style>
html,
body {
width: 100%;
height: 100%;
margin: 0;
}
*,
*:before,
*:after {
box-sizing: border-box;
position: relative;
}
.luminus-block {
/* cursor: pointer; */
cursor: auto;
width: 100%;
height: 100%;
display: grid;
background-color: #000000;
/* extra content to be removed */
display: flex;
justify-content: center;
align-items: center;
}
.luminus-content {
--x-px: calc(var(--x) * 1px);
--y-px: calc(var(--y) * 1px);
overflow: hidden;
}
.luminus-content:before,
.luminus-content:after {
content: "";
display: block;
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
inset: 0px;
border-radius: inherit;
background: radial-gradient(200px circle at var(--x-px) var(--y-px), rgba(255, 255, 255, 0.6), rgba(255, 255, 255, 0.3), rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0.002), transparent 50%);
}
.luminus-content:before {
z-index: 1;
}
.luminus-content:after {
opacity: 0;
z-index: 2;
transition: opacity 0.4s ease;
}
.luminus-content:hover:after {
opacity: 1;
}
.cursor-dot,
.cursor-dot-outline {
pointer-events: none;
position: absolute;
top: 50%;
left: 50%;
border-radius: 50%;
opacity: 0;
transform: translate(-50%, -50%);
transition: opacity 0.3s ease-in-out, transform 0.3s ease-in-out;
}
.cursor-dot {
width: 8px;
height: 8px;
background-color: #FFF;
}
.cursor-dot-outline {
width: 40px;
height: 40px;
background-color: rgba(255, 255, 255, 0.2);
}
.features {
width: 75vw;
height: 50vh;
display: grid;
grid-column-gap: 0.3rem;
grid-row-gap: 0.3rem;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(2, 1fr);
}
.feature {
--border: 2px;
background: rgba(255, 255, 255, 0.125);
border-radius: 0.5rem;
overflow: hidden;
}
.feature-content {
cursor: pointer !important;
background: #131315;
border-radius: inherit;
color: white;
text-decoration: none;
z-index: 1;
position: absolute;
inset: var(--border);
display: grid;
grid-template-rows: 1fr 1fr;
grid-row-gap: 0.5rem;
padding: 0 1rem 0 2rem;
}
.feature-content>strong {
align-self: self-end;
font-size: 125%;
}
.feature-content>span {
opacity: 0.7;
}
</style>
</head>
<body class="luminus-block luminus-content">
<div class="cursor-dot-outline"></div>
<div class="cursor-dot"></div>
<div class="features">
<div class="feature">
<a href="#" class="feature-content">
<strong>Some feature</strong>
<span>Description of the awesome feature</span>
</a>
</div>
<div class="feature">
<a href="#" class="feature-content">
<strong>Some feature</strong>
<span>Description of the awesome feature</span>
</a>
</div>
<div class="feature">
<a href="#" class="feature-content">
<strong>Some feature</strong>
<span>Description of the awesome feature</span>
</a>
</div>
<div class="feature">
<a href="#" class="feature-content">
<strong>Some feature</strong>
<span>Description of the awesome feature</span>
</a>
</div>
<div class="feature">
<a href="#" class="feature-content">
<strong>Some feature</strong>
<span>Description of the awesome feature</span>
</a>
</div>
<div class="feature">
<a href="#" class="feature-content">
<strong>Some feature</strong>
<span>Description of the awesome feature</span>
</a>
</div>
</div>
<script>
console.clear();
const luminusBlockEl = document.querySelector(".luminus-block");
const luminusContentEl = document.querySelector(".luminus-content");
luminusBlockEl.addEventListener("pointermove", (ev) => {
const rect = luminusContentEl.getBoundingClientRect();
luminusContentEl.style.setProperty("--x", ev.clientX - rect.left);
luminusContentEl.style.setProperty("--y", ev.clientY - rect.top);
});
</script>
<script>
var cursor = {
delay: 8,
_x: 0,
_y: 0,
endX: (window.innerWidth / 2),
endY: (window.innerHeight / 2),
cursorVisible: true,
cursorEnlarged: false,
$dot: document.querySelector('.cursor-dot'),
$outline: document.querySelector('.cursor-dot-outline'),
init: function () {
// Set up element sizes
this.dotSize = this.$dot.offsetWidth;
this.outlineSize = this.$outline.offsetWidth;
this.setupEventListeners();
this.animateDotOutline();
},
// updateCursor: function(e) {
// var self = this;
// console.log(e)
// // Show the cursor
// self.cursorVisible = true;
// self.toggleCursorVisibility();
// // Position the dot
// self.endX = e.pageX;
// self.endY = e.pageY;
// self.$dot.style.top = self.endY + 'px';
// self.$dot.style.left = self.endX + 'px';
// },
setupEventListeners: function () {
var self = this;
// Anchor hovering
document.querySelectorAll('a').forEach(function (el) {
el.addEventListener('mouseover', function () {
self.cursorEnlarged = true;
self.toggleCursorSize();
});
el.addEventListener('mouseout', function () {
self.cursorEnlarged = false;
self.toggleCursorSize();
});
});
// Click events
document.addEventListener('mousedown', function () {
self.cursorEnlarged = true;
self.toggleCursorSize();
});
document.addEventListener('mouseup', function () {
self.cursorEnlarged = false;
self.toggleCursorSize();
});
document.addEventListener('mousemove', function (e) {
// Show the cursor
self.cursorVisible = true;
self.toggleCursorVisibility();
// Position the dot
self.endX = e.pageX;
self.endY = e.pageY;
self.$dot.style.top = self.endY + 'px';
self.$dot.style.left = self.endX + 'px';
});
// Hide/show cursor
document.addEventListener('mouseenter', function (e) {
self.cursorVisible = true;
self.toggleCursorVisibility();
self.$dot.style.opacity = 1;
self.$outline.style.opacity = 1;
});
document.addEventListener('mouseleave', function (e) {
self.cursorVisible = true;
self.toggleCursorVisibility();
self.$dot.style.opacity = 0;
self.$outline.style.opacity = 0;
});
},
animateDotOutline: function () {
var self = this;
self._x += (self.endX - self._x) / self.delay;
self._y += (self.endY - self._y) / self.delay;
self.$outline.style.top = self._y + 'px';
self.$outline.style.left = self._x + 'px';
requestAnimationFrame(this.animateDotOutline.bind(self));
},
toggleCursorSize: function () {
var self = this;
if (self.cursorEnlarged) {
self.$dot.style.transform = 'translate(-50%, -50%) scale(0.75)';
self.$outline.style.transform = 'translate(-50%, -50%) scale(1.5)';
} else {
self.$dot.style.transform = 'translate(-50%, -50%) scale(1)';
self.$outline.style.transform = 'translate(-50%, -50%) scale(1)';
}
},
toggleCursorVisibility: function () {
var self = this;
if (self.cursorVisible) {
self.$dot.style.opacity = 1;
self.$outline.style.opacity = 1;
} else {
self.$dot.style.opacity = 0;
self.$outline.style.opacity = 0;
}
}
}
cursor.init();
</script>
</body>
</html>
<html>
<head>
<style>
html,
body {
width: 100%;
height: 100%;
margin: 0;
}
*,
*:before,
*:after {
box-sizing: border-box;
position: relative;
}
.luminus-block {
/* cursor: pointer; */
cursor: auto;
width: 100%;
height: 100%;
display: grid;
background-color: #000000;
/* extra content to be removed */
display: flex;
justify-content: center;
align-items: center;
}
.luminus-content {
--x-px: calc(var(--x) * 1px);
--y-px: calc(var(--y) * 1px);
overflow: hidden;
}
.luminus-content:before,
.luminus-content:after {
content: "";
display: block;
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
inset: 0px;
border-radius: inherit;
background: radial-gradient(200px circle at var(--x-px) var(--y-px), rgba(255, 255, 255, 0.6), rgba(255, 255, 255, 0.3), rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0.002), transparent 50%);
}
.luminus-content:before {
z-index: 1;
}
.luminus-content:after {
opacity: 0;
z-index: 2;
transition: opacity 0.4s ease;
}
.luminus-content:hover:after {
opacity: 1;
}
.cursor-dot,
.cursor-dot-outline {
pointer-events: none;
position: absolute;
top: 50%;
left: 50%;
border-radius: 50%;
opacity: 0;
transform: translate(-50%, -50%);
transition: opacity 0.3s ease-in-out, transform 0.3s ease-in-out;
}
.cursor-dot {
width: 8px;
height: 8px;
background-color: #FFF;
}
.cursor-dot-outline {
width: 40px;
height: 40px;
background-color: rgba(255, 255, 255, 0.2);
}
.features {
width: 75vw;
height: 50vh;
display: grid;
grid-column-gap: 0.3rem;
grid-row-gap: 0.3rem;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(2, 1fr);
}
.feature {
--border: 2px;
background: rgba(255, 255, 255, 0.125);
border-radius: 0.5rem;
overflow: hidden;
}
.feature-content {
cursor: pointer !important;
background: #131315;
border-radius: inherit;
color: white;
text-decoration: none;
z-index: 1;
position: absolute;
inset: var(--border);
display: grid;
grid-template-rows: 1fr 1fr;
grid-row-gap: 0.5rem;
padding: 0 1rem 0 2rem;
}
.feature-content>strong {
align-self: self-end;
font-size: 125%;
}
.feature-content>span {
opacity: 0.7;
}
</style>
</head>
<body class="luminus-block luminus-content">
<div class="cursor-dot-outline"></div>
<div class="cursor-dot"></div>
<div class="features">
<div class="feature">
<a href="#" class="feature-content">
<strong>Some feature</strong>
<span>Description of the awesome feature</span>
</a>
</div>
<div class="feature">
<a href="#" class="feature-content">
<strong>Some feature</strong>
<span>Description of the awesome feature</span>
</a>
</div>
<div class="feature">
<a href="#" class="feature-content">
<strong>Some feature</strong>
<span>Description of the awesome feature</span>
</a>
</div>
<div class="feature">
<a href="#" class="feature-content">
<strong>Some feature</strong>
<span>Description of the awesome feature</span>
</a>
</div>
<div class="feature">
<a href="#" class="feature-content">
<strong>Some feature</strong>
<span>Description of the awesome feature</span>
</a>
</div>
<div class="feature">
<a href="#" class="feature-content">
<strong>Some feature</strong>
<span>Description of the awesome feature</span>
</a>
</div>
</div>
<script>
console.clear();
const luminusBlockEl = document.querySelector(".luminus-block");
const luminusContentEl = document.querySelector(".luminus-content");
luminusBlockEl.addEventListener("pointermove", (ev) => {
const rect = luminusContentEl.getBoundingClientRect();
luminusContentEl.style.setProperty("--x", ev.clientX - rect.left);
luminusContentEl.style.setProperty("--y", ev.clientY - rect.top);
});
</script>
<script>
var cursor = {
delay: 8,
_x: 0,
_y: 0,
endX: (window.innerWidth / 2),
endY: (window.innerHeight / 2),
cursorVisible: true,
cursorEnlarged: false,
$dot: document.querySelector('.cursor-dot'),
$outline: document.querySelector('.cursor-dot-outline'),
init: function () {
// Set up element sizes
this.dotSize = this.$dot.offsetWidth;
this.outlineSize = this.$outline.offsetWidth;
this.setupEventListeners();
this.animateDotOutline();
},
// updateCursor: function(e) {
// var self = this;
// console.log(e)
// // Show the cursor
// self.cursorVisible = true;
// self.toggleCursorVisibility();
// // Position the dot
// self.endX = e.pageX;
// self.endY = e.pageY;
// self.$dot.style.top = self.endY + 'px';
// self.$dot.style.left = self.endX + 'px';
// },
setupEventListeners: function () {
var self = this;
// Anchor hovering
document.querySelectorAll('a').forEach(function (el) {
el.addEventListener('mouseover', function () {
self.cursorEnlarged = true;
self.toggleCursorSize();
});
el.addEventListener('mouseout', function () {
self.cursorEnlarged = false;
self.toggleCursorSize();
});
});
// Click events
document.addEventListener('mousedown', function () {
self.cursorEnlarged = true;
self.toggleCursorSize();
});
document.addEventListener('mouseup', function () {
self.cursorEnlarged = false;
self.toggleCursorSize();
});
document.addEventListener('mousemove', function (e) {
// Show the cursor
self.cursorVisible = true;
self.toggleCursorVisibility();
// Position the dot
self.endX = e.pageX;
self.endY = e.pageY;
self.$dot.style.top = self.endY + 'px';
self.$dot.style.left = self.endX + 'px';
});
// Hide/show cursor
document.addEventListener('mouseenter', function (e) {
self.cursorVisible = true;
self.toggleCursorVisibility();
self.$dot.style.opacity = 1;
self.$outline.style.opacity = 1;
});
document.addEventListener('mouseleave', function (e) {
self.cursorVisible = true;
self.toggleCursorVisibility();
self.$dot.style.opacity = 0;
self.$outline.style.opacity = 0;
});
},
animateDotOutline: function () {
var self = this;
self._x += (self.endX - self._x) / self.delay;
self._y += (self.endY - self._y) / self.delay;
self.$outline.style.top = self._y + 'px';
self.$outline.style.left = self._x + 'px';
requestAnimationFrame(this.animateDotOutline.bind(self));
},
toggleCursorSize: function () {
var self = this;
if (self.cursorEnlarged) {
self.$dot.style.transform = 'translate(-50%, -50%) scale(0.75)';
self.$outline.style.transform = 'translate(-50%, -50%) scale(1.5)';
} else {
self.$dot.style.transform = 'translate(-50%, -50%) scale(1)';
self.$outline.style.transform = 'translate(-50%, -50%) scale(1)';
}
},
toggleCursorVisibility: function () {
var self = this;
if (self.cursorVisible) {
self.$dot.style.opacity = 1;
self.$outline.style.opacity = 1;
} else {
self.$dot.style.opacity = 0;
self.$outline.style.opacity = 0;
}
}
}
cursor.init();
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment