canvas.air-horn
h1 Tap!
View Compiled
*
  box-sizing border-box

body
  background hsl(0, 0%, 25%)
  overflow hidden
  padding 0
  margin 0
  
h1
  position fixed
  right 2rem
  bottom 2rem
  font-family sans-serif
  color hsl(0, 0%, 15%)
  margin 0
  user-select none
            

canvas.air-horn
  height 100vh
  width 100vw
View Compiled
const { gsap: { timeline, utils: { random } }, PIXI: { Sprite, Texture, Application } } = window

const APP = new Application({
  antialias: true,
  transparent: true,
  height: window.innerHeight,
  width: window.innerWidth,
  view: document.querySelector('canvas.air-horn'),
  resizeTo: document.body,
  forceCanvas: true,
})

const TEXTURE = Texture.from('https://assets.codepen.io/605876/air-horn.png')

const fireHorn = () => {
  const horn = new Sprite(TEXTURE)
  APP.stage.addChild(horn)
  horn.scale.x = 0
  horn.scale.y = 0
  const resultScale = random(0.25, 0.6)
  timeline({
    onStart: () =>
      new Audio('https://assets.codepen.io/605876/air-horn.mp3').play(),
    onComplete: () => APP.stage.removeChild(horn),
  })
    .set(horn, {
      x: `random(${0.25 * window.innerWidth}, ${0.75 * window.innerWidth})`,
      y: `random(${0.25 * window.innerHeight}, ${0.75 * window.innerHeight})`,
      scale: { x: 0, y: 0 },
      transformOrigin: '50% 50%',
    })
    .to(
      horn.scale,
      { repeat: 1, yoyo: true, x: resultScale, y: resultScale, duration: 0.5 },
      0
    )
    .to(
      horn,
      { repeat: 1, yoyo: true, angle: 'random(-30, 30)', duration: 0.5 },
      0
    )
}

document.body.addEventListener('pointerdown', fireHorn)
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/gsap/3.3.2/gsap.min.js
  2. https://cdnjs.cloudflare.com/ajax/libs/pixi.js/5.2.4/pixi.min.js