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