Responsive Layout
Rive’s new Layout feature lets you design resizable artboards with built-in responsive behavior, configured directly in the graphic. Just set a Fit of type Layout at runtime and the artboard will resize automatically. Optionally, provide a Layout Scale Factor to further adjust the scale of the content.
For more Editor information and how to configure your graphic see Layouts Overview.
The Alignment property will not have an effect when the using a Fit of type Layout.
Web
React
React Native
Flutter
Apple
Android
Steps
- Set
fit to Fit.Layout - this will automatically scale and resize the artboard to match the canvas size when calling resizeDrawingSurfaceToCanvas().
- Optionally set
layoutScaleFactor for manual control of the artboard size (scale factor).
- Subscribe to
window.onresize and call resizeDrawingSurfaceToCanvas() to adjust the artboard size as the canvas and window changes.
- Subscribe to device pixel ratio changes and call
resizeDrawingSurfaceToCanvas() to ensure the artboard updates correctly on various screen densities. For example, when dragging the window between multiple monitors with different device pixel ratios.
<style>
body {
background: #f0f0f0;
margin: 0;
overflow: hidden;
}
canvas {
background-color: red;
display: block;
width: 100vw;
height: 100vh;
}
</style>
<canvas id="riveCanvas"></canvas>
<script src="https://unpkg.com/@rive-app/canvas@latest"></script>
<script>
const rive = new Rive({
src: "your-rive-file.riv",
autoplay: true,
canvas: riveCanvas,
layout: new Layout({
fit: Fit.Layout,
// layoutScaleFactor: 2, // 2x scale of the layout, when using `Fit.Layout`. This allows you to resize the layout as needed.
}),
stateMachines: ["State Machine 1"],
onLoad: () => {
computeSize();
},
});
function computeSize() {
rive.resizeDrawingSurfaceToCanvas();
}
// Subscribe to window size changes and update call `resizeDrawingSurfaceToCanvas`
window.onresize = computeSize;
// Subscribe to devicePixelRatio changes and call `resizeDrawingSurfaceToCanvas`
window
.matchMedia(`(resolution: ${window.devicePixelRatio}dppx)`)
.addEventListener("change", computeSize);
</script>
Steps
- Set
fit to Fit.Layout in the Layout object - this will automatically scale and resize the artboard to match the canvas size.
- Pass the
Layout object to the layout prop in useRive.
- Optionally set
layoutScaleFactor in the Layout object for manual control of the artboard’s scale factor.
- The React runtime automatically handles window resizing and device pixel ratio changes.
import { useRive, Layout, Fit } from "@rive-app/react-canvas";
export const RiveComponent = () => {
const { RiveComponent } = useRive({
src: "your-rive-file.riv",
stateMachines: "State Machine 1",
layout: new Layout({
fit: Fit.Layout,
// layoutScaleFactor: 2, // Optional: 2x scale of the layout
}),
autoplay: true,
});
return <RiveComponent />;
};
ExamplesSteps
- Set
fit to Fit.Layout - this will automatically scale and resize the artboard to match the canvas size.
- Optionally set
layoutScaleFactor in the Layout object for manual control of the artboard’s scale factor.
- The React runtime automatically handles window resizing and device pixel ratio changes.
import Rive, { Fit } from 'rive-react-native';
const resourceName = 'layout_test';
export default function ResponsiveLayout() {
return (
<Rive
autoplay={true}
fit={Fit.Layout}
layoutScaleFactor={0.5} // If you do not set this (or set equal to "-1.0"), Rive will automatically scale the layout to match the device pixel ratio
resourceName={resourceName}
artboardName={'Artboard'}
stateMachineName={'State Machine 1'}
/>
);
}
Pass the Fit.layout to the RiveWidget widget. This will automatically scale and resize the artboard to match the widget size.
You can also set the layoutScaleFactor to control the scale of the artboard. This is useful for adjusting the size of the artboard when using Fit.layout.return RiveWidget(
controller: controller,
fit: Fit.layout,
layoutScaleFactor: 2.0, // Optional: 2x scale of the layout,
);
Alternatively, you can also set the fit and layoutScaleFactor properties directly on any RivePainter, such as the RiveWidgetController:final controller = RiveWidgetController(riveFile);
controller.fit = Fit.layout;
controller.layoutScaleFactor = 2.0; // Optional: 2x scale of the layout
ExamplesSteps
- Set
fit on an instance of RiveViewModel to layout
- Optionally set
layoutScaleFactor on RiveViewModel for manual control of an artboard’s scale factor.
To enable automatically determining the scale factor, set .layoutScaleFactor to RiveViewModel.layoutScaleFactorAutomatic. This is the default value; it is equivalent to -1. When set, Rive will listen for window and screen changes for the view model’s view, and automatically apply the correct scale factor for the current view hierarchy.
let viewModel = RiveViewModel(fileName: "...")
viewModel.fit = .layout
viewModel.layoutScaleFactor = RiveViewModel.layoutScaleFactorAutomatic // Allow Rive to determine the scale factor
viewModel.layoutScaleFactor = 2.0 // Or, explicitly set the scale factor
ExamplesSee the Layout example.Steps
- Set the XML
riveLayout type to "LAYOUT":
<app.rive.runtime.kotlin.RiveAnimationView
...
app:riveFit="LAYOUT"
/>
- Alternatively, use a reference to the
RiveAnimationView and set the fit property to LAYOUT:
val animationView = findViewById<RiveAnimationView>(R.id.my_view)
animationView.fit = Fit.LAYOUT
- To adjust the scale factor of the contents, use the
layoutScaleFactor property. This is nullable, so by default, it will use the density as reported by resources.displayMetrics.density. You can override this to any positive float value, or return control to the system by resetting to null:
// Force a set scale factor
animationView.layoutScaleFactor = 2.5f
// Reset to system control
animationView.layoutScaleFactor = null
- Additionally, the artboard size can be controlled by using the
width and height properties. resetArtboardSize() can be used to return these values to their defaults:
// Force a certain artboard size
animationView.controller.activeArtboard?.width = 1000f
animationView.controller.activeArtboard?.height = 1000f
// Reset the artboard size to defaults
animationView.controller.activeArtboard?.resetArtboardSize()
Additional Layout Options
If the graphic doesn’t use Rive’s Layout feature, you can configure the layout with other Fit options and Alignment settings. See the sections below for more information on Fit and Alignment.
Web
React
React Native
Flutter
Apple
Android
Use the Layout object to configure Fit and Alignment. See Fit and Alignment below for all enum options.<div>
<canvas id="canvas" width="800" height="600"></canvas>
</div>
<script src="https://unpkg.com/@rive-app/canvas@latest"></script>
<script>
// Fill the canvas, cropping Rive if necessary
let layout = new rive.Layout({
fit: rive.Fit.Cover,
});
// Fit to the width and align to the top of the canvas
layout = new rive.Layout({
fit: rive.Fit.FitWidth,
alignment: rive.Alignment.TopCenter,
});
// Constrain the Rive content to (minX, minY), (maxX, maxY) in the canvas
layout = new rive.Layout({
fit: rive.Fit.Contain,
minX: 50,
minY: 50,
maxX: 100,
maxY: 100,
});
const r = new rive.Rive({
src: 'https://cdn.rive.app/animations/vehicles.riv',
canvas: document.getElementById('canvas'),
layout: layout,
autoplay: true
});
// Update the layout
r.layout = new rive.Layout({ fit: rive.Fit.Fill });
</script>
Use the Layout object to configure Fit and Alignment. See Fit and Alignment below for all enum options.import Rive, { Layout, Fit, Alignment } from '@rive-app/react-canvas';
export const Simple = () => (
<Rive
src="https://cdn.rive.app/animations/vehicles.riv"
layout={new Layout({ fit: Fit.Contain, alignment: Alignment.TopCenter })}
/>
);
With the useRive hook:import { useRive, Layout, Fit, Alignment } from '@rive-app/react-canvas';
export default function Example() {
const { RiveComponent } = useRive({
src: 'my-file.riv',
artboard: 'my-artboard',
animations: 'my-animation',
layout: new Layout({
fit: Fit.Cover,
alignment: Alignment.TopCenter,
}),
autoplay: true,
});
return <RiveComponent />;
}
Set layout attributes for Fit and Alignment on the Rive component directly. See Fit and Alignment below for all enum options.import Rive, { Alignment, Fit } from 'rive-react-native';
export default function Simple() {
return (
<ScrollView>
<Rive
fit={Fit.Cover}
alignment={Alignment.TopCenter}
resourceName="truck_v7"
/>
</ScrollView>
);
};
Pass the Fit and Alignment to the RiveWidget widget.return RiveWidget(
controller: controller,
fit: Fit.contain,
alignment: Alignment.center,
);
Alternatively, you can also the set fit and alignment properties directly on any RivePainter, such as the RiveWidgetController:final controller = RiveWidgetController(riveFile);
controller.fit = Fit.contain;
controller.alignment = Alignment.center;
See values and descriptions in the sections below for Fit and Alignment. The runtime provides the following enums to set on layout parameters:
-
Fit
.fill
.contain
.cover
.fitWidth
.fitHeight
.scaleDown
.noFit
-
Alignment
.topLeft
.topCenter
.topRight
.centerLeft
.center
.centerRight
.bottomLeft
.bottomCenter
.bottomRight
SwiftUI
The following example shows how to set layout parameters and switch them at runtime:struct SwiftLayout: View {
@State private var fit: RiveFit = .contain
@State private var alignment: RiveAlignment = .center
var body: some View {
VStack {
RiveViewModel(fileName: "fancy_rive_file", fit: fit, alignment: alignment).view()
}
HStack {
Text("Some Fit Examples")
}
HStack {
Button("Fill") { fit = .fill }
Button("Contain") { fit = .contain }
Button("Cover") { fit = .cover }
}
HStack {
Text("Some Alignment Examples")
}
HStack {
Button("Top Left") { alignment = .topLeft }
Button("Top Center") { alignment = .topCenter }
Button("Top Right") { alignment = .topRight }
}
}
}
UIKit
The following example shows how to set layout parameters and switch them at runtime:class LayoutViewController: UIViewController {
@IBOutlet weak var riveView: RiveView!
var viewModel = RiveViewModel(fileName: "fancy_rive_file")
override func viewDidLoad() {
viewModel.setView(riveView)
}
@IBAction func fitButtonTriggered(_ sender: UIButton) {
setFit(name: sender.currentTitle!)
}
@IBAction func alignmentButtonTriggered(_ sender: UIButton) {
setAlignment(name: sender.currentTitle!)
}
func setFit(name: String) {
var fit: RiveFit = .contain
switch name {
case "Fill": fit = .fill
case "Contain": fit = .contain
case "Cover": fit = .cover
case "Fit Width": fit = .fitWidth
case "Fit Height": fit = .fitHeight
case "Scale Down": fit = .scaleDown
case "None": fit = .noFit
default: fit = .contain
}
viewModel.fit = fit
}
func setAlignment(name: String) {
var alignment: RiveAlignment = .center
switch name {
case "Top Left": alignment = .topLeft
case "Top Center": alignment = .topCenter
case "Top Right": alignment = .topRight
case "Center Left": alignment = .centerLeft
case "Center": alignment = .center
case "Center Right": alignment = .centerRight
case "Bottom Left": alignment = .bottomLeft
case "Bottom Center": alignment = .bottomCenter
case "Bottom Right": alignment = .bottomRight
default: alignment = .center
}
viewModel.alignment = alignment
}
}
The animation view can be further customized as part of specifying layout attributes.riveFit can be specified to determine how the animation should be resized to fit its container. The available choices are NONE, FILL, CONTAIN, COVER, FIT_WIDTH, FIT_HEIGHT, SCALE_DOWN, and LAYOUT.riveAlignment informs how it should be aligned within the container. The available choices are TOP_LEFT, TOP_CENTER, TOP_RIGHT, CENTER_LEFT, CENTER, CENTER_RIGHT, BOTTOM_LEFT, BOTTOM_CENTER, and BOTTOM_RIGHT.See more about these values and meanings in the sections below.Specify the layout values in your Resource layout:<app.rive.runtime.kotlin.RiveAnimationView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:riveResource="@raw/off_road_car_blog"
app:riveAlignment="TOP_CENTER"
app:riveFit="FILL"
/>
Or in your Activity code:animationView.fit = Fit.FILL
animationView.alignment = Alignment.CENTER
Fit
Fit determines how the Rive content will be fitted to the view. There are a number of options available:
Layout: Rive content will be resized automatically based on layout constraints of the artboard to match the underlying view size. See the above for more information on how to use this option.
Cover: Rive will cover the view, preserving the aspect ratio. If the Rive content has a different ratio to the view, then the Rive content will be clipped.
Contain: (Default) Rive content will be contained within the view, preserving the aspect ratio. If the ratios differ, then a portion of the view will be unused.
Fill: Rive content will fill the available view. If the aspect ratios differ, then the Rive content will be stretched.
FitWidth: Rive content will fill to the width of the view. This may result in clipping or unfilled view space.
FitHeight: Rive content will fill to the height of the view. This may result in clipping or unfilled view space.
None: Rive content will render to the size of its artboard, which may result in clipping or unfilled view space.
ScaleDown: Rive content is scaled down to the size of the view, preserving the aspect ratio. This is equivalent to Contain when the content is larger than the canvas. If the canvas is larger, then ScaleDown will not scale up.
Alignment
Alignment determines how the content aligns with respect to the view bounds. The following options are available:
Center (Default)
TopLeft
TopCenter
TopRight
CenterLeft
CenterRight
BottomLeft
BottomCenter
BottomRight
Bounds
The bounds for the area in which the Rive content will render can be set by providing the minimum and maximum x and y coordinates. These coordinates are relative to the view in which the Rive content is contained, and all must be provided. These will override alignment settings.