Library-Thumbnails: Auto-Capture + Base64-Preview in der UI
Beim Hinzufuegen oder Importieren eines Library-Items wird automatisch ein PNG-Thumbnail vom Item generiert (Top-View, 128x128) und in library/previews/<id>.png abgelegt. Frontend rendert die Previews als Base64-Data-URIs (sicher gegen WebKit-file://-Restriktionen). library.py: - _previews_dir(): legt previews/-Folder an - _preview_rel_for(asset_rel): predictable PNG-Pfad pro Item - _capture_thumbnail_of_objects(): hided andere Objekte temporaer, switcht auf Top-Parallel, ZoomBoundingBox, CaptureToBitmap → PNG, restored Viewport + Hidden-State - read_preview_data_uri(): liest PNG + encoded als data:image/png;base64 - Hook in convert_to_3dm_via_import (vor Cleanup) + save_selection_to_asset rhinopanel.py: - _enrich_library_items_with_previews(): haengt previewDataUri an jedes Item das ein preview-Feld hat - Initial-Params + _send_library + ElementeBridge._cmd_list_library liefern angereicherte Items - _add_library_file + _save_selection_as_library setzen preview-Pfad im Item wenn Thumbnail-Datei existiert Frontend: - SymbolPicker.ItemPreview: rendert <div backgroundImage> mit Base64-URI wenn vorhanden, sonst Icon-Fallback - ProjectSettingsDialog Symbole-Tab: List-Row + Detail-Identity zeigen Thumbnail (32px in Liste, 56px im Detail), Icon nur als Fallback Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -6,17 +6,29 @@ import { BarToggle, BarButton, BAR_H } from './BarControls'
|
||||
Grid. Klick auf Item → onPick(id). Schliesst via onClose. */
|
||||
|
||||
function ItemPreview({ item }) {
|
||||
// Vorschau: type-spezifisches Icon im Center auf bg-input.
|
||||
// Spaeter: PNG-Thumbnail aus library/previews/.
|
||||
// Thumbnail wenn vorhanden, sonst type-spezifisches Icon
|
||||
if (item.previewDataUri) {
|
||||
return (
|
||||
<div style={{
|
||||
height: 80,
|
||||
background: 'var(--bg-input)',
|
||||
borderBottom: '1px solid var(--border-light)',
|
||||
backgroundImage: `url("${item.previewDataUri}")`,
|
||||
backgroundSize: 'contain',
|
||||
backgroundPosition: 'center',
|
||||
backgroundRepeat: 'no-repeat',
|
||||
}} />
|
||||
)
|
||||
}
|
||||
const iconName = item.type === 'symbol' ? 'navigation' : 'forest'
|
||||
return (
|
||||
<div style={{
|
||||
height: 56,
|
||||
height: 80,
|
||||
background: 'var(--bg-input)',
|
||||
borderBottom: '1px solid var(--border-light)',
|
||||
display: 'flex', alignItems: 'center', justifyContent: 'center',
|
||||
}}>
|
||||
<Icon name={iconName} size={24}
|
||||
<Icon name={iconName} size={28}
|
||||
style={{ color: 'var(--text-muted)' }} />
|
||||
</div>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user