html5自动切换城市功能,HTML5 WebGL 无人驾驶城市巡航

JavaScript

语言:

JaveScriptBabelCoffeeScript

确定

const postProcessingConfig = {

active: true,

passes: [{

name: 'bloomPass',

active: true,

constructor: new helpers.passes.BloomUnrealPass({

resolution: new THREE.Vector2(256, 256),

strength: 0.9,

radius: 1.0,

threshold: 0.8

})

}, {

name: 'postPass',

active: true,

constructor: new helpers.passes.PostPass()

}]

}

const assets = [{

id: 'spaceship',

type: 'bin',

url: '/uploads/161101/city/spaceship.awd'

}]

class Renderer extends THREE.WebGLRenderer {

constructor(options = {

antialias: true,

alpha: true

}) {

super(options)

this.setSize(window.innerWidth, window.innerHeight)

this.setPixelRatio(window.devicePixelRatio)

this.setClearColor(0x000000, 1.0)

helpers.Window.add(::this.resize)

}

resize(width, height) {

this.setSize(width, height)

}

}

class Camera extends THREE.PerspectiveCamera {

constructor(fov, aspect, near, far) {

super(fov, aspect, near, far)

this.controls = new helpers.OrbitControls(this, document.getElementById('webgl-container'))

this.controls.enabled = false

this.GUI = helpers.GUI

this.resize = this.resize.bind(this)

helpers.Window.add(this.resize)

// this.addGUI()

}

addGUI() {

let toggleSwitch = 0

this.GUI.add(this.controls, 'enabled', {

label: 'OrbitControls',

onChange: (value) => {

toggleSwitch++

if (toggleSwitch % 2) return

console.log(this.controls.enabled)

}

})

}

update(delta) {

this.controls.update(delta)

}

resize(width, height) {

this.aspect = width / height

this.updateProjectionMatrix()

}

}

class Scene extends THREE.Scene {

constructor(Renderer, Camera, Loader) {

super()

this.renderer = Renderer

this.camera = Camera

this.loader = Loader

this.postProcessing = new helpers.PostProcessing(this, this.camera, this.renderer, postProcessingConfig)

this.postPass = this.postProcessing.getPass('postPass')

this.clock = new helpers.Clock()

this.mousePos = new THREE.Vector2()

this.looped = false

this.direction = 1

this.acceleration = 0

this.accelerationProgress = 0

this.citySize = 1200

this.halfCitySize = this.citySize / 2

this.cityBound = this.halfCitySize - 200

this.bind()

this.createScene()

this.initTls()

}

bind() {

this.handleMouseDown = ::this.handleMouseDown

this.handleMouseMove = ::this.handleMouseMove

this.handleTouchMove = ::this.handleTouchMove

document.addEventListener('mousedown', this.handleMouseDown, false)

document.addEventListener('mousemove', this.handleMouseMove, false)

document.addEventListener('touchmove', this.handleTouchMove, false)

}

handleMouseDown(event) {

TweenMax.to(this.accelerationTl, 0.35, {

progress: utils.clamp(0, 1, this.accelerationTl.progress() + 0.3),

ease: Expo.easeOut,

onComplete: () => {

this.accelerationTl.reverse()

}

})

}

handleMouseMove(event) {

const clientX = event.clientX

const clientY = event.clientY

this.mousePos.x = (clientX / window.innerWidth) * 2 - 1

this.mousePos.y = -(clientY / window.innerHeight) * 2 + 1

this.spaceshipTargetPosition.x = utils.clamp(-16, 16, this.spaceshipBasePosition.x + this.mousePos.x * 15) * this.direction

this.spaceshipTargetPosition.y = utils.map(this.mousePos.y, -1, 1, 3, 80)

this.spaceshipTargetPosition.z = this.spaceshipMesh.position.z

this.spaceshipTargetRotation.z = this.mousePos.x * Math.PI / 30

}

handleTouchMove(event) {

const clientX = event.touches[0].clientX

const clientY = event.touches[0].clientY

this.mousePos.x = (clientX / window.innerWidth) * 2 - 1

this.mousePos.y = -(clientY / window.innerHeight) * 2 + 1

this.spaceshipTargetPosition.x = utils.clamp(-16, 16, this.spaceshipBasePosition.x + this.mousePos.x * 15) * this.direction

this.spaceshipTargetPosition.y = utils.map(this.mousePos.y, -1, 1, 3, 80)

this.spaceshipTargetPosition.z = this.spaceshipMesh.position.z

this.spaceshipTargetRotation.z = this.mousePos.x * Math.PI / 30

}

initTls() {

this.accelerationTl = new TimelineMax({

paused: true

})

this.accelerationTl

.fromTo(this, 0.4, {

acceleration: 0

}, {

acceleration: 4

})

.to(this.postPass.material.uniforms.uRgbSplit.value, 0.4, {

x: 120,

y: 120,

ease: Expo.easeOut

}, 0)

.to(this.camera, 0.4, {

fov: 110,

onUpdate: () => {

this.camera.updateProjectionMatrix()

}

}, 0)

}

createScene() {

this.fog = new THREE.FogExp2(0x000000, 0.006)

const scale = this.citySize

const gridHelper = new THREE.GridHelper(scale / 2, 100)

this.add(gridHelper)

const aLight = new THREE.AmbientLight(0x212121)

this.add(aLight)

const dLight1 = new THREE.DirectionalLight(0xd8d8d8, 0.5)

dLight1.position.set(10, 16, -10)

this.add(dLight1)

const dLight2 = new THREE.DirectionalLight(0xc4c4c4, 0.6)

dLight2.position.set(-15, 10, -30)

this.add(dLight2)

const dLight3 = new THREE.DirectionalLight(0xa9a9a9, 0.4)

dLight3.position.set(0, 10, 10)

this.add(dLight3)

const boxGeometry = new THREE.BoxGeometry(1, 1, 1)

const boxMaterial = new THREE.MeshPhongMaterial({

color: 0x253a3f,

specular: 0x499293,

shininess: 5

})

const edgesGeometry = new THREE.EdgesGeometry(boxGeometry)

const planeG = new THREE.PlaneGeometry(1, 1, 1)

const planeM = new THREE.MeshBasicMaterial({

color: 0xffffff

})

const lineMaterial = new THREE.LineBasicMaterial({

color: 0xffffff,

fog: true,

linewidth: 1.5

})

const lineWidth = 0.2

const groundMaterial = new THREE.MeshPhongMaterial({

color: 0x141f22,

specular: 0x141f22,

shininess: 15

})

const ground = new THREE.Mesh(planeG, groundMaterial)

ground.rotation.set(-Math.PI / 2, 0, 0)

ground.position.setY(-0.1)

ground.scale.multiplyScalar(scale)

this.add(ground)

const lines = [

[-12 * 2, 0, 0],

[12 * 2, 0, 0]

]

for (let i = 0; i < lines.length; i++) {

const line = new THREE.Mesh(boxGeometry, lineMaterial)

line.position.fromArray(lines[i])

line.scale.set(lineWidth, lineWidth, scale)

this.add(line)

}

for (let j = 0; j < 900; j++) {

const box = new THREE.Mesh(boxGeometry, boxMaterial)

const boxHeight = utils.randomInt(8, 50)

const boxXPos = utils.randomFloat(-scale / 2 * 0.45, -16 * 2 - 5)

box.position.set((j % 2) ? boxXPos : Math.abs(boxXPos), boxHeight / 2, utils.randomInt(-this.halfCitySize, this.halfCitySize))

box.scale.set(utils.randomInt(3, 10), boxHeight, utils.randomInt(3, 10))

this.add(box)

const edges = new THREE.LineSegments(edgesGeometry, lineMaterial)

edges.position.copy(box.position)

edges.scale.copy(box.scale).multiplyScalar(1.001)

this.add(edges)

if (boxHeight <= 13) {

for (let i = 0; i < 10; i++) {

const plane = new THREE.Mesh(planeG, planeM)

plane.rotation.set(-Math.PI / 2, 0, 0)

plane.position.copy(box.position)

plane.position.y += utils.randomInt(-boxHeight / 2 + 2, boxHeight / 2 - 1)

plane.scale.set(box.scale.x, box.scale.z, 1).multiplyScalar(utils.randomFloat(1.1, 1.3))

this.add(plane)

}

}

}

const awdLoader = new helpers.AWDLoader()

const spaceshipObj = awdLoader.parse(this.loader.get('spaceship'))

this.spaceshipMesh = spaceshipObj.children[0].clone()

this.spaceshipMesh.material = new THREE.MeshPhongMaterial({

color: 0xffffff,

specular: 0xffffff,

shininess: 20

})

this.spaceshipMesh.scale.multiplyScalar(0.35)

this.spaceshipBasePosition = new THREE.Vector3(0, 5, 390)

this.spaceshipBaseRotation = this.spaceshipMesh.rotation.clone()

this.spaceshipTargetPosition = this.spaceshipBasePosition.clone()

this.spaceshipTargetRotation = this.spaceshipBaseRotation.clone()

this.lookAtPosition = new THREE.Vector3(this.spaceshipBasePosition.x, this.spaceshipBasePosition.y, -this.citySize)

this.spaceshipMesh.position.copy(this.spaceshipBasePosition)

this.add(this.spaceshipMesh)

this.render = this.render.bind(this)

this.raf = requestAnimationFrame(this.render)

}

render() {

this.postProcessing.update()

this.camera.update(this.clock.delta)

if (!this.looped && this.spaceshipMesh.position.z < -this.cityBound || this.spaceshipMesh.position.z > this.cityBound) {

this.looped = true

this.lookAtPosition.z = this.lookAtPosition.z * -1

if (this.spaceshipMesh.position.z < -this.cityBound) {

console.log('1')

this.direction = -1

} else if (this.spaceshipMesh.position.z > this.cityBound) {

console.log('2')

this.direction = 1

}

const rotation = (this.direction === 1) ? Math.PI * 2 * this.direction : Math.PI * this.direction

TweenMax.to(this.spaceshipTargetPosition, 0.4, {

x: 0,

ease: Expo.easeOut

})

TweenMax.to(this.spaceshipMesh.rotation, 2, {

y: rotation,

ease: Expo.easeOut,

onComplete: () => this.looped = false

})

TweenMax.fromTo(this.camera.rotation, 2, {

y: 0

}, {

y: 2 * Math.PI * this.direction,

ease: Expo.easeOut

})

}

const movementX = Math.sin(this.clock.time) * 6

const movementY = Math.sin(this.clock.time) * 4

this.spaceshipMesh.position.x += (this.spaceshipTargetPosition.x - this.spaceshipMesh.position.x + movementX) * .05

this.spaceshipMesh.position.y += (this.spaceshipTargetPosition.y - this.spaceshipMesh.position.y + movementY) * .015

this.spaceshipMesh.position.z -= (1 + this.acceleration) * this.direction

this.spaceshipMesh.rotation.z += (this.spaceshipTargetRotation.z - this.spaceshipMesh.rotation.z) * .025;

this.camera.position.x += (this.spaceshipMesh.position.x - this.camera.position.x) * .9

this.camera.position.y += (this.spaceshipMesh.position.y + 2 - this.camera.position.y) * .2

this.camera.position.z = this.spaceshipMesh.position.z + 10 * this.direction

this.camera.lookAt(this.lookAtPosition)

requestAnimationFrame(this.render)

}

}

class App {

/**

* begin method

*/

static begin() {

const credits = document.querySelector('.credits')

const loadingEl = document.querySelector('.loading')

const progress = document.querySelector('.loading__progress')

const progressTextEl = document.querySelector('.loading__progress__text')

const progressBarEl = document.querySelector('.loading__progress__bar')

credits.style.opacity = 1

progress.style.opacity = 1

// Renderer

const renderer = new Renderer()

const container = document.getElementById('webgl-container')

container.appendChild(renderer.domElement)

// Camera

const camera = new Camera(90, window.innerWidth / window.innerHeight, 0.1, 10000)

camera.position.x = 0

camera.position.y = 1500

camera.position.z = 400

// Scene

if (assets.length) {

const loader = helpers.assetsLoader({

assets, crossOrigin: 'anonymous'

})

loader.on('progress', progress => {

progressTextEl.innerHTML = `${Math.floor(progress * 100)}%`

progressBarEl.style.transform = `scale(${progress}, ${progress})`

})

loader.on('complete', assets => {

const scene = new Scene(renderer, camera, loader)

loadingEl.style.opacity = 0

})

loader.start()

} else {

loadingEl.style.display = 'none'

const scene = new Scene(renderer, camera)

}

}

}

let the = App.begin()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值