Skip to content

Instantly share code, notes, and snippets.

@pedrocruzio
Created February 4, 2022 22:08
Show Gist options
  • Save pedrocruzio/7bc209bce156d2d9f24dc28d934aa01e to your computer and use it in GitHub Desktop.
Save pedrocruzio/7bc209bce156d2d9f24dc28d934aa01e to your computer and use it in GitHub Desktop.
Touch/Click Image Reveal
<div class="container">
<div class="image-reveal">
<img src="https://picsum.photos/seed/revealinitial/800/600" alt="Reveal Image" class="image-reveal__image">
<canvas class="image-reveal__canvas"></canvas>
</div>
<button class="reset">Reset</button>
</div>
const canvas = document.querySelector('.image-reveal__canvas')
const canvasParent = canvas.parentNode
const resetButton = document.querySelector('.reset')
const ctx = canvas.getContext('2d')
const radius = 50
const image = new Image()
const drawImage = ()=> {
ctx.drawImage(image, 0, 0, image.width, image.height)
}
const punchOutCircle = (x, y)=> {
const widthRatio = canvas.scrollWidth / canvas.width
const heightRatio = canvas.scrollHeight / canvas.height
ctx.save()
ctx.beginPath()
ctx.arc(x / widthRatio, y / heightRatio, radius, 0, 2 * Math.PI)
ctx.closePath()
ctx.clip()
ctx.clearRect(0, 0, canvas.width, canvas.height)
ctx.restore()
}
const getThemCoords = e => {
if (e.touches) {
Array.from(e.touches).forEach(getThemCoords)
return
}
const rect = e.target.getBoundingClientRect()
const x = e.clientX - rect.left
const y = e.clientY - rect.top
punchOutCircle(x, y)
}
const removeListener = () => {
canvas.removeEventListener('mousemove', getThemCoords)
}
canvas.addEventListener('mouseup', removeListener)
canvas.addEventListener('mouseleave', removeListener)
canvas.addEventListener('mousedown', e => {
getThemCoords(e)
canvas.addEventListener('mousemove', getThemCoords)
})
canvasParent.addEventListener('touchstart', getThemCoords)
canvasParent.addEventListener('touchmove', e => {
e.preventDefault()
getThemCoords(e)
})
resetButton.addEventListener('click', drawImage)
image.onload = ()=> {
canvas.width = image.width
canvas.height = image.height
drawImage()
}
image.src = 'https://picsum.photos/seed/revealoverlay/800/600'
.container
text-align center
padding 30px
.image-reveal
display inline-block
position relative
border-radius 4px
box-shadow 0 19px 38px rgba(black, 0.30), 0 15px 12px rgba(black, 0.22)
overflow hidden
user-select none
cursor pointer
&__image
display block
max-width 100%
height auto
&__canvas
position absolute
top 0
left 0
right 0
bottom 0
width 100%
height 100%
.reset
appearance none
display flex
justify-content center
align-items center
background-color green
color white
padding 20px
border 0
border-radius 4px
box-shadow 0 1px 3px rgba(black, 0.12), 0 1px 2px rgba(black, 0.24)
margin 30px auto 0
transition box-shadow 250ms, transform 250ms
cursor pointer
&:hover
box-shadow 0 14px 28px rgba(black, 0.25), 0 10px 10px rgba(black, 0.22)
transform translateY(-5px)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment