<link href="https://unpkg.com/tee-skin-renderer/dist/tee-skin-renderer.css" rel="stylesheet">
<script src="https://unpkg.com/tee-skin-renderer/dist/tee-skin-renderer.umd.js"></script>
<div class="tee"
data-skin="https://ddstats.tw/skins/pinky.png"
data-color-body="5498880"
data-color-feet="3079936"
data-eyes="happy"
data-speed="10"
data-follow-mouse="true">
</div>
<script>
// Auto-initialize all .tee elements on the page
TeeSkinRenderer.init();
</script>
const container = await TeeSkinRenderer.createAsync({
skinUrl: 'https://ddstats.tw/skins/pinky.png',
colorBody: 5498880,
colorFeet: 3079936,
eyes: 'happy',
speed: 10,
followMouse: true,
});
document.body.appendChild(container);
const container = await TeeSkinRenderer.createAsync({
skinUrl: 'https://ddstats.tw/skins/default.png',
});
// Access the renderer via container.tee
const tee = container.tee;
tee.skinUrl = 'https://ddstats.tw/skins/pinky.png';
tee.colorBody = 16768387;
tee.colorFeet = 16777215;
tee.useCustomColor = true;
tee.eyes = 'surprise';
tee.speed = -20; // reverse leg animation
tee.inAir = false;
tee.fat = true;
const bounce = TeeSkinRenderer.animation.define({
kind: 'keyframes',
duration: 900,
loop: true,
easing: 'ease-in-out',
tracks: {
body: [
{ time: 0, y: 0 }, { time: 0.2, y: 0 },
{ time: 0.5, y: -6 },
{ time: 0.8, y: 0 }, { time: 1, y: 0 },
],
backFoot: [
{ time: 0, x: -7, y: 0 },
{ time: 0.2, x: -7, y: 0 },
{ time: 0.5, x: -6, y: -4, angle: -0.05 },
{ time: 0.8, x: -7, y: 0 },
{ time: 1, x: -7, y: 0 },
],
frontFoot: [
{ time: 0, x: 7, y: 0 },
{ time: 0.2, x: 7, y: 0 },
{ time: 0.5, x: 6, y: -4, angle: 0.05 },
{ time: 0.8, x: 7, y: 0 },
{ time: 1, x: 7, y: 0 },
],
eyes: [{ time: 0, eyes: 'happy' }],
},
});
const controller = tee.playAnimation(bounce);
controller.pause();
controller.resume();
controller.seek(400);
controller.stop();
const hop = TeeSkinRenderer.animation.define({
kind: 'callback',
duration: 900,
loop: true,
frame({ progress, speed, inAir }) {
const lift = Math.sin(progress * Math.PI) ** 2;
return {
body: { y: -5 * lift },
backFoot: { x: -7 + lift, y: -3 * lift, angle: -0.04 * lift },
frontFoot: { x: 7 - lift, y: -3 * lift, angle: 0.04 * lift },
eyes: inAir || Math.abs(speed) > 19.5
? 'surprise'
: 'happy',
};
},
});
const controller = tee.playAnimation(hop);
const result = await controller.finished;
console.log(result.reason);
const container = await TeeSkinRenderer.createAsync({
skinUrl: 'https://ddstats.tw/skins/pinky.png',
colorBody: 53063,
colorFeet: 524159,
});
container.tee.addEventListener('tee:skin-loaded', (e) => {
const { skin, success } = e.detail.payload;
console.log(`Skin ${skin}: ${success ? 'loaded' : 'failed'}`);
});
container.tee.addEventListener('tee:rendered', (e) => {
console.log('Tee rendered!');
});
const container = await TeeSkinRenderer.createAsync({
skinUrl: 'https://ddstats.tw/skins/pinky.png',
colorBody: 5498880,
colorFeet: 3079936,
speed: 10,
});
const canvas = document.createElement('canvas');
container.tee.renderToCanvas(canvas, {
size: 128,
eyes: 'happy',
});
document.body.appendChild(canvas);
/* Base tee is 96em × 96em.
At font-size: 1px → 96px.
Scale by changing font-size: */
.tee-xs { font-size: 0.35px; } /* 34px */
.tee-sm { font-size: 0.55px; } /* 53px */
.tee-md { font-size: 1px; } /* 96px (default) */
.tee-lg { font-size: 1.6px; } /* 154px */
.tee-xl { font-size: 2.2px; } /* 211px */
/* Or set it inline: */
<div class="tee" style="font-size: 1.5px"
data-skin="..."></div>
/* Or dynamically via JS: */
container.style.fontSize = '2px';
const { color } = TeeSkinRenderer;
const teeColor = 5498880;
const hsl = color.convertTeeColorToHsl(teeColor);
// [74.8, 100, 75.1] = H, S%, L%
const rgba = color.convertTeeColorToRgba(teeColor);
// [127.5, 255, 0, 255] = R, G, B, A
const eyes = ['normal', 'happy', 'angry', 'pain', 'surprise', 'dead', 'blink'];
for (const eye of eyes) {
const container = await TeeSkinRenderer.createAsync({
skinUrl: 'https://ddstats.tw/skins/pinky.png',
eyes: eye,
});
gallery.appendChild(container);
}