function Map(selector) { this.stats = new Stats(); // Align top-left this.stats.domElement.style.position = 'fixed'; this.stats.domElement.style.left = '0'; this.stats.domElement.style.top = '0'; this.stats.domElement.style.zIndex = '10000'; document.body.appendChild( this.stats.domElement ); this.container = $(selector); this.container.width(this.container.parent().width()); this.container.height(this.container.parent().parent().height() - 61); this.windowHalfX = this.container.width() / 2; this.windowHalfY = this.container.height() / 2; this.mouseX = this.windowHalfX; this.mouseY = this.windowHalfY; this.generateScene(); this.generatePlane(); this.generateBuildings(); this.generateLights(); this.addToDOM(); this.animate(); var t = this; this.container.click(function(e) { //t.click(e); }); this.container.mousemove(function(e) { t.mouseMove(e); }); this.container.mousedown(function(e) { t.mouseDown(e); }); this.container.mouseup(function(e) { t.mouseUp(e); }); } Map.prototype.generateScene = function() { this.projector = new THREE.Projector(); this.scene = new THREE.Scene(); this.scene2 = new THREE.Scene(); this.camera = new THREE.PerspectiveCamera(75, this.container.innerWidth() / this.container.innerHeight(), 1, 10000); this.camera.position.x = -500; this.camera.position.y = 100; this.camera.position.z = 300; this.camera.lookAt({x: -300, y: 0, z: 0}); this.scene2.add(this.camera); } Map.prototype.generatePlane = function() { var img = new THREE.MeshBasicMaterial({ color: 0xCCCCCC, map: THREE.ImageUtils.loadTexture('images/map.jpg'), overdraw: true }); img.map.needsUpdate = true; this.plane = new THREE.Mesh(new THREE.PlaneGeometry(2048, 2048, 16, 16), img); this.scene.add(this.plane); } Map.prototype.generateBuildings = function() { //this._addCube(10, 10, 10, 0, 0, 0); } Map.prototype._addCube = function(w, h, d, x, y, z) { var geometry = new THREE.CubeGeometry(w, h, d); var material = new THREE.MeshLambertMaterial({ color: 0xffffff, shading: THREE.FlatShading, overdraw: true }); var cube = new THREE.Mesh(geometry, material); cube.position.x = x; cube.position.y = y + (h / 2); cube.position.z = z; this.scene2.add(cube); } Map.prototype.generateLights = function() { var ambientLight = new THREE.AmbientLight(Math.random() * 0x10); this.scene2.add(ambientLight); var directionalLight = new THREE.DirectionalLight(Math.random() * 0xffffff); directionalLight.position.x = Math.random() - 0.5; directionalLight.position.y = Math.random() - 0.5; directionalLight.position.z = Math.random() - 0.5; directionalLight.position.normalize(); this.scene2.add(directionalLight); var directionalLight = new THREE.DirectionalLight(Math.random() * 0xffffff); directionalLight.position.x = Math.random() - 0.5; directionalLight.position.y = Math.random() - 0.5; directionalLight.position.z = Math.random() - 0.5; directionalLight.position.normalize(); this.scene2.add(directionalLight); } Map.prototype.addToDOM = function(selector) { //this.renderer = new THREE.WebGLRenderer(); this.renderer = new THREE.CanvasRenderer(); this.renderer.setSize(this.container.innerWidth(), this.container.innerHeight()); this.renderer.autoClear = false; this.container.append(this.renderer.domElement); } Map.prototype.getMousePosition = function(event) { var parentOffset = this.container.offset(); var clickX = event.pageX - parentOffset.left; var clickY = event.pageY - parentOffset.top; var vector = new THREE.Vector3((clickX / this.container.innerWidth()) * 2 - 1, - (clickY / this.container.innerHeight()) * 2 + 1, 1); this.projector.unprojectVector(vector, this.camera); var ray = new THREE.Ray(this.camera.position, vector.subSelf(this.camera.position).normalize()); var intersect = ray.intersectObject(this.plane); return intersect[0].point; } Map.prototype.mouseDown = function(event) { this.mouseStartPosition = this.getMousePosition(event); } Map.prototype.mouseUp = function(event) { var pos = this.getMousePosition(event); var width = Math.abs(this.mouseStartPosition.x - pos.x); var depth = Math.abs(this.mouseStartPosition.z - pos.z); var middleX = (pos.x + this.mouseStartPosition.x) / 2; var middleZ = (pos.z + this.mouseStartPosition.z) / 2; this._addCube(width, 10, depth, middleX, 0, middleZ); } Map.prototype.mouseMove = function(event) { var parentOffset = this.container.offset(); var clickX = event.pageX - parentOffset.left; var clickY = event.pageY - parentOffset.top; this.mouseX = clickX - this.windowHalfX; this.mouseY = clickY - this.windowHalfY; } Map.prototype.animate = function() { this.stats.begin(); this.render(); this.stats.end(); } Map.prototype.render = function() { this.camera.position.x += (this.mouseX - this.camera.position.x) * 0.05; this.camera.position.y += ((-this.mouseY - this.camera.position.y) * 0.05); this.camera.lookAt(this.scene.position); this.renderer.clear(); this.renderer.render(this.scene, this.camera); this.renderer.render(this.scene2, this.camera); }