Goose Component

by Admiral Potato

HTML

<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<div id="goose-app">
	<goose-box></goose-box>
</div>

JavaScript

window.tau = Math.PI * 2;
const AvatarGoose = {
  props: {
    user: {
      type: Object,
      required: true
    }
  },
  computed: {
    cursor () {
      const user = this.user
      const headDegrees = (user.headAngle / window.tau) * 360
      const bodyDegrees = (user.bodyAngle / window.tau) * 360
      const pointerDegrees = (user.eyeAngle / window.tau) * 360
      const cos = Math.cos(user.headAngle)
			const doFlipA = user.headAngle < 0
			const doFlipB = (user.headAngle % tau) > Math.PI
      const eyeSlideX = doFlipA && doFlipB
        ? -cos
        : cos
      const eyeSlideXDistance = 1
      const eyeSlideY = Math.sin(user.headAngle) * 0.5
      return Object.assign(
        {},
        user,
        {
          bodyDirection: (Math.abs(user.headAngle) > (Math.PI * 0.5)) ? 1 : -1,
          headTransform: `rotate(${headDegrees})`,
          leftEyeTransform: `
            translate(${eyeSlideX - eyeSlideXDistance} ${eyeSlideY})
          `,
          rightEyeTransform: `
            translate(${eyeSlideX + eyeSlideXDistance} ${eyeSlideY})
          `,
          bodyTransform: `rotate(${bodyDegrees})`,
          pointerTransform: `rotate(${pointerDegrees})`,
          transform: `
            translate(${user.x} ${user.y})
            scale(${user.combinedScale / 8})
          `
        }
      )
    }
  },
  template: /* svg */`
    <g
      class="avatar-goose"
      :transform="cursor.transform"
    >
      <g
        class="goose-body"
      >
        <use
          class="goose-neck-outline"
          href="#goose-neck"
          stroke="#000"
          stroke-width="1.25"
          stroke-linejoin="round"
          stroke-linecap="round"
        />
        <use
          href="#goose-body"
          stroke="#000"
          stroke-width="0.25"
          stroke-linejoin="round"
          stroke-linecap="round"
          :transform="'translate(0,2.25)' + cursor.bodyTransform"
        />
        <use
          class="goose-neck-white"
         ...