iphonex.js 18 KB

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