-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathImageWithAnnotationsGrid.jsx
More file actions
94 lines (90 loc) · 3.35 KB
/
ImageWithAnnotationsGrid.jsx
File metadata and controls
94 lines (90 loc) · 3.35 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
import React from 'react';
// import './ImageWithAnnotationsGrid.css'; // Using a new CSS file for clarity
// Data remains the same - coordinates are relative to the overlay/image area
const defaultFeatures = [
{
id: 'seat-height',
line: { top: '12%', left: '15%', width: '10%', height: '1px' },
text: { top: '8%', left: '15%', content: 'SEAT HEIGHT\nLorem ipsum dolor sit amet...' }
},
{
id: 'seat-comfort',
line: { top: '12%', left: '45%', width: '10%', height: '1px' },
text: { top: '8%', left: '45%', content: 'SEAT COMFORT\nFind the soft supportive fit...' }
},
{
id: 'seat-depth',
line: { top: '12%', left: '75%', width: '10%', height: '1px' },
text: { top: '8%', left: '75%', content: 'SEAT DEPTH\nClassic 303C medium seat depth...' }
},
{
id: 'bottom-left',
line: { top: '82%', left: '26.5%', width: '2px', height: '8%', origin: '0 0' },
text: { top: '86%', left: '27.5%', content: 'Lower Feature\nDetails here...' }
},
{
id: 'arm-rest',
line: { top: '20%', left: '80.5%', width: '2px', height: '20%', origin: '0 0' },
text: { top: '20%', left: '81.5%', content: 'Armrest Detail\nFSC Certified Wood...' }
},
{
id: 'ky-rest',
line: { top: '20%', left: '8%', width: '2px', height: '33%', origin: '0 0' },
text: { top: '20%', left: '9%', content: 'Armrest Detail\nFSC Certified Wood...' }
}
// top: 20%;
// left: 8%;
// width: 2px;
// height: 33%;
// /* transform: rotate(-90deg); */
// transform-origin: 0px 0px;
];
const ImageWithAnnotationsGrid = ({ imageUrl, features = defaultFeatures, altText = "Annotated product" }) => {
return (
// The container is now a Grid parent
<div className="annotation-container-grid">
{/* Layer 1: Background Image - Placed in the grid */}
<img
src={imageUrl}
alt={altText}
className="background-image-grid"
/>
{/* Layer 2 & 3: Annotations Overlay - Placed in the SAME grid cell */}
{/* This overlay needs position: relative for its children */}
<div className="annotations-overlay-grid">
{features.map(feature => (
// Annotations (lines/text) are still absolutely positioned *within* the overlay
<React.Fragment key={feature.id}>
{/* Layer 2: Line */}
<div
className="annotation-line" // Re-use previous style name or create new
style={{
top: feature.line.top,
left: feature.line.left,
width: feature.line.width,
height: feature.line.height,
transform: feature.line.rotate ? `rotate(${feature.line.rotate}deg)` : 'none',
transformOrigin: feature.line.origin
}}
/>
{/* Layer 3: Text */}
<div
className="annotation-text" // Re-use previous style name or create new
style={{
top: feature.text.top,
left: feature.text.left,
}}
>
{feature.text.content.split('\n').map((line, index) => (
<span key={index} className={index === 0 ? 'title' : 'description'}>
{line}
</span>
))}
</div>
</React.Fragment>
))}
</div>
</div>
);
};
export default ImageWithAnnotationsGrid;