iphonex.js 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645
  1. import '../scss/style.scss'
  2. import '../scss/iphonex.scss'
  3. import '../scss/swiper-4.1.6.min.css'
  4. import * as THREE from 'three';
  5. import 'three/examples/js/loaders/GLTFLoader';
  6. import Swiper from './lib/swiper-4.1.6.min';
  7. import UTIL from './util';
  8. import Video from './video';
  9. import 'three/examples/js/controls/OrbitControls';
  10. import textureBox from '../texture/box-location.png'
  11. // 全景图
  12. import negx from '../texture/bg/negx.jpg'
  13. import negy from '../texture/bg/negy.jpg'
  14. import negz from '../texture/bg/negz.jpg'
  15. import posx from '../texture/bg/posx.jpg'
  16. import posy from '../texture/bg/posy.jpg'
  17. import posz from '../texture/bg/posz.jpg'
  18. var container, controls;
  19. var camera, scene, renderer;
  20. var projectiveObj;//定义上次投射到的对象
  21. var raycaster = new THREE.Raycaster();//光线投射器
  22. var mouse = new THREE.Vector2();//二维向量
  23. document.addEventListener('mousemove', function(){
  24. event.preventDefault();
  25. mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
  26. mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
  27. }, false);
  28. $(document).on('click', function(){
  29. $('.modal').fadeOut()
  30. controls ? controls.autoRotate = true : ''
  31. })
  32. /**
  33. * 添加鼠标点击事件,捕获点击时当前选中的物体
  34. */
  35. window.addEventListener( 'click', function(){
  36. if(projectiveObj){
  37. controls.autoRotate = false
  38. $('.entry-tips').hide()
  39. var Util = new UTIL(camera)
  40. var dataInfo = projectiveObj.dataInfo
  41. $('.modal-left-img').fadeOut()
  42. $('.modal-right').fadeOut()
  43. $('.modal-hide').fadeOut()
  44. if(dataInfo == 'screen') {
  45. Util.CameraTo(0, 0, 150, function() {
  46. $('#modal1').fadeIn()
  47. $('.modal-group1').addClass('fadeInLeft').show()
  48. })
  49. }
  50. if(dataInfo == 'faceId') {
  51. Util.CameraTo(-20, 40, 100, function() {
  52. $('#modal2').fadeIn()
  53. // $('.modal-group2').fadeIn()
  54. $('.modal-group2').addClass('fadeInLeft').show()
  55. })
  56. }
  57. if(dataInfo == 'camera') {
  58. Util.CameraTo(20, 20, 180, function() {
  59. $('#modal3').fadeIn()
  60. $('.modal-group3').addClass('fadeInRight').show()
  61. })
  62. }
  63. if(dataInfo == 'back-camera') {
  64. Util.CameraTo(40, 50, -160, function() {
  65. $('#modal4').fadeIn()
  66. $('.modal-group4').addClass('fadeInRight').show()
  67. })
  68. }
  69. if(dataInfo == 'A11') {
  70. Util.CameraTo(0, 0, -150, function() {
  71. $('#modal5').fadeIn()
  72. $('.modal-group5').addClass('fadeInRight').show()
  73. })
  74. }
  75. }
  76. }, false );
  77. function init() {
  78. container = document.createElement( 'div' );
  79. document.body.appendChild( container );
  80. // 视角:90度
  81. // 镜头宽高比: window.innerWidth / window.innerHeight
  82. // 近平面距离: 0.1
  83. // 远平面距离:1000
  84. camera = new THREE.PerspectiveCamera( 90, window.innerWidth / window.innerHeight, 0.1, 1000 );
  85. camera.position.z = 200
  86. camera.position.y = 0
  87. camera.position.x = 0
  88. if(window.location.search) {
  89. controls = new THREE.OrbitControls( camera );
  90. controls.autoRotate = true
  91. controls.autoRotateSpeed = 1
  92. controls.enablePan = false
  93. // controls.enableZoom = false
  94. controls.maxDistance = 300
  95. controls.minDistance = 200
  96. }
  97. scene = new THREE.Scene();
  98. scene.add( new THREE.HemisphereLight(0xffffff, 0xffffff, 1) );
  99. // envmap
  100. var path = 'iphoneX1/bg/';
  101. var format = '.jpg';
  102. var envMap = new THREE.CubeTextureLoader().load( [
  103. posx, negx,
  104. posy, negy,
  105. posz, negz
  106. ] );
  107. // scene.background = envMap
  108. // 添加辅助线
  109. // var helper = new THREE.GridHelper( 500, 100 );
  110. // helper.position.y = -50;
  111. // helper.material.opacity = 0.25;
  112. // helper.material.transparent = true;
  113. // scene.add( helper );
  114. //参数设置了三条轴线的长度
  115. // var axes = new THREE.AxisHelper(800);
  116. // scene.add(axes);
  117. // 创建互动点
  118. var geometry = new THREE.SphereGeometry(2,32,32);//盒子模型
  119. var tranGeometry = new THREE.SphereGeometry(6,96,96);//盒子模型
  120. var material = new THREE.MeshLambertMaterial({color: 0xffc000, transparent: true, opacity: 0.8})
  121. var tranMaterial = new THREE.MeshLambertMaterial({color: 0x0000ff, transparent: true, opacity: 0});
  122. var point1 = new THREE.Mesh( geometry, material );
  123. point1.position.set(0,0,8)
  124. scene.add( point1 );
  125. var tranPoint1 = new THREE.Mesh( tranGeometry, tranMaterial );
  126. tranPoint1.position.set(0,0,8)
  127. tranPoint1.dataInfo = 'screen'
  128. scene.add(tranPoint1)
  129. var point2 = new THREE.Mesh( geometry, material );
  130. point2.position.set(-12,119,10)
  131. scene.add( point2 );
  132. var tranPoint2 = new THREE.Mesh( tranGeometry, tranMaterial );
  133. tranPoint2.position.set(-12,119,10)
  134. tranPoint2.dataInfo = 'faceId'
  135. scene.add(tranPoint2)
  136. var point3 = new THREE.Mesh( geometry, material );
  137. point3.position.set(17,119,10)
  138. scene.add( point3 );
  139. var tranPoint3 = new THREE.Mesh( tranGeometry, tranMaterial );
  140. tranPoint3.position.set(17,119,10)
  141. tranPoint3.dataInfo = 'camera'
  142. scene.add(tranPoint3)
  143. var point4 = new THREE.Mesh( geometry, material );
  144. point4.position.set(45,98,-10)
  145. scene.add( point4 );
  146. var tranPoint4 = new THREE.Mesh( tranGeometry, tranMaterial );
  147. tranPoint4.position.set(45,98,-10)
  148. tranPoint4.dataInfo = 'back-camera'
  149. scene.add(tranPoint4)
  150. var point5 = new THREE.Mesh( geometry, material );
  151. point5.position.set(-26,55,-12)
  152. scene.add( point5 );
  153. var tranPoint5 = new THREE.Mesh( tranGeometry, tranMaterial );
  154. tranPoint5.position.set(-26,55,-12)
  155. tranPoint5.dataInfo = 'A11'
  156. scene.add(tranPoint5)
  157. // 加载3D模型
  158. var loader = new THREE.GLTFLoader();
  159. loader.load( 'iphonex/scene.gltf', function ( object ) {
  160. object.scene.traverse( function ( child ) {
  161. if ( child.isMesh ) {
  162. child.material.envMap = envMap;
  163. console.log(child)
  164. }
  165. } );
  166. scene.add( object.scene );
  167. });
  168. renderer = new THREE.WebGLRenderer({
  169. antialias: true,
  170. alpha: true
  171. });
  172. renderer.setClearColor(0x000000, 0);
  173. renderer.setPixelRatio( window.devicePixelRatio );
  174. renderer.setSize( window.innerWidth, window.innerHeight );
  175. container.appendChild( renderer.domElement );
  176. window.addEventListener( 'resize', resize, false );
  177. }
  178. function resize() {
  179. camera.aspect = window.innerWidth / window.innerHeight;
  180. camera.updateProjectionMatrix();
  181. renderer.setSize( window.innerWidth, window.innerHeight );
  182. }
  183. function animate() {
  184. if(controls) {
  185. controls.update();
  186. }
  187. renderRaycasterObj(raycaster,scene,camera,mouse);//渲染光投射器投射到的对象
  188. renderer.render( scene, camera );
  189. //重新渲染标签位置
  190. var Util = new UTIL(camera)
  191. Util.windowVector(0, 0, 8, 'modal1');
  192. Util.windowVector(-12,119,10, 'modal2');
  193. Util.windowVector(17,119,10, 'modal3');
  194. Util.windowVector(45,98,-10, 'modal4');
  195. Util.windowVector(-26,55,-12, 'modal5');
  196. requestAnimationFrame( animate );
  197. }
  198. /**
  199. * 根据光投射器判断鼠标所在向量方向是否穿过物体
  200. */
  201. function renderRaycasterObj(raycaster,scene,camera,mouse) {
  202. raycaster.setFromCamera(mouse, camera);
  203. var intersects = raycaster.intersectObjects(scene.children);
  204. if (intersects.length > 0) {
  205. var currentProjectiveObjT = intersects[0].object;
  206. if (projectiveObj != currentProjectiveObjT) {
  207. if((currentProjectiveObjT instanceof THREE.AxisHelper) || (currentProjectiveObjT instanceof THREE.GridHelper)){
  208. //穿过的是坐标轴线和网格线
  209. return;
  210. }
  211. projectiveObj = intersects[0].object;
  212. }
  213. } else {
  214. projectiveObj = null;
  215. }
  216. }
  217. // 弹窗根随球体
  218. // function modalAnimate() {
  219. // var Util = new UTIL(camera)
  220. // //重新渲染标签位置
  221. // Util.windowVector(0, 0, 8, 'modal1');
  222. // Util.windowVector(-12,119,10, 'modal2');
  223. // Util.windowVector(17,119,10, 'modal3');
  224. // Util.windowVector(45,98,-10, 'modal4');
  225. // Util.windowVector(-26,55,-12, 'modal5');
  226. // //每帧渲染
  227. // // renderer.render(scene, camera);
  228. // requestAnimationFrame(modalAnimate);
  229. // }
  230. init();
  231. // animate();
  232. // modalAnimate()
  233. // ---- 弹窗交互相关 ------
  234. var timer
  235. var scrollFlag = false
  236. var frontCameraSwiper = null
  237. var screenSwiper = null
  238. var planeSwiper = null
  239. var faceSwiper = null
  240. var backCameraSwiper = null
  241. // 入口页滚动进入
  242. if(!window.location.search && !controls) {
  243. $(document).on('mousewheel DOMMouseScroll', function (e) {
  244. //WebKit内核,Trident内核 => mousewheel
  245. //Gecko内核 => DOMMouseScroll
  246. e.preventDefault();
  247. var value = e.originalEvent.wheelDelta || -e.originalEvent.detail;
  248. //e.originalEvent.wheelDelta => 120(up) or -120(down) 谷歌IE内核
  249. //e.originalEvent.detail => -3(up) or 3(down) 火狐内核
  250. var delta = Math.max(-1, Math.min(1, value));
  251. // console.log(delta < 0 ? 'down' : 'up');
  252. if(delta < 0 && !scrollFlag) {
  253. clearInterval(timer)
  254. $('.iphonex-wrapper').fadeOut()
  255. $('.full-video').fadeIn()
  256. document.getElementById('entry-video').play()
  257. if(!controls) {
  258. controls = new THREE.OrbitControls( camera );
  259. controls.autoRotate = true
  260. controls.autoRotateSpeed = 1
  261. controls.enablePan = false
  262. // controls.enableZoom = false
  263. controls.maxDistance = 300
  264. controls.minDistance = 200
  265. }
  266. scrollFlag = true
  267. animate()
  268. }
  269. });
  270. }
  271. var View = {
  272. init() {
  273. this.setVideoSrc()
  274. this.handleModal()
  275. // 场景二回到场景一,不显示介绍
  276. var search = window.location.search
  277. if(search) {
  278. $('.iphonex-wrapper').hide()
  279. animate()
  280. } else {
  281. this.phoneChange()
  282. }
  283. $('.arrow').click(function() {
  284. clearInterval(timer)
  285. $('.iphonex-wrapper').fadeOut()
  286. $('.full-video').fadeIn()
  287. document.getElementById('entry-video').play()
  288. if(!controls) {
  289. controls = new THREE.OrbitControls( camera );
  290. controls.autoRotate = true
  291. controls.autoRotateSpeed = 1
  292. controls.enablePan = false
  293. // controls.enableZoom = false
  294. controls.maxDistance = 300
  295. controls.minDistance = 200
  296. }
  297. animate()
  298. })
  299. },
  300. setVideoSrc() {
  301. var vids = [8925251, 8904623, 8904999, 8908143, 8908435, 8908441,8908437,8908443,
  302. 8909221, 8909229,8925097]
  303. var videoEls = {
  304. '8925251': 'entry-video',
  305. '8904623': 'face-video1',
  306. '8904999': 'face-video2',
  307. '8908143': 'back-camera-video',
  308. '8908435': 'front-camera-video',
  309. '8908441': 'front-camera-video2',
  310. '8908437': 'front-camera-video3',
  311. '8908443': 'front-camera-video4',
  312. '8909221': 'screen-video1',
  313. '8909229': 'screen-video2',
  314. '8925097': 'suggest-video',
  315. }
  316. Video.getVideoSource(vids, videoEls)
  317. var entryVideo = document.getElementById('entry-video')
  318. entryVideo.addEventListener('ended', function() {
  319. $('.full-video').hide()
  320. })
  321. $('.video-next-btn').click(function(){
  322. entryVideo.pause()
  323. $('.full-video').hide()
  324. })
  325. },
  326. phoneChange() {
  327. var flag = true
  328. var $phone = $('.iphone-pic')
  329. var $phoneDown = $('.down-iphone-pic')
  330. timer = setInterval(() => {
  331. if(flag) {
  332. flag = false
  333. $phone.fadeOut('slow')
  334. $phoneDown.fadeIn('slow')
  335. } else {
  336. flag = true
  337. $phone.fadeIn('slow')
  338. $phoneDown.fadeOut('slow')
  339. }
  340. }, 6000);
  341. },
  342. videoPause() {
  343. var videoList = document.getElementsByTagName('video')
  344. for(var i = 0; i < videoList.length; i++) {
  345. videoList[i].pause()
  346. }
  347. },
  348. handleModal() {
  349. var $videoCon = $('.full-video-wrap')
  350. $('.close-full-video').click(function() {
  351. $(this).parent().hide()
  352. $videoCon.find('video').hide()
  353. var videoList = document.getElementsByTagName('video')
  354. for(var i = 0; i < videoList.length; i++) {
  355. videoList[i].pause()
  356. }
  357. })
  358. // 屏幕
  359. $('#modal1-poster1').click(function() {
  360. $('#screen-video1').show()
  361. $videoCon.show()
  362. document.getElementById('screen-video1').play()
  363. })
  364. $('#screen-know-more').click(function() {
  365. $('.screen-swiper').removeClass('fadeOutDown').addClass('fadeInUp').show()
  366. if(!screenSwiper) {
  367. View.swiperScreenCamera()
  368. }
  369. document.getElementById('screen-video2').currentTime = 0
  370. document.getElementById('screen-video2').play()
  371. })
  372. $('#close-screen-swiper').click(function() {
  373. View.videoPause()
  374. $('.screen-swiper').removeClass('fadeInUp').addClass('fadeOutDown')
  375. screenSwiper.slideTo(0, 0, false)
  376. })
  377. $('#reset-screen-video2').click(function() {
  378. document.getElementById('screen-video2').currentTime = 0
  379. document.getElementById('screen-video2').play()
  380. })
  381. // faceid
  382. $('#modal2-poster1').click(function() {
  383. $('#face-video1').show()
  384. $videoCon.show()
  385. document.getElementById('face-video1').play()
  386. })
  387. $('#modal2-poster2').click(function() {
  388. $('#face-video2').show()
  389. $videoCon.show()
  390. document.getElementById('face-video2').play()
  391. })
  392. $('#face-know-more').click(function() {
  393. $('.face-swiper').removeClass('fadeOutDown').addClass('fadeInUp').show()
  394. if(!faceSwiper) {
  395. View.swiperFace()
  396. }
  397. })
  398. $('#close-face-swiper').click(function() {
  399. $('.face-swiper').removeClass('fadeInUp').addClass('fadeOutDown')
  400. faceSwiper.slideTo(0, 0, false)
  401. })
  402. // 前置摄像头
  403. $('#modal3-poster').click(function() {
  404. $('#front-camera-video').show()
  405. $videoCon.show()
  406. document.getElementById('front-camera-video').play()
  407. })
  408. $('#modal3-poster1').click(function() {
  409. $('#front-camera-video3').show()
  410. $videoCon.show()
  411. document.getElementById('front-camera-video3').play()
  412. })
  413. $('#camera-know-more').click(function() {
  414. $('.camera-swiper').removeClass('fadeOutDown').addClass('fadeInUp').show()
  415. if(!frontCameraSwiper) {
  416. View.swiperFrontCamera()
  417. }
  418. })
  419. $('#close-camera-siwper').click(function() {
  420. View.videoPause()
  421. $('.camera-swiper').removeClass('fadeInUp').addClass('fadeOutDown')
  422. frontCameraSwiper.slideTo(0, 0, false)
  423. })
  424. // 后置摄像头
  425. $('#modal4-poster').click(function() {
  426. $('#back-camera-video').show()
  427. $videoCon.show()
  428. document.getElementById('back-camera-video').play()
  429. })
  430. $('#backcamera-know-more').click(function() {
  431. $('.back-camera-swiper').removeClass('fadeOutDown').addClass('fadeInUp').show()
  432. if(!backCameraSwiper) {
  433. View.swiperBackCamera()
  434. }
  435. })
  436. $('#close-backcamera-swiper').click(function() {
  437. $('.back-camera-swiper').removeClass('fadeInUp').addClass('fadeOutDown')
  438. backCameraSwiper.slideTo(0, 0, false)
  439. })
  440. // 玻璃后盖
  441. $('#plane-know-more').click(function() {
  442. $('.plane-swiper').removeClass('fadeOutDown').addClass('fadeInUp').show()
  443. if(!planeSwiper) {
  444. View.swiperPlane()
  445. }
  446. })
  447. $('#close-plane-swiper').click(function() {
  448. $('.plane-swiper').removeClass('fadeInUp').addClass('fadeOutDown')
  449. planeSwiper.slideTo(0, 0, false)
  450. })
  451. // 全屏视频结束自动退出
  452. var videoBox = document.getElementsByClassName('full-video-wrap')[0]
  453. var videos = videoBox.getElementsByTagName('video')
  454. for(var i = 0; i < videos.length; i++) {
  455. videos[i].addEventListener('ended', function() {
  456. $videoCon.hide()
  457. $videoCon.find('video').hide()
  458. })
  459. }
  460. // 评测视频
  461. $('#suggest-watch').click(function() {
  462. $('#suggest-video').show()
  463. $videoCon.show()
  464. document.getElementById('suggest-video').play()
  465. })
  466. // 进入扩展页,停止转动和缩放
  467. $('.bottom-more-btn').find('button').click(function(e) {
  468. controls.enableZoom = false
  469. return false
  470. })
  471. $('.close-swiper-btn').click(function() {
  472. controls.enableZoom = true
  473. return false
  474. })
  475. },
  476. swiperFrontCamera() {
  477. var ipxVideo = document.getElementById('front-camera-video2')
  478. var ipxVideo4 = document.getElementById('front-camera-video4')
  479. // 前置
  480. frontCameraSwiper = new Swiper('.swiper-front-camera',{
  481. direction : 'vertical',
  482. speed:800,
  483. mousewheel: true,
  484. pagination: {
  485. el: '.swiper-pagination',
  486. clickable: true,
  487. },
  488. on:{
  489. slideChangeTransitionStart: function(){
  490. // alert(this.activeIndex);
  491. if(this.activeIndex == 1) {
  492. ipxVideo.play()
  493. } else {
  494. ipxVideo.pause()
  495. }
  496. if(this.activeIndex == 2) {
  497. ipxVideo4.play()
  498. } else {
  499. ipxVideo4.pause()
  500. }
  501. }
  502. }
  503. });
  504. // 重播
  505. $('#reset-front-video2').click(function() {
  506. ipxVideo.currentTime = 0
  507. ipxVideo.play()
  508. })
  509. $('#reset-front-video4').click(function() {
  510. ipxVideo4.currentTime = 0
  511. ipxVideo4.play()
  512. })
  513. },
  514. swiperScreenCamera() {
  515. var ipxVideo = document.getElementById('screen-video2')
  516. screenSwiper = new Swiper('#screen-swiper',{
  517. direction : 'vertical',
  518. speed:800,
  519. mousewheel: true,
  520. pagination: {
  521. el: '.swiper-pagination',
  522. clickable: true,
  523. },
  524. on:{
  525. slideChangeTransitionStart: function(){
  526. if(this.activeIndex == 0) {
  527. setTimeout(() => {
  528. ipxVideo.play()
  529. }, 500);
  530. } else {
  531. ipxVideo.pause()
  532. }
  533. }
  534. }
  535. });
  536. },
  537. swiperPlane() {
  538. planeSwiper = new Swiper('.swiper-plane',{
  539. direction : 'vertical',
  540. speed:800,
  541. mousewheel: true,
  542. pagination: {
  543. el: '.swiper-pagination',
  544. clickable: true,
  545. },
  546. on:{
  547. }
  548. });
  549. },
  550. swiperFace() {
  551. faceSwiper = new Swiper('.swiper-face',{
  552. direction : 'vertical',
  553. speed:800,
  554. mousewheel: true,
  555. pagination: {
  556. el: '.swiper-pagination',
  557. clickable: true,
  558. },
  559. on:{
  560. }
  561. });
  562. },
  563. swiperBackCamera() {
  564. backCameraSwiper = new Swiper('.swiper-back-camera',{
  565. direction : 'vertical',
  566. speed:800,
  567. mousewheel: true,
  568. pagination: {
  569. el: '.swiper-pagination',
  570. clickable: true,
  571. },
  572. on:{
  573. }
  574. });
  575. }
  576. }
  577. View.init()