iframe 没有 click 事件,所以要监听内部点击,可以从内部触发,或给父盒子添加 click 监听
基本实现
javascriptimport { isSylvia } from "@/config/live2d";
import { IModalConfig } from "@/services/user";
import { CircularProgress } from "@nextui-org/progress";
import clsx from "clsx";
import { sample } from "lodash";
import { useEffect, useImperativeHandle, useState } from "react";
import ModelPreviewCover from "../ModelPreviewCover";
interface PixiLive2DRenderProps {
currModel: IModalConfig;
isCubismCoreLoaded: boolean;
intimacy: number;
}
export default function ModalRender({
currModel,
isCubismCoreLoaded,
intimacy,
ref,
iframeWindow,
setIframeWindow,
}: PixiLive2DRenderProps) {
const [loadingState, setLoadingState] = useState(true);
const randomMotion = () => {
const ins = iframeWindow?.ins;
if (!ins?.motion) return;
const actions = intimacy > 80 ? [0, 1, 2] : [0, 2];
ins?.motion("Tap", sample(actions));
};
useImperativeHandle(ref, () => ({
randomMotion,
}));
if (!currModel?.uuid) return;
return (
<div className="flex items-center justify-center relative">
{/* {isCubismCoreLoaded &&
window?.location?.host === "wingman.bestie.icu" && (
<FpsDisplay app={modelApp} />
)} */}
<div
className={clsx(
"w-[600px] h-[1000px] object-cover",
!loadingState ? "opacity-0" : "opacity-100",
)}
onClick={(e) => {
randomMotion?.();
}}
>
<iframe
src={`/bestie/${currModel?.uuid}`}
frameBorder="0"
onLoad={(e) => {
const cw = e?.target?.contentWindow;
if (cw) {
setIframeWindow(cw);
}
}}
title="Live2D"
className={clsx(
"w-[600px] h-[1000px] object-cover pointer-events-none",
!loadingState ? "opacity-0" : "opacity-100",
)}
/>
</div>
{!loadingState && (
<div
className="flex justify-center items-center absolute inset-0 bg-center left-1/2 -translate-x-[45%]"
style={{
width: 600,
height: 1000,
}}
>
<ModelPreviewCover
width={600}
height={isSylvia(currModel?.uuid) ? 1200 : 1000}
modelUuid={currModel?.uuid}
className={clsx(
isSylvia(currModel?.uuid)
? "w-full h-full !object-cover !-translate-x-8"
: "",
)}
/>
<CircularProgress
aria-label="Loading..."
color="warning"
size="lg"
className="absolute left-1/2 top-1/2 -translate-y-1/2 -translate-x-1/2"
/>
</div>
)}
</div>
);
}