|
5 | 5 | <meta charset="utf-8" /> |
6 | 6 | <meta http-equiv="X-UA-Compatible" content="IE=edge" /> |
7 | 7 | <meta name="viewport" content="width=device-width,initial-scale=1.0" /> |
| 8 | + <meta name="description" content="dwg-viewer examples: online DWG/DXF viewer, PDF viewer, CAD JSON viewer, and CAD comparison in your browser. Upload local files or browse sample projects." /> |
| 9 | + <meta name="robots" content="index,follow" /> |
| 10 | + <link rel="canonical" href="https://dwg.thingraph.site/" /> |
| 11 | + <meta property="og:title" content="DWG Viewer Examples" /> |
| 12 | + <meta property="og:description" content="Online DWG/DXF viewer, PDF viewer, CAD JSON viewer, and CAD comparison examples." /> |
| 13 | + <meta property="og:url" content="https://dwg.thingraph.site/" /> |
| 14 | + <meta property="og:type" content="website" /> |
| 15 | + <meta name="twitter:card" content="summary" /> |
8 | 16 | <link rel="icon" href="./favicon.ico" /> |
9 | 17 | <link rel="stylesheet" type="text/css" href="./global.css" /> |
10 | | - <title>x-viewer samples</title> |
| 18 | + <title>DWG Viewer Examples | x-viewer</title> |
11 | 19 | <style type="text/css"> |
| 20 | + :root { |
| 21 | + --bg: #f8f9fb; |
| 22 | + --text: #1f2937; |
| 23 | + --muted: #6b7280; |
| 24 | + --card: #ffffff; |
| 25 | + --border: rgba(109, 76, 65, .25); |
| 26 | + --accent: #3a6aca; |
| 27 | + --accent-2: #6d4c41; |
| 28 | + --shadow: 0 10px 30px rgba(17, 24, 39, 0.08); |
| 29 | + } |
12 | 30 | body { |
13 | 31 | font-family: 'Segoe UI', 'Roboto', 'Arial', sans-serif; |
14 | | - background: #f8f9fb; |
| 32 | + background: var(--bg); |
15 | 33 | margin: 0; |
16 | | - padding: 0 0 0 0; |
17 | | - color: #222; |
| 34 | + padding: 0; |
| 35 | + color: var(--text); |
18 | 36 | font-size: 16px; |
19 | 37 | } |
| 38 | + .container { |
| 39 | + max-width: 1150px; |
| 40 | + margin: 0 auto; |
| 41 | + padding: 0 18px; |
| 42 | + } |
| 43 | + .skip-link { |
| 44 | + position: absolute; |
| 45 | + left: -9999px; |
| 46 | + top: 10px; |
| 47 | + background: #fff; |
| 48 | + padding: 10px 12px; |
| 49 | + border: 1px solid var(--border); |
| 50 | + border-radius: 10px; |
| 51 | + z-index: 9999; |
| 52 | + } |
| 53 | + .skip-link:focus { |
| 54 | + left: 18px; |
| 55 | + } |
20 | 56 | .header { |
21 | | - text-align: center; |
22 | | - font-size: 2.2rem; |
23 | | - font-weight: 700; |
24 | | - margin-top: 0; |
25 | | - padding: 36px 0 18px 0; |
| 57 | + padding: 34px 0 26px 0; |
26 | 58 | background: linear-gradient(90deg, #f6f6f6 60%, #e9e4e0 100%); |
27 | 59 | border-bottom: 1.5px solid #ebeef5; |
28 | 60 | box-shadow: 0 2px 8px 0 rgba(109, 76, 65, 0.04); |
29 | | - letter-spacing: 1px; |
| 61 | + } |
| 62 | + .hero-inner { |
| 63 | + display: flex; |
| 64 | + flex-direction: column; |
| 65 | + gap: 12px; |
| 66 | + } |
| 67 | + .hero-title { |
| 68 | + font-size: 2.0rem; |
| 69 | + font-weight: 800; |
| 70 | + margin: 0; |
| 71 | + letter-spacing: 0.2px; |
| 72 | + } |
| 73 | + .hero-subtitle { |
| 74 | + margin: 0; |
| 75 | + color: var(--muted); |
| 76 | + line-height: 1.5; |
| 77 | + max-width: 70ch; |
| 78 | + } |
| 79 | + .hero-actions { |
| 80 | + display: flex; |
| 81 | + gap: 10px; |
| 82 | + flex-wrap: wrap; |
| 83 | + margin-top: 4px; |
| 84 | + } |
| 85 | + .btn { |
| 86 | + display: inline-flex; |
| 87 | + align-items: center; |
| 88 | + justify-content: center; |
| 89 | + padding: 10px 14px; |
| 90 | + border-radius: 12px; |
| 91 | + text-decoration: none; |
| 92 | + font-weight: 700; |
| 93 | + border: 1px solid var(--border); |
| 94 | + color: #fff; |
| 95 | + background: var(--accent); |
| 96 | + box-shadow: 0 8px 18px rgba(58, 106, 202, 0.18); |
| 97 | + transition: transform .12s ease, box-shadow .12s ease, background .12s ease; |
| 98 | + } |
| 99 | + .btn:focus-visible { |
| 100 | + outline: 3px solid rgba(58, 106, 202, 0.35); |
| 101 | + outline-offset: 3px; |
| 102 | + } |
| 103 | + .btn:hover { |
| 104 | + transform: translateY(-1px); |
| 105 | + box-shadow: 0 12px 26px rgba(58, 106, 202, 0.24); |
| 106 | + background: var(--accent-2); |
| 107 | + } |
| 108 | + .btn-ghost { |
| 109 | + background: transparent; |
| 110 | + color: var(--accent); |
| 111 | + box-shadow: none; |
| 112 | + } |
| 113 | + .btn-ghost:hover { |
| 114 | + background: rgba(58, 106, 202, 0.06); |
| 115 | + box-shadow: none; |
| 116 | + } |
| 117 | + /* Hide CTA buttons from users, but keep links in DOM for crawlers. */ |
| 118 | + #hero-actions { |
| 119 | + position: absolute; |
| 120 | + left: -9999px; |
| 121 | + top: 0; |
| 122 | + width: 1px; |
| 123 | + height: 1px; |
| 124 | + overflow: hidden; |
30 | 125 | } |
31 | 126 | .project-cards { |
32 | 127 | display: grid; |
33 | | - grid-template-columns: repeat(auto-fit, 250px); |
34 | | - gap: 10px; |
35 | | - padding: 10px; |
36 | | - box-shadow: 0 2px 12px 0 rgba(0, 0, 0, .1); |
37 | | - justify-content: flex-start; |
| 128 | + grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); |
| 129 | + gap: 14px; |
| 130 | + padding: 0; |
| 131 | + margin-top: 14px; |
38 | 132 | } |
39 | 133 | .project-card { |
40 | 134 | width: 100%; |
41 | | - display: inline-block; |
| 135 | + display: block; |
42 | 136 | } |
43 | 137 | .project-card-main { |
44 | 138 | display: flex; |
45 | 139 | flex-direction: column; |
46 | 140 | overflow: hidden; |
47 | 141 | height: 100%; |
48 | 142 | min-width: 150px; |
49 | | - background-color: #fff; |
50 | | - color: #303133; |
51 | | - margin-bottom: 10px; |
52 | | - border: 1px solid rgba(109, 76, 65, .5); |
53 | | - margin: 1px; |
54 | | - transition: all .1s; |
55 | | - opacity: 0.95; |
56 | | - background-color: #f6f6f6; |
| 143 | + background-color: var(--card); |
| 144 | + color: #1f2937; |
| 145 | + border-radius: 16px; |
| 146 | + border: 1px solid var(--border); |
| 147 | + transition: transform .12s ease, box-shadow .12s ease, border-color .12s ease; |
| 148 | + box-shadow: 0 8px 22px rgba(17, 24, 39, 0.06); |
| 149 | + } |
| 150 | + .project-card-link { |
| 151 | + display: flex; |
| 152 | + flex-direction: column; |
| 153 | + height: 100%; |
| 154 | + text-decoration: none; |
| 155 | + color: inherit; |
| 156 | + cursor: pointer; |
| 157 | + outline: none; |
57 | 158 | } |
58 | 159 | .project-card-main:hover { |
59 | 160 | cursor: pointer; |
60 | | - border: 1px solid rgba(109, 76, 65, 1.0); |
61 | | - opacity: 1.0; |
62 | | - box-shadow: 3px 5px 10px rgba(109, 76, 65, 0.5); |
| 161 | + transform: translateY(-2px); |
| 162 | + border-color: rgba(109, 76, 65, 0.45); |
| 163 | + box-shadow: 0 16px 30px rgba(17, 24, 39, 0.12); |
| 164 | + } |
| 165 | + .project-card-link:focus-visible .project-card-main { |
| 166 | + border-color: rgba(58, 106, 202, 0.7); |
| 167 | + box-shadow: 0 0 0 4px rgba(58, 106, 202, 0.2); |
63 | 168 | } |
64 | 169 | .project-card-thumbnail { |
65 | | - height: 150px; |
| 170 | + height: 160px; |
66 | 171 | flex-shrink: 0; |
67 | 172 | background-repeat: no-repeat; |
68 | 173 | background-position: 50%; |
69 | 174 | background-size: cover; |
70 | | - box-shadow: 0 0 1px rgba(0, 0, 0, .3); |
| 175 | + box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .05); |
71 | 176 | transition: transform 0.5s cubic-bezier(0.4,0,0.2,1); |
72 | 177 | } |
73 | 178 | .project-card-main:hover .project-card-thumbnail { |
|
77 | 182 | display: flex; |
78 | 183 | align-items: center; |
79 | 184 | justify-content: center; |
80 | | - min-height: 40px; |
81 | | - background: #f6f6f6; |
| 185 | + min-height: 46px; |
| 186 | + background: linear-gradient(180deg, rgba(248, 249, 251, 0.2), rgba(248, 249, 251, 1)); |
82 | 187 | text-align: center; |
83 | 188 | font-size: 14px; |
84 | 189 | padding: 2px; |
85 | | - line-height: 35px; |
| 190 | + line-height: 1.2; |
86 | 191 | white-space: nowrap; |
87 | 192 | overflow: hidden; |
88 | 193 | text-overflow: ellipsis; |
|
97 | 202 | text-overflow: ellipsis; |
98 | 203 | white-space: nowrap; |
99 | 204 | } |
| 205 | + .seo-links { |
| 206 | + padding: 14px 14px 8px 14px; |
| 207 | + border: 1px solid var(--border); |
| 208 | + border-radius: 16px; |
| 209 | + background: rgba(255, 255, 255, 0.75); |
| 210 | + color: #333; |
| 211 | + font-size: 14px; |
| 212 | + } |
| 213 | + /* Keep links in DOM for crawlers, but hide them from users. */ |
| 214 | + #seo-links { |
| 215 | + position: absolute; |
| 216 | + left: -9999px; |
| 217 | + top: 0; |
| 218 | + width: 1px; |
| 219 | + height: 1px; |
| 220 | + overflow: hidden; |
| 221 | + } |
| 222 | + .seo-links ul { |
| 223 | + list-style: none; |
| 224 | + padding: 0; |
| 225 | + margin: 10px 0 0 0; |
| 226 | + display: flex; |
| 227 | + flex-wrap: wrap; |
| 228 | + gap: 10px 12px; |
| 229 | + } |
| 230 | + .seo-links li { |
| 231 | + margin: 0; |
| 232 | + } |
| 233 | + .seo-links a { |
| 234 | + color: #3a6aca; |
| 235 | + text-decoration: none; |
| 236 | + font-weight: 500; |
| 237 | + } |
| 238 | + .seo-links a:hover { |
| 239 | + color: #6d4c41; |
| 240 | + text-decoration: underline; |
| 241 | + } |
100 | 242 | .footer { |
101 | 243 | width: 100%; |
102 | 244 | background: #f6f6f6; |
|
133 | 275 | </head> |
134 | 276 |
|
135 | 277 | <body> |
136 | | - <div class="header">dwg-viewer examples</div> |
137 | | - <div class="project-cards-container"></div> |
138 | | - <!-- |
139 | | - <div><a href="./upload_dxf.html">Upload local dxf/pdf</a></div> |
140 | | - <br /> |
141 | | - <div><a href="./dxf_0.html">Dxf example 0</a></div> |
142 | | - <div><a href="./dxf_1.html">Dxf example 1</a></div> |
143 | | - <div><a href="./dxf_2.html">Dxf example 2</a></div> |
144 | | - <div><a href="./dxf_compare_1_viewport.html">Dxf example 3 (compare with 1 viewport)</a></div> |
145 | | - <div><a href="./dxf_compare_2_viewports.html">Dxf example 4 (compare with 2 viewports)</a></div> |
146 | | - <div><a href="./pdf_1.html">Pdf example 1</a></div> |
147 | | - <br /> |
148 | | - --> |
| 278 | + <a class="skip-link" href="#content">Skip to content</a> |
| 279 | + |
| 280 | + <header class="header"> |
| 281 | + <div class="container hero-inner"> |
| 282 | + <h1 class="hero-title">DWG Viewer Examples</h1> |
| 283 | + <p class="hero-subtitle"> |
| 284 | + Online DWG/DXF/PDF viewer and CAD tools powered by <a href="https://www.npmjs.com/package/@x-viewer/core" target="_blank" rel="noopener">x-viewer</a>. Upload your local files, |
| 285 | + or explore sample projects in your browser. |
| 286 | + </p> |
| 287 | + <div id="hero-actions" class="hero-actions" aria-hidden="true"> |
| 288 | + <a class="btn" href="./upload_dxf.html">Upload local CAD</a> |
| 289 | + <a class="btn btn-ghost" href="./dwg_0.html">Try sample viewer</a> |
| 290 | + </div> |
| 291 | + </div> |
| 292 | + </header> |
| 293 | + |
| 294 | + <main id="content" class="container"> |
| 295 | + <section aria-label="Example quick links"> |
| 296 | + <div id="seo-links" class="seo-links" aria-hidden="true"> |
| 297 | + <div style="font-weight: 800; margin-bottom: 2px;">Browse examples</div> |
| 298 | + <ul> |
| 299 | + <li><a href="./upload_dxf.html">Upload local CAD (DWG/DXF/PDF)</a></li> |
| 300 | + <li><a href="./dwg_json_viewer.html">DWG/DXF JSON structure viewer</a></li> |
| 301 | + <li><a href="./cad_compare_2_files.html">Compare 2 CAD files</a></li> |
| 302 | + <li><a href="./dwg_0.html">DWG example 0</a></li> |
| 303 | + <li><a href="./dwg_1.html">DWG example 1</a></li> |
| 304 | + <li><a href="./dwg_2.html">DWG example 2</a></li> |
| 305 | + <li><a href="./dxf_0.html">DXF example 0</a></li> |
| 306 | + <li><a href="./dxf_1.html">DXF example 1</a></li> |
| 307 | + <li><a href="./dxf_2.html">DXF example 2</a></li> |
| 308 | + <li><a href="./dxf_compare_1_viewport.html">DXF compare (1 viewport)</a></li> |
| 309 | + <li><a href="./dxf_compare_2_viewports.html">DXF compare (2 viewports)</a></li> |
| 310 | + <li><a href="./pdf_1.html">PDF viewer</a></li> |
| 311 | + </ul> |
| 312 | + </div> |
| 313 | + </section> |
| 314 | + |
| 315 | + <div class="project-cards-container"></div> |
| 316 | + </main> |
| 317 | + |
| 318 | + <script type="application/ld+json"> |
| 319 | + { |
| 320 | + "@context": "https://schema.org", |
| 321 | + "@type": "ItemList", |
| 322 | + "name": "dwg-viewer examples", |
| 323 | + "itemListElement": [ |
| 324 | + { "@type": "ListItem", "position": 1, "url": "https://dwg.thingraph.site/upload_dxf.html" }, |
| 325 | + { "@type": "ListItem", "position": 2, "url": "https://dwg.thingraph.site/dwg_json_viewer.html" }, |
| 326 | + { "@type": "ListItem", "position": 3, "url": "https://dwg.thingraph.site/cad_compare_2_files.html" }, |
| 327 | + { "@type": "ListItem", "position": 4, "url": "https://dwg.thingraph.site/dwg_0.html" }, |
| 328 | + { "@type": "ListItem", "position": 5, "url": "https://dwg.thingraph.site/dwg_1.html" }, |
| 329 | + { "@type": "ListItem", "position": 6, "url": "https://dwg.thingraph.site/dwg_2.html" }, |
| 330 | + { "@type": "ListItem", "position": 7, "url": "https://dwg.thingraph.site/dxf_0.html" }, |
| 331 | + { "@type": "ListItem", "position": 8, "url": "https://dwg.thingraph.site/dxf_1.html" }, |
| 332 | + { "@type": "ListItem", "position": 9, "url": "https://dwg.thingraph.site/dxf_2.html" }, |
| 333 | + { "@type": "ListItem", "position": 10, "url": "https://dwg.thingraph.site/dxf_compare_1_viewport.html" }, |
| 334 | + { "@type": "ListItem", "position": 11, "url": "https://dwg.thingraph.site/dxf_compare_2_viewports.html" }, |
| 335 | + { "@type": "ListItem", "position": 12, "url": "https://dwg.thingraph.site/pdf_1.html" } |
| 336 | + ] |
| 337 | + } |
| 338 | + </script> |
149 | 339 | <footer class="footer"> |
150 | 340 | <div class="footer-content"> |
151 | 341 | Contact: <a href="mailto:thingraph@outlook.com">thingraph@outlook.com</a> |
|
186 | 376 | projectCard.classList.add('project-card'); |
187 | 377 | projectCard.innerHTML = ` |
188 | 378 | <div class="project-card-main"> |
189 | | - <div class="project-card-thumbnail" style="background-image: url('${project.thumbnail}');"></div> |
190 | | - <div class="project-card-desc"> |
191 | | - <span class="project-card-desc-text" title="${project.name}">${project.name}</span> |
192 | | - </div> |
| 379 | + <a class="project-card-link" href="${project.link}" aria-label="${project.name}"> |
| 380 | + <div class="project-card-thumbnail" style="background-image: url('${project.thumbnail}');" aria-hidden="true"></div> |
| 381 | + <div class="project-card-desc"> |
| 382 | + <span class="project-card-desc-text" title="${project.name}">${project.name}</span> |
| 383 | + </div> |
| 384 | + </a> |
193 | 385 | </div> |
194 | 386 | `; |
195 | 387 | projectCards.appendChild(projectCard); |
196 | | - projectCard.onclick = () => { |
197 | | - window.location.href = project.link; |
198 | | - }; |
199 | 388 | }); |
200 | 389 | projectCardsContainer.appendChild(projectCards); |
201 | 390 | }; |
|
0 commit comments