Pen Settings

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URL's added here will be added as <link>s in order, and before the CSS in the editor. If you link to another Pen, it will include the CSS from that Pen. If the preprocessor matches, it will attempt to combine them before processing.

+ add another resource

You're using npm packages, so we've auto-selected Babel for you here, which we require to process imports and make it all work. If you need to use a different JavaScript preprocessor, remove the packages in the npm tab.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Use npm Packages

We can make npm packages available for you to use in your JavaScript. We use webpack to prepare them and make them available to import. We'll also process your JavaScript with Babel.

⚠️ This feature can only be used by logged in users.

Code Indentation

     

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

HTML Settings

Here you can Sed posuere consectetur est at lobortis. Donec ullamcorper nulla non metus auctor fringilla. Maecenas sed diam eget risus varius blandit sit amet non magna. Donec id elit non mi porta gravida at eget metus. Praesent commodo cursus magna, vel scelerisque nisl consectetur et.

            
              <main>
    <div class="static">
        <h1 class="js-heading">FOOTBALL LEAGUE</h1>
        <p class="js-subheading">Experimental team line-up and football field using CSS 3D transforms.<br><span style="font-size: 11px">Currently buggy in Chrome, will fix soon :)</span></p>
        <div class="js-switcher switcher">
            <a href="#" class="js-switch disabled switch-btn">HOME</a><a href="#" class="js-switch switch-btn">AWAY</a>
        </div>
    </div>
    <div class="js-stage stage texture">
        <div class="js-world world">
            <div class="team js-team">
                <!-- Team cards / icons goes here -->
            </div>
            <div class="terrain js-terrain">
                <div class="field field--alt"></div>
                <div class="field ground">
                    <div class="field__texture field__texture--gradient"></div>
                    <div class="field__texture field__texture--gradient-b"></div>
                    <div class="field__texture field__texture--grass"></div>
                    <div class="field__line field__line--goal"></div>
                    <div class="field__line field__line--goal field__line--goal--far"></div>
                    <div class="field__line field__line--outline"></div>
                    <div class="field__line field__line--penalty"></div>
                    <div class="field__line field__line--penalty-arc"></div>
                    <div class="field__line field__line--penalty-arc field__line--penalty-arc--far"></div>
                    <div class="field__line field__line--mid"></div>
                    <div class="field__line field__line--circle"></div>
                    <div class="field__line field__line--penalty field__line--penalty--far"></div>
                </div>
                <div class="field__side field__side--front"></div>
                <div class="field__side field__side--left"></div>
                <div class="field__side field__side--right"></div>
                <div class="field__side field__side--back"></div>
            </div>
        </div>
        <div class="loading js-loading">PLEASE WAIT...</div>
    </div>
    </main>
            
          
!
            
              // Palette
$body-bg-color      = #2a437c
$body-bg-color-2    = #10203b
$colors-text-def    = #333
$colors-text-med    = #777
$colors-text-lt     = #aaa
$colors-card-bg1    = #f7f7f7
$colors-card-bg2    = #eeeeee
$colors-card-bg3    = #1d2643
$colors-card-txt    = #a40028
$field-bg-color     = #eeeeee
$field-side-color   = #f7f7f7
$line-color         = rgba(255,255,255,0.5)
$texture-field-side = #141d2b

// Field dimensions
$stage-perspective  = 1100px
$field-y            = 840px
$field-x            = ($field-y * 0.8)
$field-ratio        = ($field-x / $field-y)
$field-side-y       = 8px
$field-rot          = 90deg
$field-buffer       = 4%
$line-x             = 3px
$line-circle-x      = 25%

// Player dimensions
$player-x           = 65px
$card-x             = 230px
$card-y             = 260px

// Codepen asset mixin
asset(filename='blank.gif')
  background-image: url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/215059/' filename)

*
  box-sizing: border-box

html, body
  width: 100%
  height: 100%
  font-size: 62.5%
  padding: 0
  margin: 0

.velocity-animating
  transition: none !important

body
  background-image: -webkit-radial-gradient(ellipse, $body-bg-color 0, $body-bg-color-2 100%)
  font-family: 'Open Sans', helvetica, arial, sans-serif

main
  opacity: 0

.static
  position: absolute
  top: 0
  left: 0
  width: 100%
  color: #fff
  text-align: center
  padding:  0
  z-index: 3

  h1
    margin: 50px 0 15px
    font-size: 50px
    font-weight: 800
    text-transform: uppercase
    line-height: 42px
    letter-spacing: -3px
    font-family: montserrat

  p
    font-weight: 300
    opacity: 0.4
    margin: 0 0 20px
    font-size: 16px
    color: lighten($body-bg-color, 50%)

.loading
  position: absolute
  top: 0
  right: 0
  bottom: 0
  left: 0
  margin: auto
  height: 16px
  line-height: 16px
  color: #fff
  font-family: 'montserrat'
  font-size: 24px
  font-weight: 900
  letter-spacing: -1px
  text-align: center
  opacity: 0

.team-list
  position: absolute
  left: 40px
  top: 100px
  list-style: none
  display: none

  li:first-child
    color: #fff
    font-weight: bold

  li
    font-size: 1.4rem
    margin: 0 0 10px
    color: lighten($body-bg-color, 50%)

.stage
  position: absolute
  width: 100%
  height: 100%
  top: 0
  perspective-origin: 50% -200px
  perspective: $stage-perspective
  z-index: 1
  backface-visibility: hidden

.world
  position: absolute
  top: 130px
  left: 50%
  margin-left: -($field-x / 2)
  width: $field-x
  height: $field-y
  transform: translateZ(-($field-y / 4))
  transform-style: preserve-3d
  z-index: 1
  backface-visibility: hidden

  &.flipped
    transform: translateZ(-($field-y / 4)) rotateY(180deg)

  &.switched
    transform: translateZ(250px) rotateY(30deg) translateX(60px) translateY(-200px)

.switch-btn
  display: inline-block
  padding: 6px 15px
  border: solid 1px lighten($body-bg-color, 50%)
  border-radius: 5px
  text-align: center
  color: lighten($body-bg-color, 50%)
  text-decoration: none
  opacity: 1
  font-size: 12px
  transition: all 0.15s

  &.disabled
    background: lighten($body-bg-color, 50%)
    color: $body-bg-color
    cursor: default

    &:hover
      color: $body-bg-color

  &:hover
    color: #fff

  &:first-child
    border-radius: 10px 0 0 10px
    border-right: none

  &:last-child
    border-radius: 0 10px 10px 0

.team
  position: absolute
  top: 0
  left: 0
  width: 100%
  height: 100%
  transform-style: preserve-3d

.terrain
  position: absolute
  top: 0
  left: 0
  width: 100%
  height: 100%
  transform-style: inherit

.field
  position: absolute
  top: 0
  left: 0
  width: 100%
  height: 100%
  background-color: $field-bg-color
  z-index: 2
  transform: rotateX($field-rot) translateZ(0)
  transform-origin: 50% 50%
  box-sizing: content-box
  backface-visibility: hidden

.field--alt
  display: block
  width: 80%
  left: 10%
  transform: rotateX($field-rot) translateZ(-10px)
  background: black
  opacity: 0.3
  box-shadow: 0 0 40px 30px #000

.field__texture
  width: 100%
  height: 100%
  position: absolute
  z-index: 3

  &.field__texture--gradient
    background-image: linear-gradient(to top, rgba(0,0,0,0.2), transparent)
    z-index: 4

    .flipped &
      opacity: 0

  &.field__texture--gradient-b
    opacity: 0
    background-image: linear-gradient(to bottom, rgba(0,0,0,0.2), transparent)
    z-index: 4

    .flipped &
      opacity: 1

  .texture &
    &.field__texture--grass
      asset('grass2.png')
      background-repeat: repeat
      background-size: 75px 75px
      background-position: -20px -20px


.field__side
  position: absolute
  top: ($field-y / 2)
  left: 0
  width: 100%
  height: $field-side-y
  transform: rotateX($field-rot * 2) translateZ(-($field-y / 2))
  transform-origin: 50% 50%
  background-color: $field-side-color
  z-index: 9

  .texture &
    background-color: black

    &:after
      content: ""
      top: 0
      left: 0
      bottom: 0
      right: 0
      position: absolute
      opacity: 0.55
      asset('mud.png')
      background-repeat: repeat
      background-size: 75px 75px
      background-position: -20px -20px

  &.field__side--left,
  &.field__side--right
    top: 0
    left: -($field-side-y)
    height: 100%
    width: $field-side-y
    transform-origin: 100% 50%
    transform: rotateX($field-rot) rotateY(-90deg) translateZ(0)

  &.field__side--right
    left: auto
    right: 0

  &.field__side--back
    transform: rotateX($field-rot * 2) translateZ(($field-y / 2))

.field__line
  position: absolute
  width: 100%
  height: $line-x
  z-index: 4

.field__line--goal
  width: 16%
  height: 6%
  border: solid $line-x $line-color
  border-bottom: none
  left: 0
  right: 0
  margin: auto
  bottom: $field-buffer

.field__line--goal--far
  top: $field-buffer
  bottom: auto
  border: solid $line-x $line-color
  border-top: none

.field__line--penalty-arc
  width: 20%
  height: 20%
  overflow: hidden
  bottom: ($field-buffer + 16%)
  left: 0
  right: 0
  margin: auto

  &:after
    position: absolute
    top: 75%
    width: 100%
    height: 100%
    left: 0
    content: ' '
    display: block
    border-radius: 50% 50% 0 0
    border: solid $line-x $line-color
    border-bottom: none
    box-sizing: border-box

.field__line--penalty-arc--far
  bottom: auto
  top: ($field-buffer + 16%)

  &:after
    bottom: 75%
    top: auto
    border: solid $line-x $line-color
    border-top: none
    border-radius: 0 0 50% 50%


.field__line--penalty
  width: 44%
  height: 16%
  border: solid $line-x $line-color
  border-bottom: none
  left: 0
  right: 0
  margin: auto
  bottom: $field-buffer

.field__line--penalty--far
  top: $field-buffer
  bottom: auto
  border: solid $line-x $line-color
  border-top: none

.field__line--outline
  width: (100% - ($field-buffer * 2))
  height: (100% - ($field-buffer * 2))
  top: $field-buffer
  left: $field-buffer
  border: solid $line-x $line-color

.field__line--mid
  top: 50%
  width: (100% - ($field-buffer * 2))
  left: $field-buffer
  background-color: $line-color

.field__line--circle
  width: 20%
  height: 20%
  top:  0
  left: 0
  right: 0
  bottom: 0
  margin: auto
  border: solid $line-x $line-color
  border-radius: 50%

.debug-btn
  position: absolute
  right: 40px
  top: 40px
  border: solid 1px #fff
  border-radius: 10px
  height: 20px
  padding: 0 10px
  color: #fff
  text-decoration: none
  line-height: 20px

  &:hover
    opacity: 1
    background-color: rgba(255, 255, 255, 0.1)

  &.debug-btn--load
    top: 80px

.player
  position: absolute
  height: $player-x + 23px
  width: $player-x
  padding-bottom: 23px
  z-index: 9
  left: 50%
  margin-left: -($player-x / 2)
  bottom: 50%
  transform-style: preserve-3d
  backface-visibility: hidden
  transition: all 0.2s
  cursor: pointer

  .player__placeholder
    position: absolute
    opacity: 0
    transform: rotateX(90deg)
    height: 30px
    width: 30px
    bottom: -10px
    left: 0
    right: 0
    margin: auto
    border-radius: 50%
    background-color: rgba(0, 0, 0, 0.2)
    z-index: 1

  &.active
    .player__placeholder
      opacity: 1

  .player__card
    position: absolute
    bottom: 26px
    left: (($player-x / 2) - ($card-x / 2))
    height: $card-y
    background-color: $colors-card-bg1
    opacity: 0
    width: $card-x
    padding: 0
    font-size: 18px
    color: #333
    border-radius: 4px
    z-index: 2
    //overflow: hidden

    &:after
      position: absolute
      display: block
      content: ''
      height: 1px
      width: 1px
      border: solid 10px transparent
      border-top: solid 10px $colors-card-bg2
      bottom: -21px
      left: 0
      right: 0
      margin: auto
      top: auto
      z-index: 3

    i
      position: absolute
      top: 0px
      right: 0px
      padding: 10px 15px
      font-size: 24px
      line-height: 20px
      color: white
      opacity: 0.3
      cursor: pointer
      transition: all 0.15s

      &:hover
        opacity: 0.6

    h3
      text-align: center
      font-weight: normal
      text-transform: uppercase
      font-family: montserrat
      font-size: 19px
      line-height: 27px
      color: $colors-text-def
      color: white
      padding: 15px 30px 40px
      margin: 0 0 30px
      background-color: #eee
      border-radius: 4px 4px 0 0
      background-color: desaturate(darken($body-bg-color, 45%), 10%)

      span:first-child
        display: inline-block
        height: 27px
        width: 27px
        border-radius: 50%
        border: solid 1px #fff
        line-height: 27px
        opacity: 0.4
        font-size: 18px

      span:last-child
        font-size: 14px
        opacity: 0.4
    p
      color: $colors-text-med
      font-syle: italic
      text-align: center

    .player__card__list
      padding: 10px 0
      font-size: 14px
      color: $colors-text-med
      overflow: auto
      text-align: center

      li
        display: inline-block
        white-space: nowrap
        text-overflow: ellipsis
        text-align: center
        font-size: 15px
        padding-left: 20px
        color: $colors-text-def
        //border-left: solid 1px #ddd

        span
          font-size: 12px
          text-transform: uppercase
          color: $colors-text-lt

        &:first-child
          padding-left: 0
          border-left: none

    .player__card__list--last
      position: absolute
      width: 100%
      bottom: 0
      background-color: $colors-card-bg2
      margin: 0
      padding: 0
      border-top: solid 1px #ddd
      border-radius: 0 0 6px 6px
      overflow: hidden

      li
        width: 50%
        padding: 10px 0 20px 0
        color: $colors-card-txt
        font-size: 28px
        line-height: 22px

        &:last-child
          border-left: solid 1px #ddd

  *
    pointer-events: none

  .player__img
    position: absolute
    top: 0
    left: 0
    width: $player-x
    height: $player-x
    z-index: 4
    overflow: hidden
    border-radius: ($player-x / 2)
    background-color: #000
    border: solid 1px #fff
    backface-visibility: hidden
    transition: all 0.2s


    img
      width: 100%
      transition: all 0.2s
      display: block

  .player__label
    position: absolute
    height: 20px
    display: inline-block
    width: auto
    overflow: visible
    white-space: nowrap
    left: -100%
    right: -100%
    margin: auto
    padding: 0 10px
    line-height: 20px
    text-align: center
    border-radius: 10px
    bottom: 0
    opacity: 0
    text-transform: upppercase
    transition: opacity 0.2s
    z-index: 2
    pointer-events: none

    span
      background-color: rgba(16, 20, 30, 0.9)
      color: white
      font-size: 11px
      padding: 3px 10px 2px 10px
      border-radius: 10px
      text-transform: upppercase


  &:hover
    .player__img
      opacity: 1
    .player__label
      opacity: 1

  .texture &
    background-size: 100% auto

// @keyframes spinner
//     to
//       transform rotate(360deg)
            
          
!
            
              ASSET_URL = 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/215059/'

$stage        = null
$world        = null
$terrain      = null
$team         = null
$teamListHome = null
$players      = null
$playersHome  = null # Subset of $players
$playersAway  = null # Subset of $players
$switchBtn    = null
$loadBtn      = null
$closeBtn     = null
$heading      = null
$subHeading   = null
$loading      = null
$switcher     = null

data =
    players:
        home: [
            { name: 'Pizarro', asset: 'bm-pizarro.jpg', origin: 'Peru', height: '1.84m', shirt: '14', pos: 'Forward', dob: '36', goals: 1, games: 16, x: 110, y: -190 }
            { name: 'Robben', asset: 'bm-robben.png', origin: 'Holland', height: '1.80m', shirt: '10', pos: 'Forward', dob: '32', goals: 19, games: 30, x: -110, y: -190 }
            { name: 'Rilbery', asset: 'bm-rilbery.jpg', origin: 'France', height: '1.70m', shirt: '7', pos: 'Midfield', dob: '32', goals: 9, games: 22, x: 150, y: 50 }
            { name: 'Schweinsteiger', asset: 'bm-schweinsteiger.jpg', origin: 'Germany', height: '1.87m', shirt: '24', pos: 'Forward', dob: '31', goals: 21, games: 3, x: 0, y: 100 }
            { name: 'Martinez', asset: 'bm-martinez.jpg', origin: 'Spain', height: '1.90m', shirt: '8', pos: 'Midfield', dob: '28', goals: 0, games: 2, x: -150, y: 50 }
            { name: 'Alaba', asset: 'bm-alaba.jpg', origin: 'Austria', height: '1.80m', shirt: '27', pos: 'Defence', dob: '24', goals: 5, games: 27, x: -200, y: 180 }
            { name: 'Lahm', asset: 'bm-lahm.jpg', origin: 'Germany', height: '1.70', shirt: '21', pos: 'Defence', dob: '32', goals: 2, games: 25, x: 200, y: 180 }
            { name: 'Benatia', asset: 'bm-benatia.jpg', origin: 'France', height: '1.87m', shirt: '5', pos: 'Defence', dob: '31', goals: 21, games: 1, x: 100, y: 300 }
            { name: 'Dante', asset: 'bm-dante.jpg', origin: 'Brazil', height: '1.87m', shirt: '4', pos: 'Defence', dob: '32', goals: 0, games: 34, x: -100, y: 300 }
            { name: 'Neuer', asset: 'bm-neuer.jpg', origin: 'Germany', height: '1.93m', shirt: '1', pos: 'Goalie', dob: '29', goals: 0, games: 48, x: 0, y: 410 }
        ]
        away: [
            { name: 'Benzema', asset: 'rm-benzema.jpg', origin: 'France', height: '1.87m', shirt: '9', pos: 'Forward', dob: '36', goals: 1, games: 16, x: 110, y: -190 }
            { name: 'Bale', asset: 'rm-bale.jpg', origin: 'Wales', height: '1.83m', shirt: '11', pos: 'Midfield', dob: '26', goals: 19, games: 30, x: -110, y: -190 }
            { name: 'carvajal', asset: 'rm-carvajal.jpg', origin: 'Spain', height: '1.70m', shirt: '15', pos: 'Defender', dob: '32', goals: 9, games: 22, x: 150, y: 50 }
            { name: 'Silva', asset: 'rm-silva.jpg', origin: 'Brazil', height: '1.87m', shirt: '16', pos: 'Forward', dob: '22', goals: 21, games: 3, x: 0, y: 100 }
            { name: 'Kroos', asset: 'rm-kroos.jpg', origin: 'Germany', height: '1.82', shirt: '8', pos: 'Midfield', dob: '25', goals: 0, games: 2, x: -150, y: 50 }
            { name: 'Modric', asset: 'rm-modric.jpg', origin: 'Croatia', height: '1.74m', shirt: '19', pos: 'Midfield', dob: '30', goals: 5, games: 27, x: -200, y: 180 }
            { name: 'Nacho', asset: 'rm-nacho.jpg', origin: 'Germany', height: '1.79', shirt: '18', pos: 'Defence', dob: '25', goals: 2, games: 25, x: 200, y: 180 }
            { name: 'Ramos', asset: 'rm-ramos.jpg', origin: 'Spain', height: '1.83m', shirt: '4', pos: 'Defence', dob: '31', goals: 21, games: 1, x: 100, y: 300 }
            { name: 'Pepe', asset: 'rm-pepe.jpg', origin: 'Brazil', height: '1.88m', shirt: '3', pos: 'Defence', dob: '32', goals: 0, games: 34, x: -100, y: 300 }
            { name: 'Casillas', asset: 'rm-casillas.jpg', origin: 'Spain', height: '1.85m', shirt: '1', pos: 'Goalie', dob: '34', goals: 0, games: 48, x: 0, y: 410 }
        ]

state =
    home: true
    disabHover: false
    swapSides: ->
        if @home then @home = false else @home = true
    curSide: ->
        if @home then 'home' else 'away'

pos =
    world:
        baseX: 0
        baseY: 0
        baseZ: -200
    def:
        goalie: [0,-50]

dom =
    addPlayers: (side) ->
        for key, val of data.players[side]
            val.side= side
            $el = @addPlayer val
            $team.append $el

        $players = $('.js-player')
        $playersHome = $('.js-player[data-side="home"]')
        $playersAway = $('.js-player[data-side="away"]')


    addPlayer: (data) ->
        $el = $ '<div class="js-player player" data-name="' + data.name + '" data-side="' + data.side + '" data-x="' + data.x + '" data-y="' + data.y + '"></div>'
        $el.append '<div class="player__label"><span>' + data.name + '</span></div>'
        $el.append '<div class="player__img"><img src= ' + ASSET_URL + data.asset + '></div>'
        $el.prepend '<div class="player__card"> </div>'
        $el.prepend '<div class="player__placeholder"></div>'
        @populateCard $el.find('.player__card'), data
        $el

    preloadImages: (preload) ->
        promises = []
        i = 0
        while i < preload.length
          ((url, promise) ->
            img = new Image
            img.onload = -> promise.resolve()
            img.src = url
          ) preload[i], promises[i] = $.Deferred()
          i++
        $.when.apply($, promises).done ->
            scenes.endLoading()
            scenes.loadIn(1600)


    populateCard: ($el, data) ->
        $el.append '<h3>' + data.name + '</h3>' +
            '<ul class="player__card__list"><li><span>DOB</span><br/>' + data.dob + ' yr</li><li><span>Height</span><br/>' + data.height + '</li><li><span>Origin</span><br/>' + data.origin + '</li></ul>' +
            '<ul class="player__card__list player__card__list--last"><li><span>Games</span><br/>' + data.games + '</li><li><span>Goals</span><br/>' + data.goals + '</li></ul>'

    displayNone: ($el) ->
        $el.css 'display', 'none'

events =
    attachAll: ->
        $switchBtn.on 'click', (e) ->
            e.preventDefault()
            $el = $(this)
            return if $el.hasClass 'disabled'
            scenes.switchSides()
            $switchBtn.removeClass 'disabled'
            $el.addClass 'disabled'

        $loadBtn.on 'click', (e) ->
            e.preventDefault()
            scenes.loadIn()

        $players.on 'click', (e) ->
            e.preventDefault()
            $el = $(this)
            if $('.active').length then return false
            $el.addClass 'active'
            scenes.focusPlayer($el)
            setTimeout ( -> events.attachClose()), 1

    attachClose: ->
        $stage.one 'click', (e) ->
            e.preventDefault()
            scenes.unfocusPlayer()

scenes =
    preLoad: ->
        $teamListHome.velocity { opacity: 0 }, 0
        $players.velocity { opacity: 0 }, 0
        $loadBtn.velocity { opacity: 0 }, 0
        $switcher.velocity { opacity: 0 }, 0
        $heading.velocity { opacity: 0 }, 0
        $subHeading.velocity { opacity: 0 }, 0
        $playersAway.css 'display', 'none'
        $world.velocity { opacity: 0, translateZ: -200, translateY: -60 }, 0
        $('main').velocity { opacity: 1 }, 0

    loadIn: (delay = 0) ->
        $world.velocity { opacity: 1, translateY: 0, translateZ: -200 }, { duration: 1000, delay: delay, easing: 'spring' }
        anim.fadeInDir($heading, 300, (delay + 600), 0, 30)
        anim.fadeInDir($subHeading, 300, (delay + 800), 0, 30)
        anim.fadeInDir($teamListHome, 300, (delay + 800), 0, 30)
        anim.fadeInDir($switcher, 300, (delay + 900), 0, 30)

        delay += 1200
        delayInc = 30
        anim.dropPlayers($playersHome, delay, delayInc)

    startLoading: ->
        anim.fadeInDir $loading, 300, 0, 0, -20
        images = []
        for key, val of data.players.home and data.players.away
            images.push ASSET_URL + val.asset

        dom.preloadImages(images)

    endLoading: ->
        anim.fadeOutDir $loading, 300, 1000, 0, -20

    arrangePlayers: ->
        $players.each ->
            $el = $(this)

            $el.velocity
                translateX: parseInt $el.attr('data-x')
                translateZ: parseInt $el.attr('data-y') # Z is the Y axis on the field

    focusPlayer: ($el) ->
        data = $el.data()
        shiftY = data.y

        if shiftY > 0 then shiftY = (data.y / 2)

        $('.js-player[data-side="' + state.curSide() + '"]').not('.active').each ->
            $unfocus = $(this)
            anim.fadeOutDir $unfocus, 300, 0, 0, 0, 0, null, 0.2

        $world.velocity
            translateX: (pos.world.baseX - data.x)
            translateY: (pos.world.baseY)
            translateZ: (pos.world.baseZ - shiftY) # Z is the Y axis on the field

        , 600

        $terrain.velocity
            opacity: 0.66
        , 600

        @showPlayerCard $el, 600, 600

    unfocusPlayer: ->
        $el = $('.js-player.active')
        data = $el.data()
        anim.fadeInDir $('.js-player[data-side="' + state.curSide() + '"]').not('.active'), 300, 300, 0, 0, 0, null, 0.2
        $el.removeClass 'active'
        $world.velocity
            translateX: (pos.world.baseX)
            translateY: (pos.world.baseY)
            translateZ: (pos.world.baseZ) # Z is the Y axis on the field

        , 600

        $terrain.velocity
            opacity: 1
        , 600

        @hidePlayerCard $el, 600, 600

    hidePlayerCard: ($el, dur, delay) ->
        $card = $el.find '.player__card'
        $image = $el.find '.player__img'
        $image.velocity
            translateY: 0
        , 300
        anim.fadeInDir $el.find '.player__label', 200, delay
        anim.fadeOutDir $card, 300, 0, 0, -100

    showPlayerCard: ($el, dur, delay) ->
        $card = $el.find '.player__card'
        $image = $el.find '.player__img'
        $image.velocity
            translateY: '-=150px'
        , 300
        anim.fadeOutDir $el.find '.player__label', 200, delay
        anim.fadeInDir $card, 300, 200, 0, 100

    switchSides: ->
        delay = 0
        delayInc = 20

        $old = $playersHome
        $new = $playersAway
        if !state.home
            $old = $playersAway
            $new = $playersHome

        state.swapSides()

        $old.each ->
            $el = $(this)
            anim.fadeOutDir($el, 200, delay, 0, -60, 0)
            anim.fadeOutDir($el.find('.player__label'), 200, (delay + 700))
            delay += delayInc

        $terrain.velocity { rotateY: '+=180deg' }, { delay: 150, duration: 1200 }
        anim.dropPlayers($new, 1500, 30)

anim =
    fadeInDir: ($el, dur, delay, deltaX = 0, deltaY = 0, deltaZ = 0, easing = null, opacity = 0) ->
        $el.css 'display', 'block'

        $el.velocity
            translateX: '-=' + deltaX
            translateY: '-=' + deltaY
            translateZ: '-=' + deltaZ
        , 0

        $el.velocity
            opacity: 1
            translateX: '+=' + deltaX
            translateY: '+=' + deltaY
            translateZ: '+=' + deltaZ
        ,
            easing: easing
            delay: delay
            duration: dur

    fadeOutDir: ($el, dur, delay, deltaX = 0, deltaY = 0, deltaZ = 0, easing = null, opacity = 0) ->
        if !opacity
            display = 'none'
        else
            display = 'block'

        $el.velocity
            opacity: opacity
            translateX: '+=' + deltaX
            translateY: '+=' + deltaY
            translateZ: '+=' + deltaZ
        ,
            easing: easing
            delay: delay
            duration: dur
        .velocity
            opacity: opacity
            translateX: '-=' + deltaX
            translateY: '-=' + deltaY
            translateZ: '-=' + deltaZ
        ,
            duration: 0
            display: display


    dropPlayers: ($els, delay, delayInc) ->
        $els.each ->
            $el = $(this)
            $el.css
                display : 'block'
                opacity : 0

            anim.fadeInDir($el, 800, delay, 0, 50, 0, 'spring')
            anim.fadeInDir($el.find('.player__label'), 200, (delay + 250))
            delay += delayInc

init = ->
    $stage        = $('.js-stage')
    $world        = $('.js-world')
    $switchBtn    = $('.js-switch')
    $loadBtn      = $('.js-load')
    $heading      = $('.js-heading')
    $switcher     = $('.js-switcher')
    $closeBtn     = $('.js-close')
    $subHeading   = $('.js-subheading')
    $terrain      = $('.js-terrain')
    $team         = $('.js-team')
    $teamListHome = $('.js-team-home')
    $loading      = $('.js-loading')

    dom.addPlayers('home')
    dom.addPlayers('away')
    scenes.preLoad()
    scenes.arrangePlayers()
    events.attachAll()
    scenes.startLoading()

$(document).ready ->
    init()
            
          
!
999px
🕑 One or more of the npm packages you are using needs to be built. You're the first person to ever need it! We're building it right now and your preview will start updating again when it's ready.

Console