I’m making a website that I wanted to be a white page that you could stamp to make another image appear under. So when you click, you make a holepunch. Like this exemple :
So I managed to have a randomized image in the background as I click which is fine for what I want, and to be able to .append()
the holepunches.
But I don’t know how to do the mask thing I’ve been digging online for a few things and help, and managed to make it work in certain cases but not that one…
It should be like that (I guess) :
- image in the background
- white shape in front
- the star shape is making a holepunch in the white shape
For now, the only thing I managed to do is to have the picture besides a bigger holepunch (which is my original img) but when I click it doesn’t make any holepunch, it justs add the stamp.
Here is the code :
var images = ["https://icatcare.org/app/uploads/2018/07/Thinking-of-getting-a-cat.png", "https://ichef.bbci.co.uk/news/1024/cpsprodpb/151AB/production/_111434468_gettyimages-1143489763.jpg"]; $(document.body).click(function(c) { var tw = 100 / 2; var th = 30 / 2; var x = Math.floor((Math.random() * images.length)); document.getElementById('random').src = images[x]; $("#random").css({ position: 'absolute', display: "block", left: 0, top: 0 }); var tw = 50 / 2; var th = tw; $('#holepunch:last').clone().appendTo(this).css({ position: 'absolute', display: "block", left: c.pageX - tw - $(this).position().left, top: c.pageY - th + $(this).scrollTop() }); });
body{ background: lightgrey; width: 100vw; height: 100vh; z-index: 1; opacity: 1; } .fauxbody{ z-index: 100; position: fixed; width: 100vw; height: 100vh; background-color: white; top: 0; left: 0; -webkit-mask: -moz-element(#holepunch) 1vw 1vh no-repeat, linear-gradient(#fff 0 0); mask-composite:exclude; } #random{ z-index: -100; width: 100vw; height: auto; } #holepunch{ width: 50px; height: auto; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <body> <img id="random"> <div class ="fauxbody"> <img id="holepunch" src="https://oshi.at/iimtXg/Jqtz.png"> </div> </body>
Advertisement
Answer
Here is an idea using multiple mask and CSS variables. The trick is to add an extra layer on each click. I removed the code related to background generation since it’s irrelevant and quite easy to be added
var mask = ""; w = 60; h = 60; document.documentElement.addEventListener("click", function (c) { mask+="url(https://i.ibb.co/FzmCjLL/Jqtz.png)"+(c.pageX-w/2)+"px "+(c.pageY-h/2)+"px/"+w+"px "+h+"px no-repeat,"; document.documentElement.style.setProperty("--mask", mask) });
html { background:url(https://picsum.photos/800/800) center/cover; } html::before { content:""; position: fixed; background-color: #f3f3f3; inset: 0; -webkit-mask: var(--mask) linear-gradient(#fff 0 0); -webkit-mask-reepat: no-repeat; -webkit-mask-composite: destination-out; mask-composite: exclude; }
Also like below without mask-composite
:
var mask = ""; w = 60; h = 60; document.documentElement.addEventListener("click", function(c) { if (mask != "") mask += ","; mask += "url(https://i.ibb.co/FzmCjLL/Jqtz.png)" + (c.pageX - w / 2) + "px " + (c.pageY - h / 2) + "px/" + w + "px " + h + "px no-repeat"; document.documentElement.style.setProperty("--mask", mask) });
html::before { content: ""; position: fixed; background: url(https://picsum.photos/800/800) center/cover; inset: 0; -webkit-mask: var(--mask, linear-gradient(#0000 0 0)); }