Export in React Site
Add to favorites
Export your design in a React environment
Play video
React export
On the top bar of Spline, click Export, select Code, then select React from the dropdown menu. In other words, Spline and React are completely compatible. It includes the URL to the scene but also, a code snippets.
Figma link
To follow this part of the tutorial, you also need the Figma design file. We will recreate this design from Figma in React. I will leave the link to the Figma design in the description below. The Design system includes fonts, colors, components, and styles. There is also a static web design and a mobile design below that.
Demo
Here's a demo of what we're going to build. This website is fully interactive, including buttons and the scene. Our goal will be to learn how to make the Spline scene fullscreen and how to return it to its original size. Additionally, we will discuss responsiveness.
Template
In order to follow along with me, I highly recommend downloading or duplicating the CodeSandBox template in the description below. I will also include a link to the final template.
Starting template
The starting template has a few components such as the CloseButton, CourseButton, DownloadButton, Header, Logo, PlayButton and SplineScene. The Spline scene file is the same code as the export React in Spline. Then, we have some custom fonts, images and the TextStyles. The TextStyles is similar to the Design system in Figma converted in code.
Logo
Let’s start simple with the logo. At the top left, we have a Logo component, so let’s import it and use in HTML. Then, to position it, declare a new variable called LogoContainer which is a div.
import Logo from "./components/Logo";
<LogoContainer>
<Logo />
</LogoContainer>
const LogoContainer = styled.div`
position: absolute;
top: 44px;
left: 0px;
`;
Text Container
Then, we have a bunch of texts. Declare a TextContainer, a Title and a Description. Don’t forget to import the TextStyles.
<TextContainer>
<Title>3D Room with Game Controls</Title>
<Description>
Learn how to create a 3D scene in Spline with game interactions
like moving, jumping, mouse events and dark mode state.
</Description>
</TextContainer>
const TextContainer = styled.div`
display: grid;
gap: 24px;
max-width: 460px;
padding: 225px 0px 0px 56px;
`;
const Title = styled(TextStyles.H1)``;
const Description = styled.p`
max-width: 360px;
text-align: left;
font-family: "Inter", BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu,
Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
font-style: normal;
font-weight: 500;
font-size: 17px;
line-height: 21px;
color: rgba(0, 0, 0, 0.6);
margin: 0;
`;
Button Container
Then, we have the download and play button. Declare a ButtonContainer with a grid so we can position them side by side. For the download button, we can add the a tag to download the file. Make sure to import the download, play button and the download file.
import DownloadButton from "./components/DownloadButton";
import PlayButton from "./components/PlayButton";
import DownloadFile from "./smart_home_final.spline.zip";
<ButtonContainer>
<a href={DownloadFile} target="_blank" rel="noreferrer">
<DownloadButton />
</a>
<PlayButton />
</ButtonContainer>
const ButtonContainer = styled.div`
display: grid;
grid-template-columns: auto auto;
justify-content: start;
gap: 20px;
background: linear-gradient(
270deg,
#f1f1f1 12.86%,
rgba(255, 255, 255, 0) 83.72%
);
mix-blend-mode: normal;
padding: 40px 0px 40px 56px;
margin-top: 53px;
a {
text-decoration: none;
}
`;
Shadow
Right below the buttons, we have a shadow and the best way to replicate this UI is by using a gradient.
<GradientLine />
const GradientLine = styled.div`
width: 100%;
height: 48px;
background: linear-gradient(
185deg,
rgba(0, 0, 0, 0.2) 0%,
rgba(255, 255, 255, 0) 50%
);
`;
Controls
Next, we have the controls. So, let’s declare the container, a Subtitle and the ControlImage. Don’t forget to import the image.
import ImageControl from "./images/controls.png";
<ControlContainer1>
<Subtitle>Keyboard key</Subtitle>
<ControlImage src={ImageControl} alt="controls image" />
</ControlContainer1>
const ControlContainer1 = styled.div`
display: block;
`;
const Subtitle = styled(TextStyles.BodyMain)`
color: rgba(0, 0, 0, 0.6);
margin-top: 14px;
padding-left: 56px;
`;
const ControlImage = styled.img`
max-width: 326px;
padding: 14px 0px 0px 56px;
`;
Container
Based on the design, you can see that we have a left side which contains the texts, buttons and controls, and the right layout which has the Spline scene. Let’s insert a container to keep all these elements together.
<ContentWrapper>
<Container>
</Container>
</ContentWrapper>
const ContentWrapper = styled.div`
display: grid;
grid-template-columns: auto 855px;
max-width: 1440px;
width: 100%;
margin: 0 auto;
`;
const Container = styled.div`
position: relative;
`;
Spline Container
On the other side, declare a Spline Container which will contain the Header, CloseButton and the Spline scene.
import Header from "./components/Header";
import SplineScene from "./components/SplineScene";
import CloseButton from "./components/CloseButton";
<SplineContainer>
<Header />
<CloseButton/>
<SplineScene/>
</SplineContainer>
const SplineContainer = styled.div`
position: relative;
padding: 24px 20px 24px 0px;
.closeButton {
top: 54%;
left: -32px;
}
`;
useState
Similar to Spline, React has a state system called useState. The goal is to pass from window size to fullscreen and vice versa. First, import useState from react and then, set the state. The initial value is false. The PlayButton is the trigger so we will set the onClick event on it and set the state to true.
const [isOpen, setIsOpen] = useState(false);
<PlayButton onClick={() => setIsOpen(true)} />
Props
When you click on the PlayButton, nothing really happens, the event is there and the state is changing but we aren’t changing the CSS appropriately. In SplineContainer, we will use the state to switch between 2 different styles.
<SplineContainer isOpen={isOpen}>
<Header />
<CloseButton isOpen={isOpen} onClick={() => setIsOpen(false)} />
<SplineScene />
</SplineContainer>
const SplineContainer = styled.div`
position: ${(props) => (props.isOpen ? "fixed" : "relative")};
padding: ${(props) => (props.isOpen ? "0px" : "24px 20px 24px 0px")};
top: 0;
left: 0;
bottom: 0;
right: 0;
overflow: auto;
.spline {
border-radius: ${(props) => (props.isOpen ? "0px" : "20px")};
}
`;
Responsiveness
It is really important to think about how your website will look like on a smaller screen. If it is not adaptive, your website will break at a certain screen size. To fix this issue, we will use media queries. There’s 3 screen sizes that we have to take into consideration: over 1400px, below 1400px and below 560px. At 1400px, the layout changes from left and right side to a single column. When this happens, we need to change the position of the close button. The text container will have less paddings. We will remove the gradient. We will also remove the controls.
const ContentWrapper = styled.div`
@media (max-width: 1400px) {
grid-template-columns: 1fr;
align-content: center;
padding-bottom: 40px;
}
`;
const SplineContainer = styled.div`
@media (max-width: 1400px) {
padding: ${(props) => (props.isOpen ? "0px" : "0px 20px 10px")};
.closeButton {
top: -44px;
left: 50%;
margin-left: -50px;
transform: rotate(90deg);
}
}
`;
const GradientLine = styled.div`
@media (max-width: 1400px) {
display: none;
}
`;
const ControlContainer1 = styled.div`
@media (max-width: 1400px) {
display: none;
}
`;
Second controls
In the design, we can see that the controls are below the scene, there’s multiple ways to go about this but I think the most understandable one is to add a second controls. Set the display to none and only show when we hide the first one.
<ControlContainer2>
<Subtitle>Keyboard key</Subtitle>
<ControlImage src={ImageControl} alt="controls image" />
</ControlContainer2>
const ControlContainer2 = styled.div`
display: none;
@media (max-width: 1400px) {
display: block;
}
`;
Mobile responsiveness
At the smaller screen size, the text container will have less paddings. On the button container, we will change the layout to be a single column. Reduce the paddings on the subtitle and the image.
const TextContainer = styled.div`
@media (max-width: 560px) {
padding: 145px 20px 0px;
}
`;
const ButtonContainer = styled.div`
@media (max-width: 560px) {
grid-template-columns: auto;
justify-content: center;
justify-items: center;
align-content: center;
padding: 32px 20px;
margin-top: 40px;
}
`;
const Subtitle = styled(TextStyles.BodyMain)`
@media (max-width: 560px) {
padding: 8px 20px;
}
`;
const ControlImage = styled.img`
@media (max-width: 560px) {
padding: 8px 20px;
}
`;
Templates and source code
Download source files
Download the videos and assets to refer and learn offline without interuption.
Design template
Source code for all sections
Video files, ePub and subtitles
Subtitles
Videos
Assets
1
Intro to Game Controls
Use key inputs, joysticks, buttons, gravity, and collision detection to move your character through your scene
4:26
2
States, Events & Animations
Animate objects by using state-based animations
13:03
3
Movement & Controls
Use game controls to move an object in your scene
5:26
4
Collision Detection
Set a shape to your character to enable collisions
10:15
5
Physics
Make your object dynamic in a 3D environment
4:34
6
3D Camera & Lighting
Customize your camera to make your scene looks stunning
16:10
7
Audio & Sounds
Elevate your scene with beautiful sounds
6:32
8
URL & Embed
Export your 3D scene in web with no code
4:16
9
Export in React Site
Export your design in a React environment
29:31
10
Performance & 3D Vitals
Monitor and optimize your scene using 3D Vitals
4:28
Meet the instructor
We all try to be consistent with our way of teaching step-by-step, providing source files and prioritizing design in our courses.
Willie Yam
Front-end/UI developer at Design+Code
I do UI coding. HTML/CSS/JS/SWIFTUI dev.
10 courses - 37 hours

Design and Prototype an App with Play
Build a completely functional prototype without writing a single line of code from your phone
3 hrs

Create a 3D site with game controls in Spline
Build an interactive 3D scene implemented on a ReactJS site using Figma and Spline
2 hrs

Build a Movie Booking App in SwiftUI
Learn how to create an iOS app based on a beautiful UI design from Figma with interesting animations and interactions, create a custom tab bar and use navigation views to build a whole flow
1 hrs

Build Quick Apps with SwiftUI
Apply your Swift and SwiftUI knowledge by building real, quick and various applications from scratch
11 hrs

CSS Handbook
A comprehensive series of tutorials that encompass styled-components, CSS, and all layout and UI developments
1 hrs

Advanced React Hooks
Learn how to build a website with Typescript, Hooks, Contentful and Gatsby Cloud
5 hrs

Unity for Designers
If you want to make a game and don't know where to start, you are in the right place. I will teach you how to use Unity, code in C# and share essential tips and tricks to make your first game.
5 hrs

Create a Javascript Game
Learn how to create a web game using Phaser 3, a popular javascript game engine. Draw a map using an editor, implement the player, make the player move, apply physics, collisions, and implement the enemies.
2 hrs

Build an ARKit 2 App
Introduction to ARKit and learn how to make your own playground. You will be able to add models or even your own designs into the app and play with them
4 hrs

Create a SpriteKit Game
Overview of SpriteKit a powerful 2D sprite-based framework for games development from Apple and learn how to create your very own platform
3 hrs