Aurora Mesh Background
An animated aurora background made with a mesh gradient.

- Backgrounds
- iOS 18.0+
- intermediate
- Origin
- Original work
- Found by
- background · aurora · mesh gradient · gradient · animated · ambient · colors · fondo · aurora · degradado · malla · gradiente · animado · colores
Description
Section titled “Description”A slowly moving aurora built with a mesh gradient.
With Reduce Motion on, it shows a still gradient.
struct AuroraMeshBackgroundDemo: View { var body: some View { ZStack { AuroraMeshBackground()
Text("Aurora") .font(.system(.largeTitle, design: .rounded, weight: .bold)) .foregroundStyle(.white) } }}API reference
Section titled “API reference”| Parameter | Type | Default |
|---|---|---|
first | Color | .indigo |
second | Color | .purple |
third | Color | .teal |
speed | Double | 0.6 |
Copy this code into your project, or download the file.
// SPDX-License-Identifier: MIT// Copyright (c) 2026 Oscar Canton and SwiftUI Blocks contributors
import SwiftUI
/// A slowly moving aurora built with a mesh gradient.////// With Reduce Motion on, it shows a still gradient.struct AuroraMeshBackground: View { var first: Color = .indigo var second: Color = .purple var third: Color = .teal var speed: Double = 0.6
@Environment(\.accessibilityReduceMotion) private var reduceMotion
var body: some View { TimelineView(.animation(minimumInterval: 1.0 / 30.0, paused: reduceMotion)) { context in MeshGradient( width: AuroraMesh.size, height: AuroraMesh.size, points: AuroraMesh.points(at: reduceMotion ? 0 : context.date.timeIntervalSinceReferenceDate * speed), colors: [ first, second, first, third, second, first, second, first, third, ] ) } .ignoresSafeArea() .accessibilityHidden(true) }}
enum AuroraMesh { static let size = 3
/// Corners stay fixed and edge points slide along their edge, so the mesh always fills the view. static func points(at time: TimeInterval) -> [SIMD2<Float>] { func wave(speed: Double, phase: Double) -> Double { 0.5 + sin(time * speed + phase) * 0.2 }
let positions: [(Double, Double)] = [ (0, 0), (wave(speed: 0.8, phase: 2.1), 0), (1, 0), (0, wave(speed: 0.9, phase: 0)), (wave(speed: 1, phase: 0.7), wave(speed: 0.6, phase: 4.2)), (1, wave(speed: 0.7, phase: 1.3)), (0, 1), (wave(speed: 1.1, phase: 3.4), 1), (1, 1), ] return positions.map { SIMD2(Float($0.0), Float($0.1)) } }}
// MARK: - Demo
struct AuroraMeshBackgroundDemo: View { var body: some View { ZStack { AuroraMeshBackground()
Text("Aurora") .font(.system(.largeTitle, design: .rounded, weight: .bold)) .foregroundStyle(.white) } }}
#Preview { AuroraMeshBackgroundDemo()}