跳到主要内容
哒哒星球DADA PLANET

Skill · 已公开版本

spatial-computing-ui · 空间计算风格界面实现指南

提供玻璃拟态、Z轴层级与悬停高亮等空间计算UI风格的多端实现示例,覆盖CSS、SwiftUI、Flutter、React Native与Compose,并说明仅为视觉模拟。

先看看示例

作者提供的示例,实际效果取决于你的输入和使用工具。

输入

为我的React Native应用设计一个Vision Pro风格的浮动玻璃窗口,带悬停高亮按钮。

输出

预期交付:对应平台的样式代码示例与设计原则说明,含玻璃材质、圆角、阴影与交互提示。(编辑说明,非实际运行结果)

方法说明

---
name: spatial-computing-ui
description: Web and App implementation guide for Spatial Computing UI. Trigger when user wants floating elements, environmental awareness, and Apple Vision Pro style.
date_added: "2026-06-17"
risk: safe
source: self
source_type: self
---

# Spatial Computing UI

> "A step beyond Spatial Design. Fully 3D windows floating in augmented reality."


## When to Use
Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly.

## Core Principles
1. **Z-Space Hierarchy**: Not just drop shadows, but actual 3D distance. Modals float 10px *in front of* the main window.
2. **Gaze-Based Interaction Cues**: Elements highlight vividly when hovered, anticipating eye-tracking or precise pointer control.
3. **Glass and Light**: Windows are thick sheets of frosted glass that bend light and cast soft shadows onto the physical environment.

## Visual DNA
- **Colors**: Relies entirely on the background environment. Uses purely translucent whites (`rgba(255,255,255,0.x)`) and blacks. 
- **Typography**: `SF Pro`. Heavy use of varied font weights (Regular, Semibold, Bold) to create hierarchy.
- **Shapes**: High border radii (`24px`-`32px`). Everything is a rounded rectangle or a perfect circle.

## Web Implementation
- Best emulated using CSS 3D transforms to simulate the user's perspective.
- **CSS Example**:
```css
body {
  /* Simulate the physical room */
  background: url('living-room.jpg') center/cover;
  perspective: 1200px;
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
}

.spatial-window {
  width: 800px;
  height: 600px;
  border-radius: 32px;
  
  /* The Glass Material */
  background: rgba(255, 255, 255, 0.15);
  backdrop-filter: blur(50px) saturate(200%);
  -webkit-backdrop-filter: blur(50px) saturate(200%);
  
  /* Specular Highlights */
  border: 1px solid rgba(255, 255, 255, 0.4);
  box-shadow: 
    inset 0 1px 2px rgba(255, 255, 255, 0.8),
    0 30px 60px rgba(0, 0, 0, 0.3);
    
  /* 3D Positioning */
  transform: translateZ(-100px);
  transform-style: preserve-3d;
}

.spatial-modal {
  /* Floating in front of the main window */
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%) translateZ(50px);
  
  background: rgba(255, 255, 255, 0.6); /* More opaque */
  backdrop-filter: blur(30px);
  border-radius: 24px;
  padding: 30px;
  box-shadow: 0 20px 40px rgba(0, 0, 0, 0.2);
}

.spatial-btn {
  /* Gaze/Hover interaction */
  background: rgba(0,0,0,0.05);
  transition: all 0.2s cubic-bezier(0.2, 0.8, 0.2, 1);
}
.spatial-btn:hover {
  background: rgba(255,255,255,0.4);
  transform: translateZ(10px) scale(1.05);
  box-shadow: 0 10px 20px rgba(0,0,0,0.1);
}
```

## App Implementation

### SwiftUI (visionOS Native / iOS emulation)
```swift
struct SpatialComputingView: View {
    var body: some View {
        ZStack {
            // Simulated room environment
            Image("living-room")
                .resizable()
                .aspectRatio(contentMode: .fill)
                .ignoresSafeArea()
            
            // Spatial Window
            VStack(spacing: 24) {
                Text("Spatial Window")
                    .font(.title).fontWeight(.bold)
                    .foregroundColor(.white)
                
                // Gaze-reactive button
                Button(action: {}) {
                    Text("Focus Me")
                        .fontWeight(.semibold)
                        .foregroundColor(.white)
                        .padding(.horizontal, 32)
                        .padding(.vertical, 16)
                        // .hoverEffect() is magic on visionOS/iPadOS
                        // .hoverEffect(.highlight)
                }
                .background(Color.black.opacity(0.2))
                .clipShape(Capsule())
            }
            .padding(60)
            // The magic glass material
            .background(.ultraThinMaterial)
            .cornerRadius(32)
            // Specular edge highlight
            .overlay(
                RoundedRectangle(cornerRadius: 32)
                    .stroke(Color.white.opacity(0.4), lineWidth: 1)
            )
            // Environmental shadow
            .shadow(color: .black.opacity(0.3), radius: 40, y: 30)
            
            // Z-Space Modal simulation (if on iOS)
            // On visionOS, this would be a separate window volume
            Text("Floating Modal")
                .foregroundColor(.white)
                .padding(30)
                .background(.thinMaterial)
                .cornerRadius(24)
                .shadow(color: .black.opacity(0.4), radius: 30, y: 20)
                .offset(x: 100, y: 100)
        }
    }
}
```
- Use `.ultraThinMaterial` for the base windows and `.thinMaterial` for floating popovers so they feel more opaque as they get closer to the eye.
- Use `.hoverEffect()` extensively if targeting iPadOS or visionOS.

### Flutter
```dart
import 'dart:ui';

class SpatialComputingScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        fit: StackFit.expand,
        children: [
          // Simulated Environment
          Image.asset('assets/living-room.jpg', fit: BoxFit.cover),
          
          Center(
            child: ClipRRect(
              borderRadius: BorderRadius.circular(32),
              child: BackdropFilter(
                filter: ImageFilter.blur(sigmaX: 40.0, sigmaY: 40.0), // Heavy blur
                child: Container(
                  width: 600, height: 400,
                  decoration: BoxDecoration(
                    color: Colors.white.withOpacity(0.15), // Glass tint
                    borderRadius: BorderRadius.circular(32),
                    border: Border.all(color: Colors.white.withOpacity(0.4), width: 1), // Specular highlight
                    // Note: BoxShadow won't render under BackdropFilter nicely unless wrapped in a separate PhysicalModel
                  ),
                  child: Center(
                    child: Column(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: [
                        const Text('Spatial Window', style: TextStyle(color: Colors.white, fontSize: 32, fontWeight: FontWeight.bold)),
                        const SizedBox(height: 32),
                        // Simulated Gaze Button
                        InkWell(
                          onTap: () {},
                          borderRadius: BorderRadius.circular(50),
                          hoverColor: Colors.white.withOpacity(0.4), // Pointer hover; does not add gaze tracking
                          child: Container(
                            padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 16),
                            decoration: BoxDecoration(color: Colors.black.withOpacity(0.2), borderRadius: BorderRadius.circular(50)),
                            child: const Text('Focus Me', style: TextStyle(color: Colors.white, fontSize: 18)),
                          ),
                        )
                      ],
                    ),
                  ),
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }
}
```
- You must wrap `BackdropFilter` inside a `ClipRRect` to give the blurred glass rounded corners.
- `hoverColor` on `InkWell` simulates the gaze-highlighting.

### React Native
```jsx
// REQUIRES: @react-native-community/blur
import { BlurView } from '@react-native-community/blur';

const SpatialComputingScreen = () => {
  return (
    <ImageBackground source={{uri: 'room_bg'}} style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
      
      {/* Spatial Window */}
      <View style={{
        width: '90%', height: 400,
        shadowColor: '#000', shadowOffset: { width: 0, height: 30 },
        shadowOpacity: 0.3, shadowRadius: 40, elevation: 20
      }}>
        <BlurView
          style={{ flex: 1, borderRadius: 32, borderWidth: 1, borderColor: 'rgba(255,255,255,0.4)', padding: 40, justifyContent: 'center', alignItems: 'center' }}
          blurType="light"
          blurAmount={30}
          reducedTransparencyFallbackColor="gray"
        >
          <Text style={{ color: '#FFF', fontSize: 32, fontWeight: 'bold', marginBottom: 32 }}>
            Spatial Window
          </Text>

          {/* Touchable simulating Gaze */}
          <TouchableOpacity style={{
            backgroundColor: 'rgba(0,0,0,0.2)', paddingVertical: 16, paddingHorizontal: 32, borderRadius: 50
          }}>
            <Text style={{ color: '#FFF', fontSize: 18, fontWeight: '600' }}>Focus Me</Text>
          </TouchableOpacity>
        </BlurView>
      </View>

    </ImageBackground>
  );
};
```
- The example uses @react-native-community/blur; other native integrations are possible. Choose a supported version and test the target platform.
- Apply shadows to a wrapper `View`, and put the `BlurView` inside it with `borderRadius` and `borderWidth`.

### Jetpack Compose
```kotlin
@Composable
fun SpatialComputingScreen() {
    Box(modifier = Modifier.fillMaxSize()) {
        // Environment
        Image(painterResource(R.drawable.living_room), contentDescription = null, contentScale = ContentScale.Crop, modifier = Modifier.fillMaxSize())
        
        // Spatial Window
        Box(
            modifier = Modifier
                .align(Alignment.Center)
                .size(600.dp, 400.dp)
                // Note: Native Android background blur requires Android 12+ (RenderEffect)
                .graphicsLayer {
                    // No renderEffect here: it would blur this panel and its text, not the room.
                    clip = true
                    shape = RoundedCornerShape(32.dp)
                }
                .background(Color.White.copy(alpha = 0.15f))
                .border(1.dp, Color.White.copy(alpha = 0.4f), RoundedCornerShape(32.dp))
                .padding(40.dp),
            contentAlignment = Alignment.Center
        ) {
            Column(horizontalAlignment = Alignment.CenterHorizontally) {
                Text("Spatial Window", color = Color.White, fontSize = 32.sp, fontWeight = FontWeight.Bold)
                Spacer(Modifier.height(32.dp))
                
                // Button
                Box(
                    modifier = Modifier
                        .background(Color.Black.copy(alpha = 0.2f), CircleShape)
                        .clickable { }
                        .padding(horizontal = 32.dp, vertical = 16.dp)
                ) {
                    Text("Focus Me", color = Color.White, fontSize = 18.sp, fontWeight = FontWeight.SemiBold)
                }
            }
        }
    }
}
```
- RenderEffect on this panel filters its own content, not the room behind it. This snippet is a tinted fallback; a backdrop effect requires separately captured background content or a compatible backdrop library.
- The `border` modifier applies the bright specular rim-light crucial to glass effects.

## Do's and Don'ts
- **DO**: Create a distinct visual pop (size increase and shadow depth increase) on hover/focus to simulate the gaze-tracking interaction of Spatial Computing.
- **DON'T**: Use flat, opaque colors for the main windows. They must be glass.

## Limitations
- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review.
- Ensure appropriate contrast ratios and responsive behaviors are verified separately.

These flat-screen examples simulate spatial styling; they do not implement eye tracking, AR anchoring, environmental lighting or 3D windows. Keep content contrast stable over every background and use actual labeled controls for interaction. Native visionOS windows should use the platform window/material APIs.