@capgo/capacitor-screen-orientation

中文文档
8.4.3发布于 2026/10/15MPL-2.0TypeScriptESM + CJS零依赖构建来源已验证近 30 天下载 4.3万

Screen orientation plugin with support for bypassing orientation lock

原始使用文档
文档目录30 节
  1. ➡️ Get started for free
  2. Features
  3. Foldable devices
  4. Documentation
  5. Compatibility
  6. Install
  7. iOS Configuration
  8. Usage
  9. API
  10. orientation()
  11. lock(...)
  12. unlock()
  13. startOrientationTracking(...)
  14. stopOrientationTracking()
  15. isOrientationLocked()
  16. isDeviceFoldable()
  17. getFoldState()
  18. getHingeAngle()
  19. getReservedRegions()
  20. getBarPlacement()
  21. setVerticalBarBehavior(...)
  22. getSizeClass()
  23. addListener('screenOrientationChange', ...)
  24. addListener('foldStateChange', ...)
  25. addListener('hingeAngleChange', ...)
  26. addListener('sizeClassChange', ...)
  27. removeAllListeners()
  28. getPluginVersion()
  29. Interfaces
  30. Type Aliases

@capgo/capacitor-screen-orientation

Capgo - Build Capacitor apps with AI, ship updates instantly

Capgo: push fixes to your Capacitor users in minutes, build signed iOS and Android apps without a Mac, and roll back in one click.

➡️ Get started for free

14-day unlimited free trial. No credit card required

🤖 Building with an AI coding agent? Install Capgo skills so Claude Code, Codex, Cursor, Copilot, or Gemini CLI know how to install and use @capgo/capacitor-screen-orientation in your Capacitor app: npx skills add Cap-go/capgo-skills. Then ask your agent: "Add @capgo/capacitor-screen-orientation to my Capacitor app and wire it up." Agent setup guides · Hosted MCP

Screen orientation plugin with support for detecting true physical device orientation

Features

  • 📱 Full Screen Orientation API support
  • 🔍 Detect true physical device orientation using motion sensors (even when orientation lock is enabled)
    • iOS: Uses Core Motion framework
    • Android: Uses accelerometer sensor
  • 🔒 Detect if orientation lock is enabled by comparing physical vs UI orientation
  • 🔄 Real-time orientation change detection
  • 🎯 Lock orientation to specific modes
  • 📖 Foldable devices (Galaxy Z Fold/Flip, Pixel Fold, Surface Duo, iPhone Duo): posture, hinge, size classes, and live fold updates
  • 🌐 Web platform support

Important Note: This plugin can detect the physical orientation of the device using motion sensors, but it cannot bypass the UI orientation lock. The screen will still respect the user's orientation lock setting. This is useful for knowing how the device is physically held vs. how the UI is displayed.

Foldable devices

Foldables give you more than a wider canvas: the hinge, cover screen, and posture change how people hold the phone. This plugin reports that state in JavaScript so you can adapt layouts, controls, and media without guessing from window size alone. It targets Galaxy Z Fold and Flip, Pixel Fold, Surface Duo, and iPhone Duo (iOS 27.1+), alongside the orientation APIs already in this package.

What you get

  • Device and posture: isDeviceFoldable(), getFoldState() (flat / half-opened, posture flat / tabletop / book, hinge bounds, separating fold, occluded hinge area when applicable)
  • Hinge angle: getHingeAngle() and hingeAngleChange (native sensor on Android; iPhone Duo on iOS 27.1+; null on web)
  • Layout signals: getSizeClass() and sizeClassChange (Apple compact/regular plus Material width/height classes)
  • iPhone Duo extras: activeDisplay (inner / outer), getReservedRegions(), getBarPlacement(), setVerticalBarBehavior()
  • Live updates: foldStateChange when posture or hinge geometry changes the reported fold state (rotation alone may not fire if devicePosture is available but usable viewport segments are not)

Good fits

  • Two-pane layouts that follow the hinge instead of a fixed breakpoint
  • Toolbar, gamepad, or reader chrome that moves when the user folds to tabletop or book
  • Cover-screen vs inner-screen flows on foldables and iPhone Duo
  • Size-class driven UI that reacts when the user opens the device fully

Quick start

import { ScreenOrientation } from '@capgo/capacitor-screen-orientation';

const fold = await ScreenOrientation.getFoldState();
console.log(fold.posture, fold.hingeBounds);

await ScreenOrientation.addListener('foldStateChange', (state) => {
  document.documentElement.dataset.posture = state.posture;
});

iPhone Duo (iOS 27.1+)

PosepostureHinge (typical)
Open flat, or closed on the outer displayflat180 open, 0 closed
Held half-open like a bookbookvertical hinge, about 20 to 160
Propped half-open like a laptoptabletophorizontal hinge

iPhone Duo simulator on the cover display, reporting flat posture and outer display

Non-folding iPhones and iOS before 27.1 stay flat with no hinge. Android uses Jetpack WindowManager; web uses the Device Posture API and viewport segments when the browser exposes them (hinge angle stays null on web).

Fold API (full types below): isDeviceFoldable(), getFoldState(), getHingeAngle(), getReservedRegions(), getBarPlacement(), setVerticalBarBehavior(), getSizeClass(), listeners foldStateChange, hingeAngleChange, sizeClassChange.

Documentation

The most complete doc is available here: https://capgo.app/docs/plugins/screen-orientation/

Compatibility

Plugin versionCapacitor compatibilityMaintained
v8.*.*v8.*.*✅
v7.*.*v7.*.*On demand
v6.*.*v6.*.*❌
v5.*.*v5.*.*❌

Note: The major version of this plugin follows the major version of Capacitor. Use the version that matches your Capacitor installation (e.g., plugin v8 for Capacitor 8). Only the latest major version is actively maintained.

Install

You can use our AI-Assisted Setup to install the plugin. Add the Capgo skills to your AI tool using the following command:

npx skills add https://github.com/cap-go/capacitor-skills --skill capacitor-plugins

Then use the following prompt:

Use the `capacitor-plugins` skill from `cap-go/capacitor-skills` to install the `@capgo/capacitor-screen-orientation` plugin in my project.

If you prefer Manual Setup, install the plugin by running the following commands and follow the platform-specific instructions below:

npm install @capgo/capacitor-screen-orientation
npx cap sync

iOS Configuration

To detect physical device orientation using motion sensors on iOS, you need to add the Motion Usage Description to your Info.plist:

<key>NSMotionUsageDescription</key>
<string>This app uses motion sensors to detect the true physical orientation of your device.</string>

Locking the screen orientation only applies to the Capacitor view controller by default. To also apply the lock to presented view controllers (for example, ones shown by the Browser plugin), add this to your app's AppDelegate.swift:

func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
  return UIInterfaceOrientationMask(rawValue: (self.window!.rootViewController as! CAPBridgeViewController).supportedInterfaceOrientations.rawValue)
}

Make sure UISupportedInterfaceOrientations in Info.plist includes every orientation you want to lock to (for example landscape left/right when locking to landscape).

Usage

import { ScreenOrientation } from '@capgo/capacitor-screen-orientation';

// Get current orientation
const result = await ScreenOrientation.orientation();
console.log('Current orientation:', result.type);

// Lock to landscape
await ScreenOrientation.lock({ orientation: 'landscape' });

// Lock UI orientation and track physical orientation via motion sensors
// Note: UI will still respect user's orientation lock, but you'll get physical orientation events
await ScreenOrientation.lock({
  orientation: 'portrait',
  bypassOrientationLock: true
});

// Listen for orientation changes
const listener = await ScreenOrientation.addListener(
  'screenOrientationChange',
  (result) => {
    console.log('Orientation changed:', result.type);
  }
);

// Unlock orientation
await ScreenOrientation.unlock();

// Start motion-based tracking to detect physical device orientation
// This uses motion sensors to track how the device is actually held
await ScreenOrientation.startOrientationTracking({
  bypassOrientationLock: true
});

// Check if device orientation lock is enabled
// Compares physical device orientation (from sensors) with UI orientation (from system)
const lockStatus = await ScreenOrientation.isOrientationLocked();
if (lockStatus.locked) {
  console.log('Orientation lock is ON!');
  console.log('Physical device orientation:', lockStatus.physicalOrientation);
  console.log('UI orientation:', lockStatus.uiOrientation);
} else {
  console.log('Orientation lock is OFF or motion tracking not active');
}

// Stop motion-based tracking
await ScreenOrientation.stopOrientationTracking();

// Remove listener
await listener.remove();

// iPhone Duo and Android foldables. Flat on phones that do not fold.
const { posture, activeDisplay } = await ScreenOrientation.getFoldState();
const { angle, status } = await ScreenOrientation.getHingeAngle();
const { verticalBarEdge, inset } = await ScreenOrientation.getBarPlacement();
const { widthClass } = await ScreenOrientation.getSizeClass();

API

Capacitor Screen Orientation Plugin interface.

Provides methods to detect and control screen orientation, with support for detecting true physical device orientation using motion sensors.

orientation()

orientation() => Promise<ScreenOrientationResult>

Get the current screen orientation.

Returns the current orientation of the device screen.

Returns: Promise<ScreenOrientationResult>

Since: 1.0.0


lock(...)

lock(options: OrientationLockOptions) => Promise<void>

Lock the screen orientation to a specific type.

Locks the screen to the specified orientation. On iOS, if bypassOrientationLock is true, it will also start tracking physical device orientation using motion sensors.

Note: The UI will still respect the user's orientation lock setting. Motion tracking allows you to detect how the device is physically held even when the UI doesn't rotate.

On iOS 15 there is no public API to force a rotation, so the lock restricts the allowed orientations and the UI rotates into them when the device orientation allows it. On iOS 16 and later the rotation is requested immediately.

ParamTypeDescription
optionsOrientationLockOptionsOptions for locking the orientation.

Since: 1.0.0


unlock()

unlock() => Promise<void>

Unlock the screen orientation.

Allows the screen to rotate freely based on device position. Also stops any motion-based orientation tracking if it was enabled.

Since: 1.0.0


startOrientationTracking(...)

startOrientationTracking(options?: StartOrientationTrackingOptions | undefined) => Promise<void>

Start tracking device orientation using motion sensors.

This method is useful when you want to track the device's physical orientation independently from the screen orientation lock. It uses Core Motion on iOS to detect orientation changes.

ParamTypeDescription
optionsStartOrientationTrackingOptionsOptions for starting orientation tracking.

Since: 1.0.0


stopOrientationTracking()

stopOrientationTracking() => Promise<void>

Stop tracking device orientation using motion sensors.

Stops the motion-based orientation tracking if it was started.

Since: 1.0.0


isOrientationLocked()

isOrientationLocked() => Promise<OrientationLockStatusResult>

Check if device orientation lock is currently enabled.

This method compares the physical device orientation (from motion sensors) with the UI orientation. If they differ, orientation lock is enabled.

Note: This requires motion tracking to be active via startOrientationTracking() or lock() with bypassOrientationLock: true. Works on both iOS (Core Motion) and Android (Accelerometer).

Returns: Promise<OrientationLockStatusResult>

Since: 1.0.0


isDeviceFoldable()

isDeviceFoldable() => Promise<DeviceFoldableResult>

Whether this device folds, and whether it can stand half-open like a laptop.

On web, both flags are false when the browser lacks fold APIs or the current reading shows no fold (devicePosture.type is continuous with a single viewport segment). foldable becomes true when posture is folded or the viewport splits into two segments. On web, supportsTabletop reflects the current reading (for example, false in a book pose) rather than permanent device capability.

On Android, both flags are false on phones that do not fold. On iOS, both are false except on iPhone Duo (iOS 27.1 or later).

Returns: Promise<DeviceFoldableResult>

Since: 8.2.0


getFoldState()

getFoldState() => Promise<FoldState>

Read the current fold.

Resolves to a flat state when the device has no fold. On web, uses navigator.devicePosture and window.viewport.segments when the browser provides them.

Returns: Promise<FoldState>

Since: 8.2.0


getHingeAngle()

getHingeAngle() => Promise<HingeAngleResult>

Read the hinge angle in degrees.

0 is closed and 180 is flat. angle is null without a hinge sensor.

Returns: Promise<HingeAngleResult>

Since: 8.2.0


getReservedRegions()

getReservedRegions() => Promise<{ regions: ReservedRegion[]; }>

Read the fold and anything covering the screen.

iPhone Duo reports the fold, the vertical status bar area, and the under-display camera. Resolves to an empty list on Android, web, and iOS before 27.1.

Returns: Promise<{ regions: ReservedRegion[]; }>

Since: 8.2.0


getBarPlacement()

getBarPlacement() => Promise<BarPlacement>

Read where iPhone Duo puts native tab bars and toolbars.

verticalBarEdge is null when bars stay horizontal, and always on Android and web.

Returns: Promise<BarPlacement>

Since: 8.2.0


setVerticalBarBehavior(...)

setVerticalBarBehavior(options: { behavior: 'automatic' | 'disabled'; }) => Promise<{ applied: boolean; }>

Choose whether iPhone Duo may move this app's bars to the side.

Resolves to { applied: false } unless the app's bridge view controller opts in. Android and web always resolve to { applied: false }.

ParamTypeDescription
options{ behavior: 'automatic' | 'disabled'; }automatic lets the system move bars. disabled keeps them horizontal.

Returns: Promise<{ applied: boolean; }>

Since: 8.2.0


getSizeClass()

getSizeClass() => Promise<SizeClass>

Read the window size classes.

Returns: Promise<SizeClass>

Since: 8.2.0


addListener('screenOrientationChange', ...)

addListener(eventName: 'screenOrientationChange', listenerFunc: (result: ScreenOrientationResult) => void) => Promise<PluginListenerHandle>
ParamType
eventName'screenOrientationChange'
listenerFunc(result: ScreenOrientationResult) => void

Returns: Promise<PluginListenerHandle>


addListener('foldStateChange', ...)

addListener(eventName: 'foldStateChange', listenerFunc: (state: FoldState) => void) => Promise<PluginListenerHandle>

Listen for fold changes.

On a foldable this also fires when the device rotates, because the hinge bounds rotate with the window.

ParamTypeDescription
eventName'foldStateChange'The event name. Must be 'foldStateChange'.
listenerFunc(state: FoldState) => voidCallback invoked with the new fold state.

Returns: Promise<PluginListenerHandle>

Since: 8.2.0


addListener('hingeAngleChange', ...)

addListener(eventName: 'hingeAngleChange', listenerFunc: (event: HingeAngleResult) => void) => Promise<PluginListenerHandle>

Listen for hinge angle changes.

On Android the hinge sensor runs only while at least one listener is registered. On iOS this fires on iPhone Duo (iOS 27.1 or later). On web, hinge angle stays null; use foldStateChange for posture updates from the Device Posture API.

ParamTypeDescription
eventName'hingeAngleChange'The event name. Must be 'hingeAngleChange'.
listenerFunc(event: HingeAngleResult) => voidCallback invoked with the angle in degrees.

Returns: Promise<PluginListenerHandle>

Since: 8.2.0


addListener('sizeClassChange', ...)

addListener(eventName: 'sizeClassChange', listenerFunc: (sizeClass: SizeClass) => void) => Promise<PluginListenerHandle>

Listen for size class changes, such as unfolding, rotating, or resizing.

ParamTypeDescription
eventName'sizeClassChange'The event name. Must be 'sizeClassChange'.
listenerFunc(sizeClass: SizeClass) => voidCallback invoked with the new size class.

Returns: Promise<PluginListenerHandle>

Since: 8.2.0


removeAllListeners()

removeAllListeners() => Promise<void>

Remove all listeners for this plugin.

Removes all registered event listeners.

Since: 1.0.0


getPluginVersion()

getPluginVersion() => Promise<{ version: string; }>

Get the native plugin version.

Returns the current version of the native plugin implementation.

Returns: Promise<{ version: string; }>

Since: 1.0.0


Interfaces

ScreenOrientationResult

Result returned by the orientation() method.

PropTypeDescriptionSince
typeOrientationTypeThe current orientation type.1.0.0

OrientationLockOptions

Options for locking the screen orientation.

PropTypeDescriptionDefaultSince
orientationOrientationLockTypeThe orientation type to lock to.1.0.0
bypassOrientationLockbooleanWhether to track physical device orientation using motion sensors. When true, uses device motion sensors to detect the true physical orientation of the device, even when the device orientation lock is enabled. Important: This does NOT bypass the UI orientation lock. The screen will still respect the user's orientation lock setting. This option only affects orientation detection/tracking - you'll receive orientation change events based on how the device is physically held, but the UI will not rotate if orientation lock is enabled. Supported on iOS (Core Motion) and Android (Accelerometer).false1.0.0

StartOrientationTrackingOptions

Options for starting orientation tracking using motion sensors.

PropTypeDescriptionDefaultSince
bypassOrientationLockbooleanWhether to track physical device orientation using motion sensors. When true, uses device motion sensors to detect the true physical orientation of the device, even when the device orientation lock is enabled. Important: This does NOT bypass the UI orientation lock. This only enables detection of the physical orientation. Supported on iOS (Core Motion) and Android (Accelerometer).false1.0.0

OrientationLockStatusResult

Result returned by the isOrientationLocked() method.

PropTypeDescriptionSince
lockedbooleanWhether the device orientation lock is currently enabled. This is determined by comparing the physical device orientation (from motion sensors) with the UI orientation. If they differ, orientation lock is enabled. Available on iOS (Core Motion) and Android (Accelerometer) when motion tracking is active.1.0.0
physicalOrientationOrientationTypeThe physical orientation of the device from motion sensors. Available when motion tracking is active (iOS and Android).1.0.0
uiOrientationOrientationTypeThe current UI orientation reported by the system.1.0.0

DeviceFoldableResult

Whether this device can fold.

PropTypeDescriptionSince
foldablebooleanWhether the device has a fold.8.2.0
supportsTabletopbooleanWhether it can stand half-open like a laptop.8.2.0

FoldState

Current fold of the window.

Phones that do not fold, and iOS before 27.1, resolve to a flat state. iPhone Duo reports book, tabletop, or flat, and which display is in front.

PropTypeDescriptionSince
stateFoldStateValuePosture of the fold.8.2.0
isSeparatingbooleanWhether the fold splits the web view into two areas.8.2.0
postureFoldPostureHow the device is held.8.2.0
hingeOrientationHingeOrientationDirection of the hinge. Omitted when there is no fold.8.2.0
hingeBoundsFoldBoundsPosition of the fold in CSS pixels. Omitted when there is no fold.8.2.0
occludedBoundsFoldBoundsArea the hinge covers. Present when the hinge has a physical gap.8.2.0
activeDisplay'inner' | 'outer'Which display is showing the app on iPhone Duo. Omitted on Android, web, and iOS before 27.1.8.2.0
hingeMargins{ top: number; right: number; bottom: number; left: number; }Space the system keeps clear around the fold, in CSS pixels. iPhone Duo reports 20 on each side of a vertical fold.8.2.0
cameraBoundsFoldBounds[]Areas covering the display, such as the iPhone Duo camera. Omitted when there are none.8.2.0

FoldBounds

A rectangle in CSS pixels, relative to the web view.

PropType
xnumber
ynumber
widthnumber
heightnumber

HingeAngleResult

Angle between the two halves of a foldable, in degrees.

0 is closed and 180 is flat. angle is null when the device has no hinge sensor.

PropTypeDescriptionSince
anglenumber | nullHinge angle in degrees, or null when no sensor is available.8.2.0
status'closed' | 'partiallyOpen' | 'fullyOpen' | nullHow far open iPhone Duo is, as the system sees it. null on Android and web.8.2.0

ReservedRegion

A region the system reserves on iPhone Duo.

division is the fold. occlusion is something covering the display, such as the camera.

PropTypeDescriptionSince
kind'division' | 'occlusion'What the region is.8.2.0
isActivebooleanWhether the region applies right now. An inactive division is a flat fold.8.2.0
xnumberLeft edge, in CSS pixels.8.2.0
ynumberTop edge, in CSS pixels.8.2.0
widthnumberWidth in CSS pixels.8.2.0
heightnumberHeight in CSS pixels.8.2.0
margins{ top: number; right: number; bottom: number; left: number; }Space to keep clear around the region, in CSS pixels.8.2.0

BarPlacement

Where iPhone Duo places native bars.

PropTypeDescriptionSince
verticalBarEdge'leading' | 'trailing' | nullThe edge the system moves tab bars and toolbars to. null when they stay horizontal.8.2.0
insetnumberHow much room the vertical bar takes, in points. 0 when bars stay horizontal.8.2.0

SizeClass

Window size classes.

horizontal and vertical follow Apple's compact/regular split. On Android and web, regular starts at 600 CSS pixels wide and 480 tall. widthClass and heightClass follow Material window size classes.

PropTypeDescriptionSince
horizontal'compact' | 'regular'Width size class. compact on a phone, regular on the inner display of a foldable, a tablet, or a window at least 600 CSS pixels wide.8.2.0
vertical'compact' | 'regular'Height size class. regular starts at 480 CSS pixels.8.2.0
widthClass'compact' | 'medium' | 'expanded' | 'large' | 'extraLarge'Material window width class.8.2.0
heightClass'compact' | 'medium' | 'expanded'Material window height class.8.2.0

PluginListenerHandle

PropType
remove() => Promise<void>

Type Aliases

OrientationType

Orientation type that describes the orientation state of the device.

'portrait-primary' | 'portrait-secondary' | 'landscape-primary' | 'landscape-secondary'

OrientationLockType

Orientation lock type that can be used to lock the device orientation.

'any' | 'natural' | 'landscape' | 'portrait' | 'portrait-primary' | 'portrait-secondary' | 'landscape-primary' | 'landscape-secondary'

FoldStateValue

How open a foldable is.

closed is reserved. A device shut onto its cover display reports flat.

'flat' | 'half-opened'

FoldPosture

How a half-open foldable is held.

tabletop is a horizontal hinge, like a laptop. book is a vertical hinge.

'flat' | 'tabletop' | 'book'

HingeOrientation

Direction of the hinge relative to the window.

'horizontal' | 'vertical'

Foldable support adapted from erkamyaman/capacitor-foldable (MIT, Copyright (c) Erkam Yaman).

版本与发布记录

@capgo/capacitor-screen-orientation 共发布 29 个版本,首次发布于 2025/11/28;过去 12 个月发布了 29 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
8.4.3latest2026/10/1525 天前
8.4.22026/10/1327 天前
8.4.12026/10/091 个月前
8.4.02026/10/091 个月前
8.3.12026/10/081 个月前
8.3.02026/10/031 个月前

关于 @capgo/capacitor-screen-orientation 的常见问题

@capgo/capacitor-screen-orientation 是什么?

Screen orientation plugin with support for bypassing orientation lock

如何安装 @capgo/capacitor-screen-orientation?

在项目目录运行 npm install @capgo/capacitor-screen-orientation,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:@capacitor/core(>=8.0.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@capgo/capacitor-screen-orientation 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@capgo/capacitor-screen-orientation 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@capgo/capacitor-screen-orientation 可以商用吗?

@capgo/capacitor-screen-orientation 使用 MPL-2.0 许可。弱 Copyleft:可以商用,也可以和闭源代码一起使用;但如果分发时修改了 MPL 授权的文件,这些文件的修改需以 MPL 开源。以上为概括,不构成法律意见,请以许可原文为准。

@capgo/capacitor-screen-orientation 的下载量有多少?

根据 npm 官方下载统计,@capgo/capacitor-screen-orientation 在 2026/10/09 – 2026/11/07 这 30 天内被下载 43,411 次,日均约 1,447 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@capgo/capacitor-screen-orientation 还在维护吗?

最新版本 8.4.3 发布于 2026/10/15(25 天前);至今共发布 29 个版本,其中过去 12 个月发布了 29 个;首次发布于 2025/11/28。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。