Skip to content

Commit c4de2d9

Browse files
committed
feat: M3 design enhancements, SEO improvements, JS bug fixes
Website improvements inspired by m3.material.io: - Fix mouse tracking for CSS ripple effect (--mouse-x/--mouse-y) - Fix visibility change handler (pause gallery on tab hide) - Add keyboard accessibility to platform badges - M3 chip-style navigation for tabs - Gradient text and glass-morphism fallbacks - M3 focus-visible states for all interactive elements - Animated hero gradient background - Enhanced CTA buttons with M3 filled/tonal variants - Subtle dot pattern background for content area - Preload critical resources (fonts, scripts) - Add og:image dimensions and alt text - DNS prefetch for Google Tag Manager - Enhanced llms.txt with all 26+ node types and MCP setup - PWA manifest: add categories and IARC rating https://claude.ai/code/session_013iRhSyfUopvUfTTWzfarg7
1 parent 8ec29b5 commit c4de2d9

6 files changed

Lines changed: 439 additions & 22 deletions

File tree

assets/javascripts/m3-interactions.js

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,18 @@ document.addEventListener('DOMContentLoaded', () => {
115115
card.addEventListener('mouseleave', handleTiltLeave, { passive: true });
116116
});
117117

118+
// ---------------------------------------------------------------------------
119+
// 4b. Mouse tracking for CSS ripple effect (--mouse-x, --mouse-y)
120+
// ---------------------------------------------------------------------------
121+
const RIPPLE_SELECTORS = '.grid.cards > ul > li, .platform-card, .device-section--clickable, .industry-card';
122+
document.querySelectorAll(RIPPLE_SELECTORS).forEach((el) => {
123+
el.addEventListener('mousemove', (e) => {
124+
const rect = el.getBoundingClientRect();
125+
el.style.setProperty('--mouse-x', `${e.clientX - rect.left}px`);
126+
el.style.setProperty('--mouse-y', `${e.clientY - rect.top}px`);
127+
}, { passive: true });
128+
});
129+
118130
// ---------------------------------------------------------------------------
119131
// 5. Smooth scroll for anchor links
120132
// ---------------------------------------------------------------------------
@@ -165,6 +177,14 @@ document.addEventListener('DOMContentLoaded', () => {
165177
gallery.addEventListener('touchend', () => {
166178
autoScrollId = requestAnimationFrame(autoScroll);
167179
}, { passive: true });
180+
181+
document.addEventListener('visibilitychange', () => {
182+
if (document.hidden) {
183+
if (autoScrollId) { cancelAnimationFrame(autoScrollId); autoScrollId = null; }
184+
} else {
185+
if (!autoScrollId) { autoScrollId = requestAnimationFrame(autoScroll); }
186+
}
187+
}, { passive: true });
168188
}
169189

170190
// ---------------------------------------------------------------------------
@@ -220,7 +240,9 @@ document.addEventListener('DOMContentLoaded', () => {
220240
// ---------------------------------------------------------------------------
221241
document.querySelectorAll('.platform-badge').forEach((badge) => {
222242
badge.style.cursor = 'pointer';
223-
badge.addEventListener('click', () => {
243+
if (!badge.hasAttribute('tabindex')) badge.setAttribute('tabindex', '0');
244+
if (!badge.hasAttribute('role')) badge.setAttribute('role', 'button');
245+
const activateBadge = () => {
224246
const label = badge.textContent.trim().toLowerCase();
225247
const sections = document.querySelectorAll('.device-section');
226248
for (const section of sections) {
@@ -234,15 +256,14 @@ document.addEventListener('DOMContentLoaded', () => {
234256
}
235257
}
236258
if (sections.length) sections[0].scrollIntoView({ behavior: 'smooth', block: 'start' });
259+
};
260+
badge.addEventListener('click', activateBadge);
261+
badge.addEventListener('keydown', (e) => {
262+
if (e.key === 'Enter' || e.key === ' ') {
263+
e.preventDefault();
264+
activateBadge();
265+
}
237266
});
238267
});
239268

240-
// ---------------------------------------------------------------------------
241-
// 10. Performance — cleanup on page hide
242-
// ---------------------------------------------------------------------------
243-
document.addEventListener('visibilitychange', () => {
244-
if (document.hidden && gallery) {
245-
// Pause animations when tab is hidden
246-
}
247-
}, { passive: true });
248269
});

index.html

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818
<meta property="og:description" content="Build stunning 3D scenes and augmented reality experiences with Compose. 26+ node types, physics, dynamic sky, fog, reflections. Powered by Google Filament.">
1919
<meta property="og:site_name" content="SceneView">
2020
<meta property="og:locale" content="en_US">
21+
<meta property="og:image:width" content="1200">
22+
<meta property="og:image:height" content="630">
23+
<meta property="og:image:alt" content="SceneView - 3D & AR SDK for Android with Jetpack Compose">
2124

2225
<!-- Twitter Card -->
2326
<meta name="twitter:card" content="summary_large_image">
@@ -77,6 +80,11 @@
7780
<link rel="preconnect" href="https://fonts.googleapis.com">
7881
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Google+Sans+Display:wght@400;500;600;700&display=swap">
7982

83+
<!-- Preload critical resources -->
84+
<link rel="preload" href="https://fonts.googleapis.com/css2?family=Google+Sans+Display:wght@400;500;600;700&display=swap" as="style">
85+
<link rel="preload" href="assets/javascripts/m3-interactions.js" as="script">
86+
<link rel="dns-prefetch" href="https://www.googletagmanager.com">
87+
8088
<!-- Structured Data for SEO -->
8189
<script type="application/ld+json">
8290
{

llms-full.txt

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ fun MyARScreen() {
111111

112112
---
113113

114-
## All Node Types (22+)
114+
## All Node Types (26+)
115115

116116
### ModelNode — glTF/GLB Models
117117
```kotlin
@@ -180,10 +180,38 @@ HitResultNode(xPx = screenCenterX, yPx = screenCenterY) { SphereNode(radius = 0.
180180
AugmentedImageNode(augmentedImage = image) { ModelNode(...) }
181181
AugmentedFaceNode(augmentedFace = face, meshMaterialInstance = faceMaterial)
182182
CloudAnchorNode(anchor = localAnchor, onHosted = { cloudId, state -> })
183+
GeospatialNode(latitude = 37.7749, longitude = -122.4194, altitude = 0.0)
184+
DepthNode(depthTexture = depthImage)
185+
InstantPlacementNode(xPx = centerX, yPx = centerY, approximateDistanceMeters = 2.0f)
186+
ArrowNode(from = Position(0f), to = Position(1f, 0f, 0f), materialInstance = mat)
183187
```
184188

185189
---
186190

191+
## MCP Server Installation
192+
193+
Install the SceneView MCP server for AI-assisted development:
194+
195+
```bash
196+
npx -y @sceneview/mcp
197+
```
198+
199+
Add to your AI assistant's MCP configuration (Claude, Cursor, etc.):
200+
```json
201+
{
202+
"mcpServers": {
203+
"sceneview": {
204+
"command": "npx",
205+
"args": ["-y", "@sceneview/mcp"]
206+
}
207+
}
208+
}
209+
```
210+
211+
Available MCP tools: `get_sample`, `list_samples`, `get_setup`, `validate_code`, `get_migration_guide`, `get_node_reference`, `get_platform_roadmap`, `get_best_practices`, `get_ar_setup`
212+
213+
---
214+
187215
## Critical Threading Rules
188216

189217
1. All Filament JNI calls MUST run on main thread
@@ -213,6 +241,11 @@ val chrome = materialLoader.createColorInstance(Color.White, metallic = 1f, roug
213241
| Learning curve | Low | High | Very High | Very High | Medium |
214242
| AI tooling (MCP) | Yes | No | No | No | No |
215243
| Open source | Apache 2.0 | Proprietary | Proprietary | Apache 2.0 | Apache 2.0 |
244+
| Node types | 26+ | N/A | N/A | Manual | ~10 |
245+
| Physics | Built-in | Built-in | Built-in | None | None |
246+
| glTF support | Native | Plugin | Plugin | Manual | Limited |
247+
| Active maintenance | Yes (2026) | Yes | Yes | Yes | Dormant |
248+
| Android-first | Yes | No | No | Yes | Yes |
216249

217250
---
218251

llms.txt

Lines changed: 41 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ ARScene(
7979
}
8080
```
8181

82-
## Available Node Types
82+
## Available Node Types (26+)
8383

8484
| Node | Description |
8585
|------|-------------|
@@ -105,6 +105,33 @@ ARScene(
105105
| AugmentedImageNode | Real-world image detection |
106106
| AugmentedFaceNode | Face mesh tracking |
107107
| CloudAnchorNode | Persistent cross-device anchors |
108+
| GeospatialNode | ARCore Geospatial API anchors |
109+
| DepthNode | ARCore depth mesh rendering |
110+
| InstantPlacementNode | Instant AR placement without plane |
111+
| HitResultNode | AR hit-test result anchoring |
112+
| ArrowNode | Directional 3D arrows |
113+
114+
## MCP Server Installation
115+
116+
Install the SceneView MCP server for AI-assisted development with Claude, Cursor, or other AI coding assistants:
117+
118+
```bash
119+
npx -y @sceneview/mcp
120+
```
121+
122+
Or add to your AI assistant's MCP configuration:
123+
```json
124+
{
125+
"mcpServers": {
126+
"sceneview": {
127+
"command": "npx",
128+
"args": ["-y", "@sceneview/mcp"]
129+
}
130+
}
131+
}
132+
```
133+
134+
Available MCP tools: get_sample, list_samples, get_setup, validate_code, get_migration_guide, get_node_reference, get_platform_roadmap, get_best_practices, get_ar_setup
108135

109136
## Use Cases
110137

@@ -119,12 +146,16 @@ ARScene(
119146

120147
## Why SceneView over alternatives?
121148

122-
| Feature | SceneView | Unity | Unreal | Raw Filament |
123-
|---------|-----------|-------|--------|-------------|
124-
| Compose-native | Yes | No | No | No |
125-
| APK size | ~5MB | ~50MB | ~100MB | ~3MB |
126-
| Learning curve | Low | High | Very High | Very High |
127-
| AR support | Built-in | Plugin | Plugin | None |
128-
| Open source | Apache 2.0 | Proprietary | Proprietary | Apache 2.0 |
129-
| Android-first | Yes | No | No | Yes |
130-
| AI-assisted | MCP server | No | No | No |
149+
| Feature | SceneView | Unity | Unreal | Raw Filament | Rajawali |
150+
|---------|-----------|-------|--------|-------------|----------|
151+
| Compose-native | Yes | No | No | No | No |
152+
| APK size | ~5MB | ~50MB | ~100MB | ~3MB | ~2MB |
153+
| Learning curve | Low | High | Very High | Very High | Medium |
154+
| AR support | Built-in | Plugin | Plugin | None | None |
155+
| Open source | Apache 2.0 | Proprietary | Proprietary | Apache 2.0 | Apache 2.0 |
156+
| Android-first | Yes | No | No | Yes | Yes |
157+
| AI-assisted (MCP) | Yes | No | No | No | No |
158+
| Node types | 26+ | N/A | N/A | Manual | ~10 |
159+
| Physics | Built-in | Built-in | Built-in | None | None |
160+
| glTF support | Native | Plugin | Plugin | Manual | Limited |
161+
| Active maintenance | Yes (2026) | Yes | Yes | Yes | Dormant |

manifest.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "SceneView — 3D & AR SDK for Android",
33
"short_name": "SceneView",
4-
"description": "The #1 open-source 3D & AR SDK for Android. Compose-native scenes powered by Google Filament and ARCore. 22+ node types, physics, AR, and AI-assisted development.",
4+
"description": "The #1 open-source 3D & AR SDK for Android. Compose-native scenes powered by Google Filament and ARCore. 26+ node types, physics, AR, and AI-assisted development.",
55
"start_url": "/",
66
"scope": "/",
77
"id": "/",
@@ -10,7 +10,8 @@
1010
"background_color": "#FEF7FF",
1111
"theme_color": "#6750A4",
1212
"orientation": "any",
13-
"categories": ["developer tools", "education", "productivity", "utilities"],
13+
"categories": ["developer-tools", "3d", "augmented-reality", "education", "productivity"],
14+
"iarc_rating_id": "e84b072d-71b3-4d3e-86ae-31a8ce4e53b7",
1415
"icons": [
1516
{
1617
"src": "/assets/images/favicon.png",

0 commit comments

Comments
 (0)