I love Felix

This commit is contained in:
artie 2023-10-29 15:45:30 +01:00
parent 5d052588dd
commit 144113efde
4 changed files with 98 additions and 61 deletions

View File

@ -1,59 +0,0 @@
<script lang="ts">
import * as PIXI from "pixi.js";
import { Live2DModel, MotionPreloadStrategy, MotionPriority } from "pixi-live2d-display";
import { onDestroy, onMount } from "svelte";
let canvas: HTMLCanvasElement;
let app: PIXI.Application;
let model: Live2DModel;
function getRandomModelUrl() {
const baseUrl = "https://cdn.artie.moe/live2d/";
const models = [
"emilia01/ac_base_emilia01.model3.json",
"emilia_nemaki01/ac_base_emilia_nemaki01.model3.json",
"emilia_dress01/ac_base_emilia_dress01.model3.json",
];
const choice = models[Math.floor(Math.random() * models.length)];
return baseUrl + choice;
}
onMount(async () => {
(window as any).PIXI = PIXI;
app = new PIXI.Application({
view: canvas,
autoStart: true,
backgroundAlpha: 0,
width: 900,
height: 900,
});
model = await Live2DModel.from(getRandomModelUrl(), { motionPreload: MotionPreloadStrategy.NONE });
app.stage.addChild(model as unknown as PIXI.DisplayObject);
canvas.style.cursor = "pointer";
model.internalModel.motionManager.state.shouldRequestIdleMotion = () => false;
model.internalModel.motionManager.on("motionFinish", () => {
setTimeout(() => model.motion("Idle", undefined, MotionPriority.IDLE), 2000);
});
model.motion("Idle", undefined, MotionPriority.IDLE);
model.scale.set(0.45);
model.x = -600;
model.y = -70;
});
onDestroy(() => {
app.destroy(false);
});
</script>
<canvas
bind:this={canvas}
on:pointerdown={() => model.motion("Tap")}
id="live2d"
class="cursor-pointer left-0 bottom-0 fixed lg:w-96 w-44"
/>

View File

@ -0,0 +1,82 @@
<script lang="ts">
import * as PIXI from "pixi.js";
import {
Live2DModel,
MotionPreloadStrategy,
MotionPriority,
} from "pixi-live2d-display";
import { onDestroy, onMount } from "svelte";
import { reZeroModels } from "../utils/constants";
let canvas: HTMLCanvasElement;
let app: PIXI.Application;
let model: Live2DModel;
function getModelFromParams(): string | undefined {
if (location.search) {
const params = new URLSearchParams(location.search);
const modelKey = params.get("model");
if (!modelKey) return;
const model = modelKey.match(/^([a-zA-Z]+)(\d+)$/);
if (!model) return;
const [_, key, index] = model;
return reZeroModels[key]?.[+index];
}
}
function getRandomModelUrl() {
let choices = reZeroModels.emilia;
// 20% chance to roll a Felix model
if (Math.random() <= 0.2) {
choices = reZeroModels.felix;
}
return choices[Math.floor(Math.random() * choices.length)];
}
onMount(async () => {
(window as any).PIXI = PIXI;
app = new PIXI.Application({
view: canvas,
autoStart: true,
backgroundAlpha: 0,
width: 900,
height: 980,
});
model = await Live2DModel.from(
getModelFromParams() || getRandomModelUrl(),
{
motionPreload: MotionPreloadStrategy.NONE,
}
);
app.stage.addChild(model as unknown as PIXI.DisplayObject);
canvas.style.cursor = "pointer";
model.internalModel.motionManager.state.shouldRequestIdleMotion = () =>
false;
model.internalModel.motionManager.on("motionFinish", () => {
setTimeout(
() => model.motion("Idle", undefined, MotionPriority.IDLE),
2000
);
});
model.motion("Idle", undefined, MotionPriority.IDLE);
model.scale.set(0.45);
model.x = -600;
model.y = 0;
});
onDestroy(() => {
app.destroy(false);
});
</script>
<canvas
bind:this={canvas}
on:pointerdown={() => model.motion("Tap")}
id="live2d"
class="cursor-pointer left-0 bottom-0 fixed lg:w-96 w-44"
/>

View File

@ -3,7 +3,7 @@ import Layout from "../layouts/Layout.astro";
import Prompt from "../components/Prompt.astro";
import Centerpiece from "../components/Centerpiece.astro";
import Icons from "../components/Icons.astro";
import Emilia from "../components/Emilia.svelte";
import Model from "../components/Model.svelte";
---
@ -14,5 +14,5 @@ import Emilia from "../components/Emilia.svelte";
<script is:inline src="/vendors/live2dcubismcore.min.js"></script>
<script is:inline src="/vendors/live2d.min.js"></script>
<Emilia client:only />
<Model client:only />
</Layout>

14
src/utils/constants.ts Normal file
View File

@ -0,0 +1,14 @@
export const modelsUrl = "https://cdn.artie.moe/live2d";
export const reZeroModels = {
emilia: [
modelsUrl + "/emilia01/ac_base_emilia01.model3.json",
modelsUrl + "/emilia_nemaki01/ac_base_emilia_nemaki01.model3.json",
modelsUrl + "/emilia_dress01/ac_base_emilia_dress01.model3.json",
],
felix: [
modelsUrl + "/ferris01/ac_base_ferris01.model3.json",
modelsUrl + "/ferris_dress01/ac_base_ferris_dress01.model3.json",
modelsUrl + "/ferris_kimono01/ac_base_ferris_kimono01.model3.json",
],
};