UNPKG

@readyplayerme/react-avatar-creator

Version:

Ready Player Me - React Avatar Creator

109 lines (102 loc) 4.61 kB
'use strict'; var React = require('react'); /** * Tries to parse the JSON data, and returns undefined if parsing fails. * @param jsonString The string to be parsed. * @returns The parsed JSON data or undefined if the data is not valid JSON. */ const JSONTryParse = (jsonString) => { try { return JSON.parse(jsonString); } catch (error) { return undefined; } }; const useAvatarCreatorUrl = (subdomain, config) => { return React.useMemo(() => { let url = `https://${subdomain || `demo`}.readyplayer.me`; if (config?.language) url += `/${config.language}`; url += `/avatar?frameApi&source=react-avatar-creator`; if (config?.clearCache) url += '&clearCache'; if (config?.quickStart) url += '&quickStart'; if (config?.bodyType) url += `&bodyType=${config?.bodyType}`; if (config?.token) url += `&token=${config?.token}`; if (config?.avatarId) url += `&id=${config?.avatarId}`; return url; }, [subdomain, config]); }; const MESSAGE_EVENT = 'message'; const RPM_TARGET = 'readyplayerme'; const IFRAME_READY_EVENT = 'v1.frame.ready'; /** * AvatarCreatorRaw is a React component that allows you to create an avatar using Ready Player Me and receive avatar URL. It exposes the raw events in one callback to allow you to write more custom logic around the event handling. * @param subdomain The subdomain of your Ready Player Me instance. * @param className The css classes to apply to this iframe. * @param style The css styles to apply to this iframe. * @param avatarCreatorConfig The configuration for the AvatarCreator component. * @param onEventReceived A callback that is called when an avatar creator event is received. * @returns A React component. */ const AvatarCreatorRaw = ({ subdomain, className, style, config, onEventReceived }) => { const frameRef = React.useRef(null); const url = useAvatarCreatorUrl(subdomain, config); const subscribeToAvatarCreatorEvents = () => { if (!frameRef.current?.contentWindow) return; frameRef.current?.contentWindow?.postMessage(JSON.stringify({ target: RPM_TARGET, type: 'subscribe', eventName: 'v1.**', }), '*'); }; const subscribe = (event) => { const avatarCreatorEvent = JSONTryParse(event.data); if (avatarCreatorEvent?.source !== RPM_TARGET) return; if (avatarCreatorEvent?.eventName === IFRAME_READY_EVENT) { subscribeToAvatarCreatorEvents(); return; } onEventReceived?.(avatarCreatorEvent); }; React.useEffect(() => { window.addEventListener(MESSAGE_EVENT, subscribe); return () => { window.removeEventListener(MESSAGE_EVENT, subscribe); }; }, []); return React.createElement("iframe", { title: "Ready Player Me", ref: frameRef, src: url, style: style, className: className, allow: "camera *; clipboard-write" }); }; /** * AvatarCreator is a React component that allows you to create an avatar using Ready Player Me and receive avatar URL. It wraps AvatarCreatorRaw to provide more type safety, and to provide explicit callbacks per event type. * @param subdomain The subdomain of your Ready Player Me instance. * @param className The css classes to apply to this iframe. * @param style The css styles to apply to this iframe. * @param config The configuration for the AvatarCreator component. * @param onUserSet A callback that is called when a user is set. * @param onAvatarExported A callback that is called when an avatar is exported. * @param onUserAuthorized A callback that is called when a user is authorized. * @param onAssetUnlock A callback that is called when an asset unlock button is pressed in RPM. * @returns A React component. */ const AvatarCreator = ({ subdomain, className, style, config, onUserSet, onAvatarExported, onUserAuthorized, onAssetUnlock }) => { const supportedEvents = { 'v1.avatar.exported': onAvatarExported, 'v1.user.set': onUserSet, 'v1.user.authorized': onUserAuthorized, 'v1.asset.unlock': onAssetUnlock, }; const handleEvents = (event) => { supportedEvents[event.eventName]?.(event); }; return React.createElement(AvatarCreatorRaw, { subdomain: subdomain, className: className, style: style, config: config, onEventReceived: handleEvents }); }; exports.AvatarCreator = AvatarCreator; exports.AvatarCreatorRaw = AvatarCreatorRaw;