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"
...