fix(avatar): re-apply CSS 100% after Pixi resize(); use fitModel helper; 65% margin
Pixi renderer.resize() overwrites canvas inline width/height styles, locking the canvas to the initial size and leaving empty space below. Now we re-apply width:100%;height:100% after every resize so the canvas always fills its container. Removed unused appRef.
This commit is contained in:
@@ -24,7 +24,6 @@ const OUTFIT_TEXTURES: Record<string, string> = {
|
|||||||
|
|
||||||
export default function KiraAvatar(props: Props) {
|
export default function KiraAvatar(props: Props) {
|
||||||
const canvasRef = useRef<HTMLDivElement>(null);
|
const canvasRef = useRef<HTMLDivElement>(null);
|
||||||
const appRef = useRef<any>(null);
|
|
||||||
const modelRef = useRef<any>(null);
|
const modelRef = useRef<any>(null);
|
||||||
const textureRef = useRef<any>(null);
|
const textureRef = useRef<any>(null);
|
||||||
const lipSyncRef = useRef<number>(0);
|
const lipSyncRef = useRef<number>(0);
|
||||||
@@ -41,6 +40,16 @@ export default function KiraAvatar(props: Props) {
|
|||||||
|
|
||||||
let app: any = null;
|
let app: any = null;
|
||||||
let model: any = null;
|
let model: any = null;
|
||||||
|
let canvasEl: HTMLCanvasElement | null = null;
|
||||||
|
|
||||||
|
const fitModel = (crW: number, crH: number) => {
|
||||||
|
if (!model || !app) return;
|
||||||
|
const maxW = crW * 0.65;
|
||||||
|
const maxH = crH * 0.65;
|
||||||
|
const s = Math.min(maxW / model.width, maxH / model.height);
|
||||||
|
model.scale.set(s);
|
||||||
|
model.position.set(app.screen.width / 2, app.screen.height / 2);
|
||||||
|
};
|
||||||
|
|
||||||
const init = async () => {
|
const init = async () => {
|
||||||
try {
|
try {
|
||||||
@@ -73,6 +82,7 @@ export default function KiraAvatar(props: Props) {
|
|||||||
canvas.style.height = '100%';
|
canvas.style.height = '100%';
|
||||||
canvas.style.display = 'block';
|
canvas.style.display = 'block';
|
||||||
container.appendChild(canvas);
|
container.appendChild(canvas);
|
||||||
|
canvasEl = canvas;
|
||||||
|
|
||||||
model = await Live2DModel.from('/live2d/models/kira/kira.model3.json', {
|
model = await Live2DModel.from('/live2d/models/kira/kira.model3.json', {
|
||||||
autoInteract: false,
|
autoInteract: false,
|
||||||
@@ -80,8 +90,8 @@ export default function KiraAvatar(props: Props) {
|
|||||||
modelRef.current = model;
|
modelRef.current = model;
|
||||||
|
|
||||||
// Fit model with generous margin to avoid clipping
|
// Fit model with generous margin to avoid clipping
|
||||||
const maxW = w * 0.68;
|
const maxW = w * 0.65;
|
||||||
const maxH = h * 0.68;
|
const maxH = h * 0.65;
|
||||||
const scale = Math.min(maxW / model.width, maxH / model.height);
|
const scale = Math.min(maxW / model.width, maxH / model.height);
|
||||||
model.scale.set(scale);
|
model.scale.set(scale);
|
||||||
model.anchor.set(0.5, 0.5);
|
model.anchor.set(0.5, 0.5);
|
||||||
@@ -117,17 +127,16 @@ export default function KiraAvatar(props: Props) {
|
|||||||
|
|
||||||
// Use ResizeObserver so we init with the real laid-out size
|
// Use ResizeObserver so we init with the real laid-out size
|
||||||
const ro = new ResizeObserver((entries) => {
|
const ro = new ResizeObserver((entries) => {
|
||||||
|
const cr = entries[0].contentRect;
|
||||||
if (app) {
|
if (app) {
|
||||||
// Already init'd — handle resize
|
// Already init'd — handle resize
|
||||||
const cr = entries[0].contentRect;
|
|
||||||
app.renderer.resize(Math.round(cr.width), Math.round(cr.height));
|
app.renderer.resize(Math.round(cr.width), Math.round(cr.height));
|
||||||
if (model) {
|
// Re-apply CSS 100% because Pixi resize() overwrites inline styles
|
||||||
const maxW = cr.width * 0.68;
|
if (canvasEl) {
|
||||||
const maxH = cr.height * 0.68;
|
canvasEl.style.width = '100%';
|
||||||
const s = Math.min(maxW / model.width, maxH / model.height);
|
canvasEl.style.height = '100%';
|
||||||
model.scale.set(s);
|
|
||||||
model.position.set(app.screen.width / 2, app.screen.height / 2);
|
|
||||||
}
|
}
|
||||||
|
fitModel(cr.width, cr.height);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// First measurement — run init
|
// First measurement — run init
|
||||||
|
|||||||
Reference in New Issue
Block a user