iframe 通讯

Category:

Tags:

iframe 没有 click 事件,所以要监听内部点击,可以从内部触发,或给父盒子添加 click 监听

基本实现

javascript
import { 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> ); }