您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527
  1. {% extends "main.html" %}
  2. {% block libs %}
  3. {{ super() }}
  4. {% endblock %}
  5. {% block scripts %}
  6. {{ super() }}
  7. <script>
  8. (function() {
  9. window.addEventListener('load', function() {
  10. setupDialogPolyfill();
  11. setupReveal();
  12. if(location.hash == '#download')
  13. document.querySelector('#bundle-dialog').showModal();
  14. });
  15. function setupDialogPolyfill()
  16. {
  17. if(typeof HTMLDialogElement !== 'undefined')
  18. return;
  19. const link = document.createElement('link');
  20. link.rel = 'stylesheet';
  21. link.href = 'style/dialog-polyfill.css';
  22. document.head.prepend(link);
  23. const script = document.createElement('script');
  24. script.onload = registerDialogs;
  25. script.src = 'js/dialog-polyfill.js';
  26. document.head.append(script);
  27. function registerDialogs()
  28. {
  29. document.querySelectorAll('dialog').forEach(function(dialog) {
  30. dialogPolyfill.registerDialog(dialog);
  31. dialog.classList.add('fixed');
  32. });
  33. }
  34. }
  35. function setupReveal()
  36. {
  37. if(typeof IntersectionObserver === 'undefined')
  38. return;
  39. const observer = new IntersectionObserver(function(entries) {
  40. for(const entry of entries) {
  41. if(entry.intersectionRatio >= 0.125)
  42. entry.target.classList.remove('unrevealed');
  43. /*else if(entry.intersectionRatio == 0.0)
  44. entry.target.classList.add('unrevealed');*/
  45. }
  46. }, { threshold: [0, 0.125] });
  47. document.querySelectorAll('.reveal').forEach(function(reveal) {
  48. reveal.classList.add('unrevealed');
  49. observer.observe(reveal);
  50. });
  51. }
  52. })();
  53. </script>
  54. {% endblock %}
  55. {% block styles %}
  56. {{ super() }}
  57. <style>
  58. :root {
  59. --max-width: 42rem;
  60. --border-radius: 22px;
  61. --hpad: 1rem;
  62. --highlighted: #ffd500;
  63. }
  64. body {
  65. color: var(--md-default-fg-color--light);
  66. background-color: var(--md-default-bg-color);
  67. }
  68. .md-main__inner {
  69. max-width: 100% !important;
  70. margin-top: 0 !important;
  71. }
  72. .md-content__inner {
  73. margin: 0 !important;
  74. padding: 0 !important;
  75. }
  76. .md-content__inner::before {
  77. height: 0 !important;
  78. }
  79. .md-footer {
  80. color: var(--md-footer-fg-color);
  81. text-align: center;
  82. padding: 0 var(--hpad);
  83. }
  84. .md-footer .md-copyright {
  85. max-width: var(--max-width);
  86. margin-left: auto;
  87. margin-right: auto;
  88. }
  89. .md-footer a {
  90. color: var(--md-footer-fg-color--light);
  91. }
  92. /*.md-typeset h1 {
  93. font-weight: 400;
  94. }*/
  95. .md-copyright {
  96. color: var(--md-footer-fg-color--light);
  97. }
  98. #title {
  99. text-align: center;
  100. padding: 1.0rem var(--hpad) 0.5rem var(--hpad);
  101. background-image: linear-gradient(180deg,rgba(255, 255, 255, 0.2) 0%, rgba(255, 255, 255, 1) 100%), url('img/enchanted-sky.webp');
  102. background-size: cover;
  103. background-position: center;
  104. }
  105. #title h1 {
  106. margin: 0;
  107. font-size: 3.0rem;
  108. font-weight: bold;
  109. color: #ffc;
  110. text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);
  111. }
  112. #title h2 {
  113. margin: 0.5rem 0 0 0;
  114. font-size: 1.35rem;
  115. font-weight: bold;
  116. color: #ffc;
  117. text-shadow: 1px 1px 4px rgba(0, 0, 0, 0.5);
  118. }
  119. #title video {
  120. width: 100%;
  121. max-width: var(--max-width);
  122. border-radius: var(--border-radius);
  123. margin: 1rem auto;
  124. }
  125. #topics {
  126. max-width: var(--max-width);
  127. margin-left: auto;
  128. margin-right: auto;
  129. padding: 0 var(--hpad);
  130. text-align: center;
  131. }
  132. #topics article {
  133. margin: 2rem 0;
  134. padding: 1.2rem;
  135. border-radius: var(--border-radius);
  136. background-image: linear-gradient(0deg, white 0%, lemonchiffon 100%);
  137. }
  138. #topics article:first-child {
  139. margin-top: 0.5rem;
  140. }
  141. #topics article h1 {
  142. margin-bottom: 1.0rem;
  143. }
  144. #topics article a.md-button {
  145. margin-top: 1.0rem;
  146. }
  147. #topics article p {
  148. margin: 0;
  149. }
  150. #topics article img {
  151. width: 100%;
  152. height: auto;
  153. border-radius: 16px;
  154. margin-top: 1.0rem;
  155. }
  156. #topics article ul {
  157. list-style: none;
  158. display: flex;
  159. margin: 0;
  160. }
  161. #topics article ul li {
  162. min-width: 33.33%;
  163. max-width: 50%;
  164. display: flex;
  165. align-items: center;
  166. margin: 0;
  167. }
  168. #topics article ul li img {
  169. border-radius: 0;
  170. }
  171. #download {
  172. background-image: linear-gradient(0deg,rgba(255, 255, 255, 0.2) 0%, rgba(255, 255, 255, 1) 100%), url('img/enchanted-sky.webp');
  173. background-size: cover;
  174. background-position: right bottom;
  175. /*min-height: 342px;*/
  176. }
  177. #download article {
  178. max-width: var(--max-width);
  179. margin-left: auto;
  180. margin-right: auto;
  181. padding: 2rem var(--hpad);
  182. font-size: 1.1em;
  183. text-align: center;
  184. color: #555;
  185. }
  186. #download article h1 {
  187. margin: 0;
  188. }
  189. #download article p {
  190. margin: 1.5rem 0;
  191. font-size: 1.05em;
  192. }
  193. #download article footer {
  194. display: flex;
  195. flex-wrap: wrap;
  196. justify-content: space-evenly;
  197. }
  198. #download article footer > * {
  199. margin: 0.5rem 0;
  200. }
  201. dialog {
  202. /*background-color: var(--md-default-bg-color);*/
  203. background-color: whitesmoke;
  204. color: var(--md-default-fg-color--light);
  205. text-align: center;
  206. padding: 1.5rem;
  207. border: 0;
  208. border-radius: 24px;
  209. box-shadow: 10px 10px 10px rgba(0, 0, 0, 0.2);
  210. transition: opacity 0.5s ease;
  211. }
  212. dialog[open] {
  213. opacity: 1;
  214. }
  215. dialog:not([open]) {
  216. opacity: 0;
  217. pointer-events: none;
  218. }
  219. dialog::backdrop {
  220. backdrop-filter: blur(8px);
  221. transition: backdrop-filter 0.5s ease;
  222. }
  223. dialog h1 {
  224. margin: 1.0rem 0;
  225. font-size: 1.4rem;
  226. }
  227. dialog .close {
  228. position: absolute;
  229. top: 0.3rem;
  230. right: 0.8rem;
  231. font-size: 1.35rem;
  232. color: var(--md-default-fg-color--light);
  233. cursor: pointer;
  234. }
  235. html:has(dialog[open]) {
  236. overflow: hidden;
  237. }
  238. #bundle-dialog label {
  239. display: flex;
  240. align-items: center;
  241. text-align: left;
  242. margin-bottom: 1rem;
  243. }
  244. #bundle-dialog footer {
  245. margin-top: 1rem;
  246. }
  247. #bundle-dialog input[type="radio"] {
  248. position: absolute;
  249. opacity: 0;
  250. }
  251. #bundle-dialog button[type="submit"] {
  252. margin-top: 0.75rem;
  253. width: 100%;
  254. }
  255. #bundle-dialog label:hover {
  256. cursor: pointer;
  257. }
  258. .custom-radio {
  259. min-width: 24px;
  260. width: 24px;
  261. height: 24px;
  262. background-color: var(--md-primary-bg-color);
  263. border-radius: 50%;
  264. border: 2px solid var(--md-default-fg-color--light);
  265. margin-right: 0.75rem;
  266. }
  267. .custom-radio:hover, label:hover > .custom-radio {
  268. background-color: var(--md-default-bg-color--lighter);
  269. }
  270. .custom-radio:after {
  271. content: "";
  272. display: block;
  273. position: relative;
  274. top: 4px;
  275. left: 4px;
  276. width: 12px;
  277. height: 12px;
  278. border-radius: 50%;
  279. background: var(--md-primary-fg-color);
  280. visibility: hidden;
  281. }
  282. input[type="radio"]:checked ~ .custom-radio {
  283. border-color: var(--md-primary-fg-color);
  284. }
  285. input[type="radio"]:checked ~ .custom-radio:after {
  286. visibility: visible;
  287. }
  288. .reveal {
  289. opacity: 1;
  290. transition: transform 0.5s ease-out, opacity 0.5s ease-out;
  291. }
  292. .reveal.unrevealed {
  293. opacity: 0;
  294. transform: translateY(5rem);
  295. }
  296. @media screen and (min-width: 768px) {
  297. #title h1 { font-size: 4.0rem; }
  298. #title h2 { font-size: 1.6rem; }
  299. #topics { text-align: justify; }
  300. #topics > article img { margin-top: initial; }
  301. #topics > article { display: flex; flex-direction: row; justify-content: space-between; align-items: center; }
  302. #topics > article:nth-child(2n+1) > div:nth-child(2) { min-width: calc(var(--max-width) * 0.4); margin-left: 32px; }
  303. #topics > article:nth-child(2n) > div:nth-child(2) { min-width: calc(var(--max-width) * 0.4); margin-right: 32px; order: -1; }
  304. }
  305. @media screen and (min-width: 992px) {
  306. #topics { padding: 0; }
  307. #download article footer > * { margin: 0; }
  308. }
  309. </style>
  310. {% endblock %}
  311. {% block content %}
  312. <header id="title">
  313. <h1>encantar.js</h1>
  314. <h2>High performance Web AR framework &mdash; no app required!</h2>
  315. <video autoplay loop muted playsinline controls poster="img/aframe-cat.webp">
  316. <source src="img/aframe-cat.mp4" type="video/mp4" />
  317. <source src="img/aframe-cat.webm" type="video/webm" />
  318. </video>
  319. </header>
  320. <section id="topics">
  321. <article class="reveal">
  322. <div>
  323. <h1>AR for all devices</h1>
  324. <p>Create Augmented Reality experiences for iOS, Android and even Desktops! All devices are supported, including those without native capabilities for AR / WebXR. User experience is frictionless, with no need to download apps!</p>
  325. <a href="demos/hello-aframe/poster.html" target="_blank" class="md-button" id="try-demo" data-goatcounter-click>Try a demo</a>
  326. </div>
  327. <div>
  328. <img src="img/mage.gif" alt="A mage in Augmented Reality" loading="lazy">
  329. </div>
  330. </article>
  331. <article class="reveal">
  332. <div>
  333. <h1>Turbocharged performance</h1>
  334. <p>A modern web browser is all that is required for a high performance experience, thanks to a powerful combination of GPU acceleration, WebAssembly and mathemagical wizardry. The result? A smooth user experience!</p>
  335. <a href="demos/basketball/poster.html" target="_blank" class="md-button" id="play-game" data-goatcounter-click>Play a game</a>
  336. </div>
  337. <div>
  338. <img src="img/demo-basketball.gif" alt="Magic AR Basketball Game" loading="lazy">
  339. </div>
  340. </article>
  341. <article class="reveal">
  342. <div>
  343. <h1>Open Source AR</h1>
  344. <p>encantar.js is one of the few open source Augmented Reality frameworks in existence. Your WebAR content is not tied to any platform. Host it wherever you want: there is no vendor lock-in and no usage limit.</p>
  345. <a href="https://github.com/alemart/encantar-js" rel="external" target="_blank" class="md-button" id="browse-source" data-goatcounter-click>Browse the source</a>
  346. </div>
  347. <div>
  348. <ul>
  349. <li><img src="img/open-source.png" alt="Open Source" loading="lazy" style="margin:1.33rem"></li>
  350. <li><img src="img/lgpl.png" alt="GNU LGPL" loading="lazy"></li>
  351. </ul>
  352. </div>
  353. </article>
  354. <article class="reveal">
  355. <div>
  356. <h1>Easy to use and to deploy</h1>
  357. <p>encantar.js may be combined with A-Frame, babylon.js, three.js, or any 3D engine &ndash; you choose! Also, all processing is performed on the user's device. A static web page is all you need!</p>
  358. <a href="demos/" target="_blank" class="md-button" id="try-more-demos" data-goatcounter-click>See for yourself</a>
  359. </div>
  360. <div>
  361. <ul>
  362. <li><img src="img/logo-aframe.png" alt="A-Frame logo" loading="lazy"></li>
  363. <li><img src="img/logo-babylon.png" alt="babylon.js logo" loading="lazy"></li>
  364. <li><img src="img/logo-three.png" alt="three.js logo" loading="lazy"></li>
  365. </ul>
  366. </div>
  367. </article>
  368. <article class="reveal">
  369. <div>
  370. <h1>Enchanted Images</h1>
  371. <p>Bring images to life! Create enchanted posters, ads, books, murals and more with Image Tracking, also known as Marker Tracking or Natural Feature Tracking. Scan your own images to start the WebAR experience &ndash; all in the browser!</p>
  372. <a href="guidelines-for-images/" target="_blank" class="md-button" id="guidelines-for-images" data-goatcounter-click>View the Guidelines</a>
  373. </div>
  374. <div>
  375. <img src="img/demo-cat.gif" alt="A cat in Augmented Reality" loading="lazy">
  376. </div>
  377. </article>
  378. <article class="reveal">
  379. <div>
  380. <h1>Add-Ons</h1>
  381. <p>Add-Ons enrich the core of encantar.js with magical additional features, such as easy to use Buttons for triggering events, as well as a pre-built Video Player for enchanting posters, murals, business cards and more!</p>
  382. <a href="addons/" target="_blank" class="md-button" id="explore-addons" data-goatcounter-click>Explore the Add-Ons</a>
  383. </div>
  384. <div>
  385. <img src="img/video-player.gif" alt="Video player for web-based Augmented Reality" loading="lazy">
  386. </div>
  387. </article>
  388. <article class="reveal">
  389. <div>
  390. <h1>Documentation</h1>
  391. <p>Extensive documentation accompanies the software. While you can quickly get magic done just by modifying the demos, the API Spellbook provides magical formulae and a comprehensive view of the technical aspects of AR magic.</p>
  392. <a href="api/" target="_blank" class="md-button" id="open-api-reference" data-goatcounter-click>Explore the API</a>
  393. </div>
  394. <div>
  395. <img src="img/witch-coder.webp" alt="Cartoon" loading="lazy">
  396. </div>
  397. </article>
  398. </section>
  399. <section id="download">
  400. <article>
  401. <h1>Download</h1>
  402. <p>encantar.js is created independently by <a href="https://github.com/alemart" target="_blank" id="author-name" data-goatcounter-click>Alexandre Martins</a>. It's based on <a href="https://github.com/alemart/speedy-vision" target="_blank" rel="external" id="speedy-vision" data-goatcounter-click>speedy-vision</a>, an open source computer vision library created by the same author. Your support is much appreciated!</p>
  403. <footer>
  404. <button class="md-button md-button--primary" id="download-button" data-goatcounter-click onclick="document.getElementById('bundle-dialog').showModal()">Download encantar.js</button>
  405. <a href="https://github.com/sponsors/alemart" target="_blank" class="md-button" id="download-sponsor" data-goatcounter-click>Sponsor on GitHub</a>
  406. </footer>
  407. </article>
  408. </section>
  409. <dialog id="bundle-dialog">
  410. <h1>Select an option</h1>
  411. <form autocomplete="off" onsubmit="location.href = this.elements.bundle.value; return false">
  412. <label>
  413. <input type="radio" name="bundle" value="https://ko-fi.com/s/697a184728" checked data-goatcounter-click>
  414. <span class="custom-radio"></span>
  415. <div>
  416. <strong>encantar.js Full</strong><br>
  417. encantar.js with <a href="addons/" id="exclusive-addons" target="_blank" data-goatcounter-click>Add-Ons for rich AR experiences</a>
  418. </div>
  419. </label>
  420. <label>
  421. <input type="radio" name="bundle" value="https://ko-fi.com/s/a9b92194e0" data-goatcounter-click>
  422. <span class="custom-radio"></span>
  423. <div>
  424. <strong>encantar.js</strong><br>
  425. encantar.js with core features and demos
  426. </div>
  427. </label>
  428. <label>
  429. <input type="radio" name="bundle" value="https://github.com/alemart/encantar-js" data-goatcounter-click>
  430. <span class="custom-radio"></span>
  431. <div>
  432. <strong>Source Code</strong><br>
  433. for Augmented Reality and Computer Vision nerds
  434. </div>
  435. </label>
  436. <footer>
  437. <button type="submit" class="md-button md-button--primary" id="download-bundle" data-goatcounter-click>OK</button>
  438. </footer>
  439. </form>
  440. <button class="close" onclick="this.parentNode.close()">&times;</button>
  441. </dialog>
  442. <footer class="md-footer">
  443. <div class="md-copyright">
  444. encantar.js: GPU-accelerated Augmented Reality framework for the web. Copyright &copy; 2022 &ndash; present Alexandre Martins
  445. </div>
  446. </footer>
  447. {% endblock %}
  448. {% block announce %}{% endblock %}
  449. {% block header %}{% endblock %}
  450. {% block tabs %}{% endblock %}
  451. {% block site_nav %}{% endblock %}
  452. {% block footer %}{% endblock %}