• Stars
    star
    285
  • Rank 140,415 (Top 3 %)
  • Language
    Swift
  • License
    MIT License
  • Created about 3 years ago
  • Updated 9 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Shimmering SwiftUI Views using device orientation.

LookingGlassUI Logo with a rectangular border in shimmering gold on black

Swift Compatibility Platform Compatibility License - MIT Version GitHub last commit Mastodon Twitter

Overview

A Swift Package with SwiftUI views that can rotate views based on device orientation. It's especially useful in faking a light reflection to create a shimmering effect when the device rotates.

  • .motionManager() - A view modifier that creates a MotionManager class that gets device rotation information from Core Motion and adds it into the environment for other views to access.
  • ShimmerView - A view similar to color that shimmers with another color as if reflecting light when your device rotates.
  • .shimmer() - A view modifier that overlays a shimmer color on any view as the device rotates.
  • .parallax() - A view modifier that applies a parallax effect on any view as the device rotates.
  • LookingGlass - A view that rotates its child view to a specific 3d angle relative to the real world and positions it relative to the device.
  • .deviceRotationEffect() - A view modifier that rotates a view based on device rotation.

Gold Shimmer Demo

This package is currently used to create a gold shimmer effect on many gold elements in the Old English Wordhord app. Download it to see the effect in action.

An iphone rotated back and forth showing the Old English Wordhord App with all the gold elements shimmering as if reflecting light. A screen recording on the right shows the same content.

Download on the App Store

LookingGlassUIExample

Check out the example app to see how you can use this package in your iOS app.

Installation

  1. In Xcode go to File -> Add Packages
  2. Paste in the repo's url: https://github.com/ryanlintott/LookingGlassUI and select main branch or select by version.

Usage

Import the package using import LookingGlassUI

Platforms

This package is compatible with iOS 13 or later. It's technically compatible with macOS 10.15 or later but hasn't been tested.

Is this Production-Ready?

Really it's up to you. I currently use this package in my own Old English Wordhord app.

Support

If you like this package, buy me a coffee to say thanks!

ko-fi

Details

.motionManager()

Before adding any custom views, add the .motionManager view modifier once, somewhere in the heirarchy above any other views or modifiers used in this package.

ContentView()
    .motionManager(updateInterval: 0.1, disabled: false)

ShimmerView

Use ShimmerView if you want a view that acts like Color but with a default shimmer effect. If MotionManager is disabled only the background color will be shown.

ShimmerView(color: .goldShimmer, background: .gold)

.shimmer()

Use .shimmer() view modifier if you want to add a default shimmer effect to another SwiftUI View. If MotionManager is disabled the modifier has no effect.

Text("Hello, World!")
    .shimmer(color: .gold)

.parallax()

Use .parallax(multiplier: CGFloat, maxOffset: CGFloat) view modifier if you want to add a parallax effect to any SwiftUI View. If MotionManager is disabled the modifier has no effect.

Text("Hello, World!")
    .parallax(multiplier: 40, maxOffset: 100)

LookingGlass

Use LookingGlass if you want to project any SwiftUI view or create your own custom effect. Content appears as if rotated and positioned from the center of the device regardless of positioin on the screen or if it's in a scrollview. If MotionManager is disabled nothing will be shown.

LookingGlass(.reflection, distance: 4000, perspective: 0, pitch: .degrees(45), yaw: .zero, localRoll: .zero, isShowingInFourDirections: false) {
    Text("Hello, World")
        .foregroundColor(.white)
        .frame(width: 500, height: 500)
        .background(Color.red)
}

.deviceRotationEffect()

Use .deviceRotationEffect() if you want to rotate a view based on device rotation. Content is rotated and positioned based on it's own center. If MotionManager is disabled nothing will be shown.

Text("Hello, World")
    .foregroundColor(.white)
    .frame(width: 500, height: 500)
    .background(Color.red)
    .deviceRotationEffect(.reflection, distance: 4000, perspective: 0, pitch: .degrees(10), yaw: .zero, localRoll: .zero, isShowingInFourDirections: false)

How it Works

Window and Reflection Modes

In window mode a view appears as if your phone is a window looking into a 3d environment.

In reflection mode a view appears as if your phone has a camera pointing out of the screen back at a 3d envrionment. It's not a true reflection as it doesn't take into account the viewer's eye location but it's a useful approximation.

Positioning View

Views are positioned based on a quaternion or pitch, yaw, and local roll angles. All angles at zero means the view will be visible when the phone is flat with the top pointing away from the user. (see diagram below)

  1. Local Roll rotate the view around the Z axis. 10 degrees will tilt the view counter-clockwise
  2. Pitch will rotate the view around the X axis. 90 degrees will bring the view up directly in front of the user.
  3. Yaw will rotate the view around the Z axis again. 5 degrees will move the view slightly to the left of the user. If you set isShowingInFourDirections to true the view will be copied 3 additional times and rotated at -90, 90, and 180 degrees from the position you chose.
  4. The view is then moved away from the origin based on the distance provided. The direction is dependant on choosing window or reflection.
  5. As the user moves their device around they will always see your view in the location you've set.

Don't worry about device orientation. Although Core Motion doesn't compensate for this, LookingGlassUI does.

Digram titled LookingGlassUI Rotation: View Rotation Axes shows a tall grey rectangle flat one a surface with positive Z up, positive Y to the top of the rectangle and positive X to the right. Positive Z is World Up and positive Y is the top of view at zero, the direction user was facing when app was opened. Z axis has Yaw and Local Roll rotational arrows and X axis has Pitch. All arrows follow right hand rule. Another rectangle rotated 90 degrees is on top and a note reads: Orientation changes will not change axes.

Additional Rotation Diagrams

3D space is confusing on iOS, especially as Core Motion and SwiftUI's rotation3dEffect each seem to use different axes. I created this diagram to keep track of how each one works. You probably won't need these unless you want to do something more custom. It's important to note that the Screen Rotation Axes are only used for determining rotation direction using the right hand rule for a rotating body. When translating a view (using .offset or similar), the axes are different with +Y towards the bottom of the screen and +X to the right. These axes are not needed as we only deal with rotation

iOS Rotation. One diagram on the left titled: Device Rotation Axes (Core Motion) shows a tall grey rectangle flat on a surface with positive Z up, positive Y to the top of the rectangle and positive X to the right. Axes have Yaw, Roll, and Pitch rotational arrows respectively, each following the right hand rule. An additional note says: Device axis do not change when orientation changes. Another diagram on the right titled: Screen Rotation Axes (SwiftUI .rotation3dEffect) shows a tall grey rectangle flat on a surface with negative Z up, positive Y to the top of the device and negative X to the right. Axes have Yaw, Roll, and Pitch rotational arrows respectively, each following the right hand rule. Another rectangle rotated 90 degrees is on top and a note reads: Screen top changes if app supports multiple orientation.

Dependencies

Fireblade Math, Copyright (c) 2018-2021 Christian Treffs

More Repositories

1

FrameUp

Reframing SwiftUI Views. A collection of tools to help with layout.
Swift
173
star
2

ShapeUp

Make shapes and cut corners in SwiftUI
Swift
101
star
3

SSVEP_keyboard

The SSVEP Keyboard works with the icibici hardware. Once connected you should be able to look at keys and it will type them for you.
C#
41
star
4

ZoomImageViewer

A SwiftUI fullscreen image viewer with smooth and bouncy pinch-zooming, scrolling, double-tap zoom in and out, and swipe to dismiss.
Swift
29
star
5

DragAndDrop

Example app for iLikeToMoveIt
Swift
26
star
6

ILikeToMoveIt

Accessible move actions for SwiftUI Lists and easy custom drag and drop for older iOS
Swift
26
star
7

OvercastDrawer

Demo of the Overcast Drawer in SwiftUI
Swift
19
star
8

OEVoice

Old English text-to-speech using AVSpeechSynthesis and IPA pronunciations.
Swift
18
star
9

LayoutThatFits

A SwiftUI Layout that chooses the Layout that fits.
Swift
17
star
10

ShiftUI

A SwiftUI sliding tile puzzle with a neumorphic design
Swift
10
star
11

WordpressReader

A simple asynchronous way to download and decode public Wordpress content.
Swift
9
star
12

MessageMaker

App for making message bubbles out of raw text.
Swift
7
star
13

LookingGlassUIExample

Example App for LookingGlassUI
Swift
5
star
14

RotationMatchingOrientation

Rotates any SwiftUI view to match device orientation
Swift
5
star
15

FrameUpExample

Example app for FrameUp
Swift
4
star
16

Molt

A relaxation app where you toss away your stressful thoughts (represented by sticky notes) and pause for a few minutes with a peaceful scene.
Swift
4
star
17

DefibHeart

Swift
3
star
18

WordpressReaderExample

Example app for WordpressReader
Swift
3
star
19

ZoomImageViewerExample

Example App for ZoomImageViewer
Swift
3
star
20

ShapeUpExample

Example Project for ShapeUp
Swift
2
star
21

OEVoiceExample

Example app for OEVoice package
Swift
2
star