{"id":316,"date":"2020-06-02T12:26:04","date_gmt":"2020-06-02T11:26:04","guid":{"rendered":"https:\/\/csee.bangor.ac.uk\/?p=316"},"modified":"2020-06-02T12:26:04","modified_gmt":"2020-06-02T11:26:04","slug":"introduction-to-web-based-xr-part-i","status":"publish","type":"post","link":"https:\/\/csee.bangor.ac.uk\/projectrainbow\/2020\/06\/02\/introduction-to-web-based-xr-part-i\/","title":{"rendered":"Introduction to Web-based XR &#8211; Part I"},"content":{"rendered":"\n<!-- Custom post code :: Pure CSS Rainbows -->\n<!-- Adds prettyprint for code snippets -->\n\n  code { background-color: rgba(0,0,0,.05) !important; }\n  .linenums { color: #aaa; }\n  .linenums li {\n    list-style-type: decimal !important;\n    font-size: 12pt;\n    margin-top: 0px;\n  }\n  .linenums li:nth-child(even) { background: transparent !important; }\n  .wp-block-image { text-align: center !important; }\n  .wp-block-image img { display: inline; }\n\n\n\n\n\n<p>One of the easiest ways to create an enjoy Virtual Reality (VR) experiences is on the Web. And the most popular and versatile way to built VR experiences for the Web is to use A-Frame and <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/WebXR_Device_API\">WebXR<\/a>. <\/p>\n\n\n\n<p>We will look into how we can built a basic VR scene, that you can experience via your Web browser. We will then convert it in Augmented Reality (AR), in a future activity. <\/p>\n\n\n\n<p>These activities relate to our <strong>Web Technologies<\/strong> modules (<a href=\"https:\/\/www.bangor.ac.uk\/courses\/undergrad\/modules\/ICE-1411\">UG<\/a>\/<a href=\"https:\/\/www.bangor.ac.uk\/courses\/postgrad\/modules\/ICE-4111\">PG<\/a>), as well as our <strong>XReality<\/strong> module (<a href=\"https:\/\/www.bangor.ac.uk\/courses\/postgraduate-modules\/ICE-4711\">PG<\/a>).<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">WebXR<\/h3>\n\n\n\n<p>WebXR (and its predecessor WebVR, which is still around) is an open specification that makes it possible to experience VR in your browser. WebXR allows everyone to get into VR experiences, no matter what device they have. More importantly, WebVR\/WebXR is used by various popular frameworks that provide tools for building VR &#8211; and AR as we are going to see later &#8211; experiences. You can find some information on <a href=\"https:\/\/www.w3.org\/TR\/webxr\/\">WebXR<\/a> on the W3C website, as well as on Youtube <a href=\"https:\/\/www.youtube.com\/watch?v=MknaAnWBMCM\">here<\/a>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">A-Frame<\/h3>\n\n\n\n<p>A-Frame, an entity-component framework built upon the popular JavaScript 3D library, Three.js. A-Frame works along WebXR and together they are the easiest way to create Web-based VR. These experiences can be viewed with the most popular Head-Mounted Displays, such as the HTC Vive, Oculus Quest, Gear VR, as well as desktops and smartphones.<\/p>\n\n\n\n<p> A-Frame is at the centre of this activity which start in VR and continue in AR. Out goal is to create a simple VR scene, with a rainbow arch, as shown below<\/p>\n\n\n\n<p class=\"codepen\" data-height=\"265\" data-theme-id=\"light\" data-default-tab=\"result\" data-user=\"ritsosp\" data-slug-hash=\"oNjmqxw\" style=\"height: 265px;align-items: center;justify-content: center;border: 2px solid;margin: 1em 0;padding: 1em\" data-pen-title=\"Simple A-Frane Rainbow Scene\">\n  <span>See the Pen <a href=\"https:\/\/codepen.io\/ritsosp\/pen\/oNjmqxw\">\n  Simple A-Frane Rainbow Scene<\/a> by Panagiotis D. Ritsos (<a href=\"https:\/\/codepen.io\/ritsosp\">@ritsosp<\/a>)\n  on <a href=\"https:\/\/codepen.io\">CodePen<\/a>.<\/span>\n<\/p>\n\n\n\n\n<h3 class=\"wp-block-heading\">Putting things together<\/h3>\n\n\n\n<p>Lets look at how we can built this and review the code. We first need an HTML page, within which A-Frame will display our scene. <\/p>\n\n\n\n<p>Using your favourite editor (Visual Studio Code is a good choice) create a file, named <code>index.html<\/code>. Create a basic Web page by adding the code below:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted prettyprint linenums\">&lt;html&gt;\n  &lt;head&gt;\n    &lt;meta charset=\"utf-8\"&gt;\n    &lt;title&gt;VR Rainbow&lt;\/title&gt;\n    &lt;meta name=\"keywords\" content=\"HTML, CSS, JavaScript,  A-Frame\"&gt;\n    &lt;meta name=\"description\" content=\"A Rainbow in VR\"&gt;\n    &lt;script src=\"https:\/\/aframe.io\/releases\/1.0.4\/aframe.min.js\"&gt;&lt;\/script&gt;\n  &lt;\/head&gt;\n  &lt;body&gt;\n    &lt;a-scene id=\"rainbowScene\" background=\"color: #FAFAFA\"&gt;\n    &lt;\/a-scene&gt;\n  &lt;\/body&gt;\n&lt;\/html&gt;<\/pre>\n\n\n\n<p>Notice, it is a good practice to add a meaningful title and some appropriate meta tags. <\/p>\n\n\n\n<p>In addition, we need a link to the A-Frame library (line 7).  Lines 10 and 11 include the A-Frame element <code>&lt;a-scene&gt;<\/code> where our VR scene will display.<\/p>\n\n\n\n<p>To see your index.html file in a browser, it is advisable to run a local web server, and add it into that. <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Learn\/Common_questions\/set_up_a_local_testing_server\">Here<\/a> is one of the ways you can do that with Python. From this point onwards we assume you have the code in your editor, and the webpage in a browser. Refreshing the page will display any changes. You can also use the console to debug your JavaScript. Here is some info, <a href=\"https:\/\/developers.google.com\/web\/tools\/chrome-devtools\/javascript\">how to do that in Chrome<\/a>.<\/p>\n\n\n\n<p>Although it is a good idea to add any JavaScript to a separate file, in this case we will embed all our additional code in<code>index.html<\/code>. Within a <code>&lt;script&gt;<\/code> tag, right before the <code>&lt;\/body&gt;<\/code> tag, add the following code:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted prettyprint linenums\">var zStartPosition = 4;    \/\/ Sceme placement\nvar color = [\"red\", \"orange\", \"yellow\", \"green\", \"blue\", \"indigo\", \"violet\"];       \/\/ The Rainbow colours of the arch\nvar zIncrement = 0.5;      \/\/ The step where each Torus is placed\nvar arc = 180;             \/\/ The arc of the Tori\nvar radius = 4;            \/\/ The radius of the Tori\nvar radiusTubular = 0.125; \/\/ The radius of the Tori's 'tube' <\/pre>\n\n\n\n<p>These are variables we will be using to built our scene. Once the scene is completed, you can tweak these and change different parts of the scene. <\/p>\n\n\n\n<p>We will itterate over the color array and use it as a spine for our arch. For that we will use a For loop: <\/p>\n\n\n\n<pre class=\"wp-block-preformatted prettyprint linenums\">for (i = 0; i&lt;color.length; i++){\n}<\/pre>\n\n\n\n<p>Within the loop we will add statements to create each Torus, and add attributes to them, using our aforementioned variables.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted prettyprint linenums\">var torus = document.createElement(\"a-torus\"); \n torus.setAttribute(\"id\", \"torus_\" + i);\n torus.setAttribute(\"color\", color[i]);\n torus.setAttribute(\"arc\", arc); \n torus.setAttribute(\"radius\", radius);\n torus.setAttribute(\"radius-tubular\", radiusTubular);<\/pre>\n\n\n\n<p>The first line of this block creates the torus element in A-Frame (<code>&lt;a-torus&gt;<\/code>). We also use the name torus followed by an underscore and the index of the for loop, to create an <code>ID<\/code> for each torus. Finally, by using the for loop index, we iterate over our colour array. This way each of our colours are assigned to each torus sequentialy.<\/p>\n\n\n\n<p>However, when it comes to positioning each torus in our scene, we need to follow a different approach. Because rendering 3D graphics is costly (in processing power) placement of objects is done at a lower level. <code>A-Frame<\/code> recommends, for performance and ergonomics, to update position directly via the Three.js <code>Object3D.position<\/code> <a rel=\"noreferrer noopener\" href=\"https:\/\/threejs.org\/docs\/index.html#api\/math\/Vector3\" target=\"_blank\">Vector3<\/a>, instead of using  <code>.setAttribute<\/code>. <\/p>\n\n\n\n<p>We therefore place the first torus in the position (<code>x:0, y:0, z:-zStartPosition<\/code>). Then for each for loop iteration, <code>z<\/code> gets incremented.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted prettyprint linenums\">\/\/ Set position using Three.js for performance\ntorus.object3D.position.set(0, 0 , -zStartPosition);\nzStartPosition += zIncrement;\n\n\/\/ Place newly created torus in scene \ndocument.getElementsByTagName(\"a-scene\")[0].appendChild(torus);\n<\/pre>\n\n\n\n<p>This effectively pushed the position of subsequent tori further from the camera\/starting position.  A-Frame uses a right-handed coordinate system. With the default camera direction: positive X-axis extends&nbsp;<em>right<\/em>, positive Y-axis extends&nbsp;<em>up<\/em>, and the positive Z-axis extends&nbsp;<em>out<\/em>&nbsp;of the screen towards us (see below). In this case we are pushing the Tori towards the screen.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/cloud.githubusercontent.com\/assets\/674727\/20328731\/326137a8-ab49-11e6-9b76-4e3a65f333d9.jpg\" alt=\"righthandimage\" \/><figcaption><em>Image from <a href=\"https:\/\/aframe.io\/docs\/1.0.0\/guides\/building-a-basic-scene.html\">A-Frame<\/a> <\/em><\/figcaption><\/figure>\n\n\n\n<p>Then next line gets a reference to the <code>&lt;a-scene&gt;<\/code> element and appends each torus in sequence. Notice the statement refers to the <code>document<\/code> which is our webpage, and then refers to all the elements in the <code>document<\/code> that have a tag name <code>&lt;a-scene&gt;<\/code>. <\/p>\n\n\n\n<pre class=\"wp-block-preformatted prettyprint linenums\">\/\/ Place newly created torus in scene \ndocument.getElementsByTagName(\"a-scene\")[0].appendChild(torus);\n<\/pre>\n\n\n\n<p>As this in principle can be many, this statement returns an array, the elements of which are accessed via an index. <code>[0]<\/code> is the first element of the array and in this case the only instance of <code>&lt;a-scene&gt;<\/code>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Adding a ground plane<\/h3>\n\n\n\n<p>The next block works in a similar way to the tori placement, to place one plane as base in our scene. In this case we have hardcoded width, heigh, colour, shadows and rotation. Placement works in a similar way to the placement of the tori. Finally, we add the plane as a child element, in our <code>&lt;a-scene&gt;<\/code>.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted prettyprint linenums\">var ground = document.createElement(\"a-plane\");\nground.setAttribute(\"id\", \"ground\");\nground.setAttribute(\"width\", 9);\nground.setAttribute(\"height\", 5);\nground.setAttribute(\"color\", \"#7BC8A4\");\nground.setAttribute(\"shadow\", \"receive: true\");\nground.setAttribute(\"rotation\", \"-90, 0, 0\");\n\n\/\/ Set rotation using Three.js for performance\nground.object3D.position.set(0, 0 , -zStartPosition + 1.5);\nground.object3D.rotation.set.x = -90;\n\ndocument.getElementsByTagName(\"a-scene\")[0].appendChild(ground);\n<\/pre>\n\n\n\n<p>If all is well, refreshing the page should display the scene below (repeated for convenience). <\/p>\n\n\n\n<p class=\"codepen\" data-height=\"265\" data-theme-id=\"light\" data-default-tab=\"result\" data-user=\"ritsosp\" data-slug-hash=\"oNjmqxw\" style=\"height: 265px;align-items: center;justify-content: center;border: 2px solid;margin: 1em 0;padding: 1em\" data-pen-title=\"Simple A-Frane Rainbow Scene\">\n  <span>See the Pen <a href=\"https:\/\/codepen.io\/ritsosp\/pen\/oNjmqxw\">\n  Simple A-Frane Rainbow Scene<\/a> by Panagiotis D. Ritsos (<a href=\"https:\/\/codepen.io\/ritsosp\">@ritsosp<\/a>)\n  on <a href=\"https:\/\/codepen.io\">CodePen<\/a>.<\/span>\n<\/p>\n\n","protected":false},"excerpt":{"rendered":"<p>code { background-color: rgba(0,0,0,.05) !important; } .linenums { color: #aaa; } .linenums li { list-style-type: decimal !important; font-size: 12pt; margin-top: 0px; } .linenums li:nth-child(even) { background: transparent !important; } .wp-block-image { text-align: center !important; } .wp-block-image img { display: inline; } One of the easiest ways to create an enjoy Virtual Reality (VR) experiences is [&hellip;]<\/p>\n","protected":false},"author":5,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3,12,14,17,18],"tags":[70,74,130],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v22.9 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Introduction to Web-based XR - Part I - Project Rainbow<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/csee.bangor.ac.uk\/projectrainbow\/2020\/06\/02\/introduction-to-web-based-xr-part-i\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Introduction to Web-based XR - Part I - Project Rainbow\" \/>\n<meta property=\"og:description\" content=\"code { background-color: rgba(0,0,0,.05) !important; } .linenums { color: #aaa; } .linenums li { list-style-type: decimal !important; font-size: 12pt; margin-top: 0px; } .linenums li:nth-child(even) { background: transparent !important; } .wp-block-image { text-align: center !important; } .wp-block-image img { display: inline; } One of the easiest ways to create an enjoy Virtual Reality (VR) experiences is [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/csee.bangor.ac.uk\/projectrainbow\/2020\/06\/02\/introduction-to-web-based-xr-part-i\/\" \/>\n<meta property=\"og:site_name\" content=\"Project Rainbow\" \/>\n<meta property=\"article:published_time\" content=\"2020-06-02T11:26:04+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/cloud.githubusercontent.com\/assets\/674727\/20328731\/326137a8-ab49-11e6-9b76-4e3a65f333d9.jpg\" \/>\n<meta name=\"author\" content=\"panosritsos\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"panosritsos\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"6 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/csee.bangor.ac.uk\/projectrainbow\/2020\/06\/02\/introduction-to-web-based-xr-part-i\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/csee.bangor.ac.uk\/projectrainbow\/2020\/06\/02\/introduction-to-web-based-xr-part-i\/\"},\"author\":{\"name\":\"panosritsos\",\"@id\":\"https:\/\/csee.bangor.ac.uk\/projectrainbow\/#\/schema\/person\/f48ca517fc033f4a261405c409469135\"},\"headline\":\"Introduction to Web-based XR &#8211; Part I\",\"datePublished\":\"2020-06-02T11:26:04+00:00\",\"dateModified\":\"2020-06-02T11:26:04+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/csee.bangor.ac.uk\/projectrainbow\/2020\/06\/02\/introduction-to-web-based-xr-part-i\/\"},\"wordCount\":948,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/csee.bangor.ac.uk\/projectrainbow\/#organization\"},\"image\":{\"@id\":\"https:\/\/csee.bangor.ac.uk\/projectrainbow\/2020\/06\/02\/introduction-to-web-based-xr-part-i\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/cloud.githubusercontent.com\/assets\/674727\/20328731\/326137a8-ab49-11e6-9b76-4e3a65f333d9.jpg\",\"keywords\":[\"intermediate\",\"javascript\",\"web\"],\"articleSection\":[\"A-Frame\",\"Intermediate\",\"JavaScript\",\"Project Rainbow\",\"WebXR\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/csee.bangor.ac.uk\/projectrainbow\/2020\/06\/02\/introduction-to-web-based-xr-part-i\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/csee.bangor.ac.uk\/projectrainbow\/2020\/06\/02\/introduction-to-web-based-xr-part-i\/\",\"url\":\"https:\/\/csee.bangor.ac.uk\/projectrainbow\/2020\/06\/02\/introduction-to-web-based-xr-part-i\/\",\"name\":\"Introduction to Web-based XR - Part I - Project Rainbow\",\"isPartOf\":{\"@id\":\"https:\/\/csee.bangor.ac.uk\/projectrainbow\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/csee.bangor.ac.uk\/projectrainbow\/2020\/06\/02\/introduction-to-web-based-xr-part-i\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/csee.bangor.ac.uk\/projectrainbow\/2020\/06\/02\/introduction-to-web-based-xr-part-i\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/cloud.githubusercontent.com\/assets\/674727\/20328731\/326137a8-ab49-11e6-9b76-4e3a65f333d9.jpg\",\"datePublished\":\"2020-06-02T11:26:04+00:00\",\"dateModified\":\"2020-06-02T11:26:04+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/csee.bangor.ac.uk\/projectrainbow\/2020\/06\/02\/introduction-to-web-based-xr-part-i\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/csee.bangor.ac.uk\/projectrainbow\/2020\/06\/02\/introduction-to-web-based-xr-part-i\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/csee.bangor.ac.uk\/projectrainbow\/2020\/06\/02\/introduction-to-web-based-xr-part-i\/#primaryimage\",\"url\":\"https:\/\/cloud.githubusercontent.com\/assets\/674727\/20328731\/326137a8-ab49-11e6-9b76-4e3a65f333d9.jpg\",\"contentUrl\":\"https:\/\/cloud.githubusercontent.com\/assets\/674727\/20328731\/326137a8-ab49-11e6-9b76-4e3a65f333d9.jpg\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/csee.bangor.ac.uk\/projectrainbow\/2020\/06\/02\/introduction-to-web-based-xr-part-i\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/csee.bangor.ac.uk\/projectrainbow\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Introduction to Web-based XR &#8211; Part I\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/csee.bangor.ac.uk\/projectrainbow\/#website\",\"url\":\"https:\/\/csee.bangor.ac.uk\/projectrainbow\/\",\"name\":\"Project Rainbow\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/csee.bangor.ac.uk\/projectrainbow\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/csee.bangor.ac.uk\/projectrainbow\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/csee.bangor.ac.uk\/projectrainbow\/#organization\",\"name\":\"Project Rainbow\",\"url\":\"https:\/\/csee.bangor.ac.uk\/projectrainbow\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/csee.bangor.ac.uk\/projectrainbow\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/csee.bangor.ac.uk\/projectrainbow\/wp-content\/uploads\/sites\/2\/2020\/05\/bangor_logo_c1_flush.png\",\"contentUrl\":\"https:\/\/csee.bangor.ac.uk\/projectrainbow\/wp-content\/uploads\/sites\/2\/2020\/05\/bangor_logo_c1_flush.png\",\"width\":3356,\"height\":958,\"caption\":\"Project Rainbow\"},\"image\":{\"@id\":\"https:\/\/csee.bangor.ac.uk\/projectrainbow\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/csee.bangor.ac.uk\/projectrainbow\/#\/schema\/person\/f48ca517fc033f4a261405c409469135\",\"name\":\"panosritsos\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/csee.bangor.ac.uk\/projectrainbow\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/?s=96&d=mm&r=g\",\"caption\":\"panosritsos\"},\"url\":\"https:\/\/csee.bangor.ac.uk\/projectrainbow\/author\/panosritsos\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Introduction to Web-based XR - Part I - Project Rainbow","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/csee.bangor.ac.uk\/projectrainbow\/2020\/06\/02\/introduction-to-web-based-xr-part-i\/","og_locale":"en_US","og_type":"article","og_title":"Introduction to Web-based XR - Part I - Project Rainbow","og_description":"code { background-color: rgba(0,0,0,.05) !important; } .linenums { color: #aaa; } .linenums li { list-style-type: decimal !important; font-size: 12pt; margin-top: 0px; } .linenums li:nth-child(even) { background: transparent !important; } .wp-block-image { text-align: center !important; } .wp-block-image img { display: inline; } One of the easiest ways to create an enjoy Virtual Reality (VR) experiences is [&hellip;]","og_url":"https:\/\/csee.bangor.ac.uk\/projectrainbow\/2020\/06\/02\/introduction-to-web-based-xr-part-i\/","og_site_name":"Project Rainbow","article_published_time":"2020-06-02T11:26:04+00:00","og_image":[{"url":"https:\/\/cloud.githubusercontent.com\/assets\/674727\/20328731\/326137a8-ab49-11e6-9b76-4e3a65f333d9.jpg"}],"author":"panosritsos","twitter_card":"summary_large_image","twitter_misc":{"Written by":"panosritsos","Est. reading time":"6 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/csee.bangor.ac.uk\/projectrainbow\/2020\/06\/02\/introduction-to-web-based-xr-part-i\/#article","isPartOf":{"@id":"https:\/\/csee.bangor.ac.uk\/projectrainbow\/2020\/06\/02\/introduction-to-web-based-xr-part-i\/"},"author":{"name":"panosritsos","@id":"https:\/\/csee.bangor.ac.uk\/projectrainbow\/#\/schema\/person\/f48ca517fc033f4a261405c409469135"},"headline":"Introduction to Web-based XR &#8211; Part I","datePublished":"2020-06-02T11:26:04+00:00","dateModified":"2020-06-02T11:26:04+00:00","mainEntityOfPage":{"@id":"https:\/\/csee.bangor.ac.uk\/projectrainbow\/2020\/06\/02\/introduction-to-web-based-xr-part-i\/"},"wordCount":948,"commentCount":0,"publisher":{"@id":"https:\/\/csee.bangor.ac.uk\/projectrainbow\/#organization"},"image":{"@id":"https:\/\/csee.bangor.ac.uk\/projectrainbow\/2020\/06\/02\/introduction-to-web-based-xr-part-i\/#primaryimage"},"thumbnailUrl":"https:\/\/cloud.githubusercontent.com\/assets\/674727\/20328731\/326137a8-ab49-11e6-9b76-4e3a65f333d9.jpg","keywords":["intermediate","javascript","web"],"articleSection":["A-Frame","Intermediate","JavaScript","Project Rainbow","WebXR"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/csee.bangor.ac.uk\/projectrainbow\/2020\/06\/02\/introduction-to-web-based-xr-part-i\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/csee.bangor.ac.uk\/projectrainbow\/2020\/06\/02\/introduction-to-web-based-xr-part-i\/","url":"https:\/\/csee.bangor.ac.uk\/projectrainbow\/2020\/06\/02\/introduction-to-web-based-xr-part-i\/","name":"Introduction to Web-based XR - Part I - Project Rainbow","isPartOf":{"@id":"https:\/\/csee.bangor.ac.uk\/projectrainbow\/#website"},"primaryImageOfPage":{"@id":"https:\/\/csee.bangor.ac.uk\/projectrainbow\/2020\/06\/02\/introduction-to-web-based-xr-part-i\/#primaryimage"},"image":{"@id":"https:\/\/csee.bangor.ac.uk\/projectrainbow\/2020\/06\/02\/introduction-to-web-based-xr-part-i\/#primaryimage"},"thumbnailUrl":"https:\/\/cloud.githubusercontent.com\/assets\/674727\/20328731\/326137a8-ab49-11e6-9b76-4e3a65f333d9.jpg","datePublished":"2020-06-02T11:26:04+00:00","dateModified":"2020-06-02T11:26:04+00:00","breadcrumb":{"@id":"https:\/\/csee.bangor.ac.uk\/projectrainbow\/2020\/06\/02\/introduction-to-web-based-xr-part-i\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/csee.bangor.ac.uk\/projectrainbow\/2020\/06\/02\/introduction-to-web-based-xr-part-i\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/csee.bangor.ac.uk\/projectrainbow\/2020\/06\/02\/introduction-to-web-based-xr-part-i\/#primaryimage","url":"https:\/\/cloud.githubusercontent.com\/assets\/674727\/20328731\/326137a8-ab49-11e6-9b76-4e3a65f333d9.jpg","contentUrl":"https:\/\/cloud.githubusercontent.com\/assets\/674727\/20328731\/326137a8-ab49-11e6-9b76-4e3a65f333d9.jpg"},{"@type":"BreadcrumbList","@id":"https:\/\/csee.bangor.ac.uk\/projectrainbow\/2020\/06\/02\/introduction-to-web-based-xr-part-i\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/csee.bangor.ac.uk\/projectrainbow\/"},{"@type":"ListItem","position":2,"name":"Introduction to Web-based XR &#8211; Part I"}]},{"@type":"WebSite","@id":"https:\/\/csee.bangor.ac.uk\/projectrainbow\/#website","url":"https:\/\/csee.bangor.ac.uk\/projectrainbow\/","name":"Project Rainbow","description":"","publisher":{"@id":"https:\/\/csee.bangor.ac.uk\/projectrainbow\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/csee.bangor.ac.uk\/projectrainbow\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/csee.bangor.ac.uk\/projectrainbow\/#organization","name":"Project Rainbow","url":"https:\/\/csee.bangor.ac.uk\/projectrainbow\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/csee.bangor.ac.uk\/projectrainbow\/#\/schema\/logo\/image\/","url":"https:\/\/csee.bangor.ac.uk\/projectrainbow\/wp-content\/uploads\/sites\/2\/2020\/05\/bangor_logo_c1_flush.png","contentUrl":"https:\/\/csee.bangor.ac.uk\/projectrainbow\/wp-content\/uploads\/sites\/2\/2020\/05\/bangor_logo_c1_flush.png","width":3356,"height":958,"caption":"Project Rainbow"},"image":{"@id":"https:\/\/csee.bangor.ac.uk\/projectrainbow\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/csee.bangor.ac.uk\/projectrainbow\/#\/schema\/person\/f48ca517fc033f4a261405c409469135","name":"panosritsos","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/csee.bangor.ac.uk\/projectrainbow\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/?s=96&d=mm&r=g","caption":"panosritsos"},"url":"https:\/\/csee.bangor.ac.uk\/projectrainbow\/author\/panosritsos\/"}]}},"_links":{"self":[{"href":"https:\/\/csee.bangor.ac.uk\/projectrainbow\/wp-json\/wp\/v2\/posts\/316"}],"collection":[{"href":"https:\/\/csee.bangor.ac.uk\/projectrainbow\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/csee.bangor.ac.uk\/projectrainbow\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/csee.bangor.ac.uk\/projectrainbow\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/csee.bangor.ac.uk\/projectrainbow\/wp-json\/wp\/v2\/comments?post=316"}],"version-history":[{"count":0,"href":"https:\/\/csee.bangor.ac.uk\/projectrainbow\/wp-json\/wp\/v2\/posts\/316\/revisions"}],"wp:attachment":[{"href":"https:\/\/csee.bangor.ac.uk\/projectrainbow\/wp-json\/wp\/v2\/media?parent=316"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/csee.bangor.ac.uk\/projectrainbow\/wp-json\/wp\/v2\/categories?post=316"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/csee.bangor.ac.uk\/projectrainbow\/wp-json\/wp\/v2\/tags?post=316"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}