When building for React Native I run into quite a few issues, some I have been able to resolve, but now I'm stuck. I looked through the closed issues and it seems React Native is supported. Is there a guide or example somewhere?
Here's the steps I've taken...
First I needed to add react-native-canvas and react-native-fs to the project.
Then I polyfilled window and navigator
global.window = {
navigator: {
userAgent: 'any',
platform: 'any',
},
location: { search: 'location' },
}
global.navigator = {
userAgent: 'any',
platform: 'any',
}
I modified the code to use Canvas
/* eslint-disable no-inner-declarations */
import React, { useEffect, useRef, useState, forwardRef } from 'react'
import { Application } from '@splinetool/runtime'
import type {
SPEObject,
SplineEvent,
SplineEventName,
} from '@splinetool/runtime'
import Canvas from 'react-native-canvas'
import { StyleProp, ViewStyle } from 'react-native'
export type { SPEObject, SplineEvent, SplineEventName }
export function mergeRefs<T = any>(
refs: Array<React.MutableRefObject<T> | React.LegacyRef<T>>,
): React.RefCallback<T> {
return (value) => {
refs.forEach((ref) => {
if (typeof ref === 'function') {
ref(value)
} else if (ref != null) {
const typedRef = ref as React.MutableRefObject<T | null>
typedRef.current = value
}
})
}
}
type CanvasAttributes = React.CanvasHTMLAttributes<HTMLCanvasElement>
export interface SplineProps
extends Omit<
CanvasAttributes,
| 'onLoad'
| 'onMouseDown'
| 'onMouseUp'
| 'onMouseHover'
| 'onKeyDown'
| 'onKeyUp'
| 'onWheel'
| 'style'
> {
scene: string
onLoad?: (e: Application) => void
onMouseDown?: (e: SplineEvent) => void
onMouseUp?: (e: SplineEvent) => void
onMouseHover?: (e: SplineEvent) => void
onKeyDown?: (e: SplineEvent) => void
onKeyUp?: (e: SplineEvent) => void
onStart?: (e: SplineEvent) => void
onLookAt?: (e: SplineEvent) => void
onFollow?: (e: SplineEvent) => void
onWheel?: (e: SplineEvent) => void
autoRender?: boolean
style?: StyleProp<ViewStyle>
}
const Spline = forwardRef<HTMLCanvasElement, SplineProps>(
(
{
scene,
style,
onMouseDown,
onMouseUp,
onMouseHover,
onKeyDown,
onKeyUp,
onStart,
onLookAt,
onFollow,
onWheel,
onLoad,
autoRender = false,
...props
},
ref,
) => {
const canvasRef = useRef<HTMLCanvasElement>(null)
const [, setIsLoading] = useState(true)
// Initialize runtime when component is mounted
useEffect(() => {
setIsLoading(true)
let speApp: Application
const events: {
name: SplineEventName
cb?: (e: SplineEvent) => void
}[] = [
{
name: 'mouseDown',
cb: onMouseDown,
},
{
name: 'mouseUp',
cb: onMouseUp,
},
{
name: 'mouseHover',
cb: onMouseHover,
},
{
name: 'keyDown',
cb: onKeyDown,
},
{
name: 'keyUp',
cb: onKeyUp,
},
{
name: 'start',
cb: onStart,
},
{
name: 'lookAt',
cb: onLookAt,
},
{
name: 'follow',
cb: onFollow,
},
{
name: 'scroll',
cb: onWheel,
},
]
if (canvasRef.current) {
speApp = new Application(canvasRef.current, { autoRender })
async function init() {
await speApp.load(scene)
for (const event of events) {
if (event.cb) {
speApp.addEventListener(event.name, event.cb)
}
}
setIsLoading(false)
onLoad?.(speApp)
}
init()
}
return () => {
for (const event of events) {
if (event.cb) {
speApp.removeEventListener(event.name, event.cb)
}
}
speApp.dispose()
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [scene])
return (
<Canvas
ref={mergeRefs<HTMLCanvasElement>([ref, canvasRef])}
style={style}
{...props}
/>
)
},
)
export default Spline
Now I'm getting
ReferenceError: Can't find variable: document
and
TypeError: undefined is not an object (evaluating '_$$_REQUIRE(_dependencyMap[7], "@splinetool/runtime").Application')
It seems I'm going down a rabbit hole. Is there a better way?
When building for React Native I run into quite a few issues, some I have been able to resolve, but now I'm stuck. I looked through the closed issues and it seems React Native is supported. Is there a guide or example somewhere?
Here's the steps I've taken...
First I needed to add
react-native-canvasandreact-native-fsto the project.Then I polyfilled window and navigator
I modified the code to use
CanvasNow I'm getting
and
It seems I'm going down a rabbit hole. Is there a better way?