Playing with AR.js - Augmented Reality
Source and Markers - https://github.com/iondrimba/augmented-reality
A Pen by Ion Drimba Filho on CodePen.
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"> | |
| <meta name="theme-color" content="#f14a4a"> | |
| <meta name="application-name" content="Playing with Augmented Reality (Ar.js)"> | |
| <meta name="description" content="Playing with Augmented Reality (AR.js)"> | |
| <meta name="keywords" content="Threejs, Javascript, WebGl, Augmented Reality, Ion Drimba Filho"> | |
| <meta name="subject" content="Playing with Augmented Reality (Ar.js)"> | |
| <meta name="copyright" content="Ion Drimba Filho"> | |
| <meta name="robots" content="index,follow"> | |
| <meta name="topic" content=""> | |
| <meta name="summary" content="Playing with Augmented Reality (Ar.js)"> | |
| <meta name="author" content="Ion Drimba Filho"> | |
| <meta name="url" content="https://iondrimba.github.io/augmented-reality/public/"> | |
| <meta name="pagename" content="Playing with Augmented Reality (Ar.js)"> | |
| <meta name="category" content=""> | |
| <meta name="coverage" content="Worldwide"> | |
| <meta name="distribution" content="Global"> | |
| <meta name="rating" content="General"> | |
| <meta name="subtitle" content="Playing with Augmented Reality (Ar.js)"> | |
| <meta name="target" content="all"> | |
| <meta http-equiv="cleartype" content="on"> | |
| <meta name="twitter:card" content="summary_large_image"> | |
| <meta name="twitter:site" content="Playing with Augmented Reality (Ar.js)"> | |
| <meta name="twitter:creator" content="Ion Drimba Filho"> | |
| <meta name="twitter:title" content="Playing with Augmented Reality (Ar.js)"> | |
| <meta name="twitter:description" content="Playing with Augmented Reality (Ar.js)"> | |
| <meta name="twitter:image:src" content="https://raw.githubusercontent.com/iondrimba/images/master/augmented-reality.PNG"> | |
| <meta property="og:url" content="https://iondrimba.github.io/augmented-reality/public/"> | |
| <meta property="og:type" content="website"> | |
| <meta property="og:title" content="Playing with Augmented Reality (Ar.js) -Playing with Augmented Reality (AR.js)"> | |
| <meta property="og:image" content="https://raw.githubusercontent.com/iondrimba/images/master/augmented-reality.PNG"> | |
| <meta property="og:description" content="Playing with Augmented Reality (AR.js)"> | |
| <meta property="og:site_name" content="Playing with Augmented Reality (Ar.js)"> | |
| <meta property="article:author" content="https://iondrimbafilho.me/"> | |
| <meta property="article:publisher" content="https://iondrimbafilho.me/"> | |
| <meta itemprop="name" content="Playing with Augmented Reality (Ar.js)"> | |
| <meta itemprop="description" content="Playing with Augmented Reality (AR.js)"> | |
| <meta itemprop="image" content="https://raw.githubusercontent.com/iondrimba/images/master/augmented-reality.PNG"> | |
| <meta name="apple-mobile-web-app-capable" content="yes"> | |
| <meta name="mobile-web-app-capable" content="yes"> | |
| <title>Playing with Augmented Reality (Ar.js)</title> | |
| <link href="https://fonts.googleapis.com/css?family=Ropa+Sans" rel="stylesheet"> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/103/three.min.js"></script> | |
| <script src="https://Threejs.org/examples/js/controls/OrbitControls.js"></script> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.20.3/TweenMax.min.js"></script> | |
| <script src="https://iondrimba.github.io/augmented-reality/public/scripts/ar.js"></script> | |
| </head> | |
| <body> | |
| <div class="loader"></div> | |
| <h1>AR - Augmented Reality Demo</h1> | |
| </body> | |
| </html> |
Playing with AR.js - Augmented Reality
Source and Markers - https://github.com/iondrimba/augmented-reality
A Pen by Ion Drimba Filho on CodePen.
| // Markers can be found at https://github.com/iondrimba/augmented-reality | |
| class App { | |
| init() { | |
| this.icosahedron = this.getIcosahedron(0xff005c); | |
| this.velocity = .08; | |
| this.angle = 0; | |
| this.patterns = [{ | |
| id: 'hiro', | |
| mesh: this.getHole() | |
| }, { | |
| id: 'letterA', | |
| mesh: this.getTourus() | |
| }, | |
| { | |
| id: 'letterB', | |
| mesh: this.getIcosahedron() | |
| }, | |
| { | |
| id: 'letterC', | |
| mesh: this.getSphere() | |
| }]; | |
| this.createScene(); | |
| this.createCamera(); | |
| this.addAmbientLight(); | |
| this.addSpotLight(); | |
| this.addRectLight(); | |
| this.setupARToolkitContext(); | |
| this.setupARToolkitSource(); | |
| this.mapMarkersWithMeshes(); | |
| this.animate(); | |
| } | |
| createScene() { | |
| this.scene = new THREE.Scene(); | |
| this.renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true }); | |
| this.renderer.setClearColor(0x000000, 0); | |
| this.renderer.setSize(640, 480); | |
| this.renderer.shadowMap.enabled = true; | |
| this.renderer.shadowMap.type = THREE.PCFSoftShadowMap; | |
| document.body.appendChild(this.renderer.domElement); | |
| } | |
| createCamera() { | |
| const width = window.innerWidth; | |
| const height = window.innerHeight; | |
| this.camera = new THREE.OrthographicCamera(width / - 2, width / 2, height / 2, height / - 2, 1, 1000); | |
| this.scene.add(this.camera); | |
| } | |
| addRectLight() { | |
| const rectLight = new THREE.RectAreaLight('#0077ff', 1, 2000, 2000); | |
| rectLight.position.set(5, 50, 0); | |
| rectLight.lookAt(0, 0, 0); | |
| this.scene.add(rectLight); | |
| } | |
| addSpotLight() { | |
| const spotLight = new THREE.SpotLight(0xffffff); | |
| spotLight.position.set(0, 50, 0); | |
| spotLight.castShadow = true; | |
| this.scene.add(spotLight); | |
| } | |
| addAmbientLight() { | |
| this.scene.add(new THREE.AmbientLight(0xffffff)); | |
| } | |
| setupARToolkitContext() { | |
| this.arToolkitContext = new THREEx.ArToolkitContext({ | |
| cameraParametersUrl: 'https://iondrimba.github.io/augmented-reality/public/data/camera_para.dat', | |
| detectionMode: 'mono' | |
| }); | |
| this.arToolkitContext.init(() => { | |
| this.camera.projectionMatrix.copy(this.arToolkitContext.getProjectionMatrix()); | |
| }); | |
| } | |
| setupARToolkitSource() { | |
| this.arToolkitSource = new THREEx.ArToolkitSource({ | |
| sourceType: 'webcam', | |
| }); | |
| this.arToolkitSource.init(() => { | |
| this.onResize(); | |
| }); | |
| } | |
| getTourus() { | |
| const mesh = new THREE.Mesh(new THREE.TorusBufferGeometry(10, 3, 16, 100), new THREE.MeshPhysicalMaterial({ | |
| color: 0xff00ff, | |
| metalness: .58, | |
| emissive: '#000000', | |
| roughness: .18, | |
| })); | |
| mesh.scale.set(.1, .1, .1) | |
| mesh.position.set(0, 2, 0); | |
| return mesh; | |
| } | |
| getIcosahedron(color = 0x00ff00) { | |
| const mesh = new THREE.Mesh(new THREE.IcosahedronGeometry(1, 0), new THREE.MeshPhysicalMaterial({ | |
| color, | |
| metalness: .58, | |
| emissive: '#000000', | |
| roughness: .18, | |
| })); | |
| mesh.position.set(0, 2, 0); | |
| return mesh; | |
| } | |
| getSphere() { | |
| const mesh = new THREE.Mesh(new THREE.SphereGeometry(1, 32, 32), new THREE.MeshPhysicalMaterial({ | |
| color: 0x0986f5, | |
| metalness: .58, | |
| emissive: '#000000', | |
| roughness: .18, | |
| })); | |
| mesh.position.set(0, 2, 0); | |
| return mesh; | |
| } | |
| getHole() { | |
| const group = new THREE.Group(); | |
| const cube = new THREE.Mesh(new THREE.BoxGeometry(2, 2, 2), new THREE.MeshPhysicalMaterial({ color: 0xffffff, side: THREE.BackSide, transparent: true })); | |
| cube.position.y = -1; | |
| group.add(cube); | |
| const geometry = new THREE.PlaneGeometry(18, 18, 9, 9); | |
| geometry.faces.splice(80, 2); | |
| geometry.faceVertexUvs[0].splice(80, 2); | |
| const mesh = new THREE.Mesh(geometry, new THREE.MeshBasicMaterial({ colorWrite: false })); | |
| mesh.rotation.x = -Math.PI / 2; | |
| group.add(mesh); | |
| this.icosahedron = this.getIcosahedron(0xff005c); | |
| this.icosahedron.position.y = -.5; | |
| this.icosahedron.scale.set(.5, .5, .5); | |
| group.add(this.icosahedron); | |
| return group; | |
| } | |
| mapMarkersWithMeshes() { | |
| this.patterns.map((pattern) => { | |
| const markerRoot = new THREE.Group(); | |
| this.scene.add(markerRoot); | |
| new THREEx.ArMarkerControls(this.arToolkitContext, markerRoot, { | |
| type: 'pattern', patternUrl: `https://iondrimba.github.io/augmented-reality/public/data/${pattern.id}.patt`, | |
| }); | |
| markerRoot.add(pattern.mesh); | |
| }); | |
| } | |
| onResize() { | |
| this.arToolkitSource.onResizeElement(); | |
| this.arToolkitSource.copyElementSizeTo(this.renderer.domElement); | |
| if (this.arToolkitContext.arController) { | |
| this.arToolkitSource.copyElementSizeTo(this.arToolkitContext.arController.canvas) | |
| } | |
| } | |
| animate() { | |
| this.renderer.render(this.scene, this.camera); | |
| this.patterns[1].mesh.rotation.y += .05; | |
| this.patterns[2].mesh.rotation.y += .05; | |
| this.patterns[1].mesh.rotation.x -= .08; | |
| this.patterns[2].mesh.rotation.x -= .08; | |
| this.icosahedron.rotation.y += .05; | |
| this.icosahedron.rotation.x -= .08; | |
| this.patterns[3].mesh.position.x = Math.sin(this.angle); | |
| if (this.arToolkitSource && this.arToolkitSource.ready) { | |
| this.arToolkitContext.update(this.arToolkitSource.domElement); | |
| } | |
| this.angle += this.velocity; | |
| requestAnimationFrame(this.animate.bind(this)); | |
| } | |
| } | |
| new App().init(); |
| * { | |
| box-sizing: border-box; | |
| } | |
| html, body { | |
| margin: 0; | |
| padding: 0; | |
| width: 100vw; | |
| height: 100vh; | |
| font-family: 'Ropa Sans', sans-serif; | |
| color: #ffffff; | |
| box-sizing: border-box; | |
| background-color:red; | |
| overflow: hidden; | |
| } | |
| canvas, video { | |
| position: absolute; | |
| top: 0; | |
| left: 0; | |
| z-index: 2; | |
| } | |
| video { | |
| z-index: 1!important; | |
| } | |
| h1, h2 { | |
| padding: 20px; | |
| margin: 0; | |
| color: inherit; | |
| } | |
| footer { | |
| position: absolute; | |
| bottom: 0; | |
| margin-left: 20px; | |
| margin-bottom: 20px; | |
| } | |
| .loader { | |
| position: absolute; | |
| width: 100%; | |
| height: 100%; | |
| top: 0; | |
| z-index: 0; | |
| transform: scale(0, 1); | |
| transform-origin: left; | |
| -webkit-transition: transform .3s cubic-bezier(.23, 1, .32, 1); | |
| transition: transform .3s cubic-bezier(.23, 1, .32, 1); | |
| background: #007adf; /* fallback for old browsers */ | |
| background-image: linear-gradient(to top, #007adf 0%, #00ecbc 100%); | |
| } | |
Good