Hi this is a bit of an odd question, I've seen similar effects to whats I'm going for but not exactly the same not sure if what I want to do is possible. I want to have two divs stacked with the contents of the div below revealed only in a specific area (around the cursor), is there a way to make only part of a div transparent? Or is there any other way to achieve this effect?
CodePudding user response:
Instead of having the element you want to show in the background you can put it in front and only show part of it via a clip-path;
For the coordinates I use CSS variables though you could also overwrite the style directly.
// Get element from the DOM
const container = document.querySelector('.container');
// Apply event listener
container.addEventListener('mousemove', updateCoords, false);
function updateCoords(event) {
// Get X and Y coordinates
const { offsetX, offsetY } = event;
// Update coordinates
container.style.setProperty('--x', offsetX 'px');
container.style.setProperty('--y', offsetY 'px');
}
.container {
border: 1px solid #000;
width: 300px;
height: 300px;
}
/* Show child when hovering the container */
.container:hover .child {
display: block;
}
.child {
clip-path: ellipse(30px 30px at var(--x) var(--y));
display: none;
}
<div class="container">
<img class="child" src="//picsum.photos/300" width="300" height="300" />
</div>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
You can use requestAnimationFrame to make the circle move more smoothly
// Get element from the DOM
const container = document.querySelector('.container');
// Apply event listener
container.addEventListener('mousemove', updateCoords, false);
function updateCoords(event) {
// Get X and Y coordinates
const { offsetX, offsetY } = event;
// Update coordinates
requestAnimationFrame(() => {
container.style.setProperty('--x', offsetX 'px');
container.style.setProperty('--y', offsetY 'px');
});
}
.container {
border: 1px solid #000;
width: 300px;
height: 300px;
}
/* Show child when hovering the container */
.container:hover .child {
display: block;
}
.child {
clip-path: ellipse(30px 30px at var(--x) var(--y));
display: none;
}
<div class="container">
<img class="child" src="//picsum.photos/300" width="300" height="300" />
</div>
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
Example with text
// Get element from the DOM
const container = document.querySelector('.container');
// Apply event listener
container.addEventListener('mousemove', updateCoords, false);
function updateCoords(event) {
// Get X and Y coordinates
const {offsetX, offsetY} = event;
// Update coordinates
requestAnimationFrame(() => {
container.style.setProperty('--x', offsetX 'px');
container.style.setProperty('--y', offsetY 'px');
});
}
.container {
min-height: 100vh;
min-width: 100vh;
overflow: hidden;
}
.container:hover .code {
display: flex;
}
.display,
.code {
position: absolute;
display: flex;
align-items: center;
justify-content: center;
width: 100vw;
height: 100vh;
background-color: rgb(49, 49, 49);
color: rgb(240, 191, 29);
pointer-events: none;
}
.code {
clip-path: ellipse(100px 100px at var(--x) var(--y));
display: none;
background-color: rgb(3, 3, 3);
color: rgb(101, 253, 101);
}
<div class="container">
<div class="display">
<h1>Header</h1>
</div>
<div class="code">
<h3><h1>Header</h1></h3>
</div>
</div>
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>