整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          看完這篇,你也可以實現一個360度全景插件(一)原理

          看完這篇,你也可以實現一個360度全景插件(一)原理篇

          本文從繪圖基礎開始講起,詳細介紹了如何使用Three.js開發一個功能齊全的全景插件。

          我們先來看一下插件的效果:

          如果你對Three.js已經很熟悉了,或者你想跳過基礎理論,那么你可以直接從全景預覽開始看起。

          本項目的github地址:https://github.com/ConardLi/tpanorama

          #一、理清關系

          #1.1 OpenGL

          OpenGL是用于渲染2D、3D量圖形的跨語言、跨平臺的應用程序編程接口(API)。

          這個接口由近350個不同的函數調用組成,用來從簡單的圖形比特繪制復雜的三維景象。

          OpenGL ES 是OpenGL三維圖形API的子集,針對手機、PDA和游戲主機等嵌入式設備而設計。

          基于OpenGL,一般使用C或Cpp開發,對前端開發者來說不是很友好。

          #1.2 WebGL

          WebGL把JavaScript和OpenGL ES 2.0結合在一起,從而為前端開發者提供了使用JavaScript編寫3D效果的能力。

          WebGL為HTML5 Canvas提供硬件3D加速渲染,這樣Web開發人員就可以借助系統顯卡來在瀏覽器里更流暢地展示3D場景和模型了,還能創建復雜的導航和數據視覺化。

          #1.3 Canvas

          Canvas是一個可以自由制定大小的矩形區域,可以通過JavaScript可以對矩形區域進行操作,可以自由的繪制圖形,文字等。

          一般使用Canvas都是使用它的2d的context功能,進行2d繪圖,這是其本身的能力。

          和這個相對的,WebGL是三維,可以描畫3D圖形,WebGL,想要在瀏覽器上進行呈現,它必須需要一個載體,這個載體就是Canvas,區別于之前的2dcontext,還可以從Canvas中獲取webglcontext。

          #1.4 Three.js

          我們先來從字面意思理解下:Three代表3D,js代表JavaScript,即使用JavaScript來開發3D效果。

          Three.js是使用JavaScript對 WebGL接口進行封裝與簡化而形成的一個易用的3D庫。

          直接使用WebGL進行開發對于開發者來說成本相對來說是比較高的,它需要你掌握較多的計算機圖形學知識。

          Three.js在一定程度上簡化了一些規范和難以理解的概念,對很多API進行了簡化,這大大降低了學習和開發三維效果成本。

          下面我們來具體看一下使用Three.js必須要知道的知識。

          #二、Three.js基礎知識

          使用Three.js繪制一個三維效果,至少需要以下幾個步驟:

          • 創建一個容納三維空間的場景 — Sence
          • 將需要繪制的元素加入到場景中,對元素的形狀、材料、陰影等進行設置
          • 給定一個觀察場景的位置,以及觀察角度,我們用相機對象(Camera)來控制
          • 將繪制好的元素使用渲染器(Renderer)進行渲染,最終呈現在瀏覽器上

          拿電影來類比的話,場景對應于整個布景空間,相機是拍攝鏡頭,渲染器用來把拍攝好的場景轉換成膠卷。

          #2.1 場景

          場景允許你設置哪些對象被three.js渲染以及渲染在哪里。

          我們在場景中放置對象、燈光和相機。

          很簡單,直接創建一個Scene的實例即可。

           _scene=new Scene();
          

          #2.2 元素

          有了場景,我們接下來就需要場景里應該展示哪些東西。

          一個復雜的三維場景往往就是由非常多的元素搭建起來的,這些元素可能是一些自定義的幾何體(Geometry),或者外部導入的復雜模型。

          Three.js 為我們提供了非常多的Geometry,例如SphereGeometry(球體)、 TetrahedronGeometry(四面體)、TorusGeometry(圓環體)等等。

          在Three.js中,材質(Material)決定了幾何圖形具體是以什么形式展現的。它包括了一個幾何體如何形狀以外的其他屬性,例如色彩、紋理、透明度等等,Material和Geometry是相輔相成的,必須結合使用。

          下面的代碼我們創建了一個長方體體,賦予它基礎網孔材料(MeshBasicMaterial)

              var geometry=new THREE.BoxGeometry(200, 100, 100);
              var material=new THREE.MeshBasicMaterial({ color: 0x645d50 });
              var mesh=new THREE.Mesh(geometry, material);
                      _scene.add(mesh);
          

          能以這個角度看到幾何體實際上是相機的功勞,這個我們下面的章節再介紹,這讓我們看到一個幾何體的輪廓,但是感覺怪怪的,這并不像一個幾何體,實際上我們還需要為它添加光照和陰影,這會讓幾何體看起來更真實。

          基礎網孔材料(MeshBasicMaterial)不受光照影響的,它不會產生陰影,下面我們為幾何體換一種受光照影響的材料:網格標準材質(Standard Material),并為它添加一些光照:

              var geometry=new THREE.BoxGeometry(200, 100, 100);
              var material=new THREE.MeshStandardMaterial({ color: 0x645d50 });
              var mesh=new THREE.Mesh(geometry, material);
              _scene.add(mesh);
              // 創建平行光-照亮幾何體
              var directionalLight=new THREE.DirectionalLight(0xffffff, 1);
               directionalLight.position.set(-4, 8, 12);
              _scene.add(directionalLight);
              // 創建環境光
              var ambientLight=new THREE.AmbientLight(0xffffff);
              _scene.add(ambientLight);
          

          有了光線的渲染,讓幾何體看起來更具有3D效果,Three.js中光源有很多種,我們上面使用了環境光(AmbientLight)和平行光(DirectionalLight)。

          環境光會對場景中的所有物品進行顏色渲染。

          平行光你可以認為像太陽光一樣,從極遠處射向場景中的光。它具有方向性,也可以啟動物體對光的反射效果。

          除了這兩種光,Three.js還提供了其他幾種光源,它們適用于不同情況下對不同材質的渲染,可以根據實際情況選擇。

          #2.3 坐標系

          在說相機之前,我們還是先來了解一下坐標系的概念:

          在三維世界中,坐標定義了一個元素所處于三維空間的位置,坐標系的原點即坐標的基準點。

          最常用的,我們使用距離原點的三個長度(距離x軸、距離y軸、距離z軸)來定義一個位置,這就是直角坐標系。

          在判定坐標系時,我們通常使用大拇指、食指和中指,并互為90度。大拇指代表X軸,食指代表Y軸,中指代表Z軸。

          這就產生了兩種坐標系:左手坐標系和右手坐標系。

          Three.js中使用的坐標系即右手坐標系。

          我們可以在我們的場景中添加一個坐標系,這樣我們可以清楚的看到元素處于什么位置:

           var axisHelper=new THREE.AxisHelper(600);
           _scene.add(axisHelper);
          

          其中紅色代表X軸,綠色代表Y軸,藍色代表Z軸。

          #2.4 相機

          上面看到的幾何體的效果,如果不創建一個相機(Camera),是什么也看不到的,因為默認的觀察點在坐標軸原點,它處于幾何體的內部。

          相機(Camera)指定了我們在什么位置觀察這個三維場景,以及以什么樣的角度進行觀察。

          #2.4.1 兩種相機的區別

          目前Three.js提供了幾種不同的相機,最常用的,也是下面插件中使用的兩種相機是:PerspectiveCamera(透視相機)、 OrthographicCamera(正交投影相機)。

          上面的圖很清楚的解釋了兩種相機的區別:

          右側是 OrthographicCamera(正交投影相機)他不具有透視效果,即物體的大小不受遠近距離的影響,對應的是投影中的正交投影。我們數學課本上所畫的幾何體大多數都采用這種投影。

          左側是PerspectiveCamera(透視相機),這符合我們正常人的視野,近大遠小,對應的是投影中的透視投影。

          如果你想讓場景看起來更真實,更具有立體感,那么采用透視相機最合適,如果場景中有一些元素你不想讓他隨著遠近放大縮小,那么采用正交投影相機最合適。

          #2.4.2 構造參數

          我們再分別來看看兩個創建兩個相機需要什么參數:

          _camera=new OrthographicCamera(left, right, top, bottom, near, far);
          

          OrthographicCamera接收六個參數,left, right, top, bottom分別對應上、下、左、右、遠、近的一個距離,超過這些距離的元素將不會出現在視野范圍內,也不會被瀏覽器繪制。實際上,這六個距離就構成了一個立方體,所以OrthographicCamera的可視范圍永遠在這個立方體內。

          _camera=new PerspectiveCamera(fov, aspect, near, far);
          

          PerspectiveCamera接收四個參數,near、far和上面的相同,分別對應相機可觀測的最遠和最近距離;fov代表水平范圍可觀測的角度,fov越大,水平范圍能觀測到的范圍越廣;aspect代表水平方向和豎直方向可觀測距離的比值,所以fov和aspect就可以確定垂直范圍內能觀測到的范圍。

          #2.4.3 position、lookAt

          關于相機還有兩個必須要知道的點,一個是position屬性,一個是lookAt函數:

          position屬性指定了相機所處的位置。

          lookAt函數指定相機觀察的方向。

          實際上position的值和lookAt接收的參數都是一個類型為Vector3的對象,這個對象用來表示三維空間中的坐標,它有三個屬性:x、y、z分別代表距離x軸、距離y軸、距離z軸的距離。

          下面,我們讓相機觀察的方向指向原點,另外分別讓x、y、z為0,另外兩個參數不為0,看一下視野會發生什么變化:

          _camera=new OrthographicCamera(-window.innerWidth / 2, window.innerWidth / 2, window.innerHeight / 2, -window.innerHeight / 2, 0.1, 1000);
           _camera.lookAt(new THREE.Vector3(0, 0, 0))
          
           _camera.position.set(0, 300, 600); // 1 - x為0
          
           _camera.position.set(500, 0, 600); // 2 - y為0
          
           _camera.position.set(500, 300, 0); // 3 - z為0
          

          很清楚的看到position決定了我們視野的出發點,但是鏡頭指向的方向是不變的。

          下面我們將position固定,改變相機觀察的方向:

          _camera=new OrthographicCamera(-window.innerWidth / 2, window.innerWidth / 2, window.innerHeight / 2, -window.innerHeight / 2, 0.1, 1000);
          _camera.position.set(500, 300, 600); 
          
          _camera.lookAt(new THREE.Vector3(0, 0, 0)) // 1 - 視野指向原點
          
          _camera.lookAt(new THREE.Vector3(200, 0, 0)) // 2 - 視野偏向x軸
          

          可見:我們視野的出發點是相同的,但是視野看向的方向發生了改變。

          #2.4.4 兩種相機對比

          好,有了上面的基礎,我們再來寫兩個例子看一看兩個相機的視角對比,為了方便觀看,我們創建兩個位置不同的幾何體:

          var geometry=new THREE.BoxGeometry(200, 100, 100);
          var material=new THREE.MeshStandardMaterial({ color: 0x645d50 });
          var mesh=new THREE.Mesh(geometry, material);
          _scene.add(mesh);
          
          var geometry=new THREE.SphereGeometry(50, 100, 100);
          var ball=new THREE.Mesh(geometry, material);
          ball.position.set(200, 0, -200);
          _scene.add(ball);
          

          正交投影相機視野:

          _camera=new OrthographicCamera(-window.innerWidth / 2, window.innerWidth / 2, window.innerHeight / 2, -window.innerHeight / 2, 0.1, 1000);
          _camera.position.set(0, 300, 600);
          _camera.lookAt(new THREE.Vector3(0, 0, 0))
          

          透視相機視野:

          _camera=new PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1100);
          _camera.position.set(0, 300, 600);
          _camera.lookAt(new THREE.Vector3(0, 0, 0))
          

          可見,這印證了我們上面關于兩種相機的理論

          #2.5 渲染器

          上面我們創建了場景、元素和相機,下面我們要告訴瀏覽器將這些東西渲染到瀏覽器上。

          Three.js也為我們提供了幾種不同的渲染器,這里我們主要看WebGL渲染器(WebGLRenderer)。顧名思義:WebGL渲染器使用WebGL來繪制場景,其夠利用GPU硬件加速從而提高渲染性能。

          _renderer=new THREE.WebGLRenderer();
          

          你需要將你使用Three.js繪制的元素添加到瀏覽器上,這個過程需要一個載體,上面我們介紹,這個載體就是Canvas,你可以通過_renderer.domElement獲取到這個Canvas,并將它給定到真實DOM中。

           _container=document.getElementById('conianer');
           _container.appendChild(_renderer.domElement);
          

          使用setSize函數設定你要渲染的范圍,實際上它改變的就是上面Canvas的范圍:

          _renderer.setSize(window.innerWidth, window.innerHeight);
          

          現在,你已經指定了一個渲染的載體和載體的范圍,你可以通過render函數渲染上面指定的場景和相機:

          _renderer.render(_scene, _camera);
          

          實際上,你如果依次執行上面的代碼,可能屏幕上還是黑漆漆的一片,并沒有任何元素渲染出來。

          這是因為上面你要渲染的元素可能并未被加載完,你就執行了渲染,并且只執行了一次,這時我們需要一種方法,讓場景和相機進行實時渲染,我們需要用到下面的方法:

          #2.6 requestAnimationFrame

          window.requestAnimationFrame()告訴瀏覽器——你希望執行一個動畫,并且要求瀏覽器在下次重繪之前調用指定的回調函數更新動畫。

          該方法需要傳入一個回調函數作為參數,該回調函數會在瀏覽器下一次重繪之前執行。

          window.requestAnimationFrame(callback);
          

          若你想在瀏覽器下次重繪之前繼續更新下一幀動畫,那么回調函數自身必須再次調用window.requestAnimationFrame()。

          使用者韓函數就意味著,你可以在requestAnimationFrame不停的執行繪制操作,瀏覽器就實時的知道它需要渲染的內容。

          當然,某些時候你已經不需要實時繪制了,你也可以使用cancelAnimationFrame立即停止這個繪制:

          window.cancelAnimationFrame(myReq);
          

          來看一個簡單的例子:

                  var i=0;
                  var animateName;
                  animate();
                  function animate() {
                      animateName=requestAnimationFrame(animate);
                      console.log(i++);
                      if (i > 100) {
                          cancelAnimationFrame(animateName);
                      }
                  }
          

          來看一下執行效果:

          我們使用requestAnimationFrame和Three.js的渲染器結合使用,這樣就能實時繪制三維動畫了:

                  function animate() {
                      requestAnimationFrame(animate);
                      _renderer.render(_scene, _camera);
                  }
          

          借助上面的代碼,我們可以簡單實現一些動畫效果:

                  var y=100;
                  var option='down';
                  function animateIn() {
                      animateName=requestAnimationFrame(animateIn);
                      mesh.rotateX(Math.PI / 40);
                      if (option=='up') {
                          ball.position.set(200, y +=8, 0);
                      } else {
                          ball.position.set(200, y -=8, 0);
                      }
                      if (y < 1) { option='up'; }
                      if (y > 100) { option='down' }
                  }
          

          #2.7 總結

          上面的知識是Three.js中最基礎的知識,也是最重要的和最主干的。

          這些知識能夠讓你在看到一個復雜的三維效果時有一定的思路,當然,要實現還需要非常多的細節。這些細節你可以去官方文檔中查閱。

          下面的章節即告訴你如何使用Three.js進行實戰 — 實現一個360度全景插件。

          這個插件包括兩部分,第一部分是對全景圖進行預覽。

          第二部分是對全景圖的標記進行配置,并關聯預覽的坐標。

          我們首先來看看全景預覽部分。

          文中如有錯誤,歡迎在評論區指正,如果這篇文章幫助到了你,歡迎點贊和關注。


          原地址:https://github.com/ConardLi/tpanorama



          • 60度的全景圖片效果常常可以用到給客戶做產品展示,今天這里我們推薦一個非常不錯的來自Robert Pataki的360全景幻燈實現教程,這里教程中將使用javascript來打造一個超酷的全景幻燈實現,相信大家一定會喜歡的!

          在這個教程中沒有使用到任何插件,我們將使用HTML,css和javascript來實現,當然,也使用是jQuery這個框架!

          如何實現?

          我們將使用預先按照360生成的圖片進行輪播來實現動畫展示效果。包含了180個圖片。所以加載時間可能比較長。

          代碼實現

          我們將在css代碼中添加media queries,來使得這個效果可以同時在ipad和iphone上實現。

          1. 代碼文件

          我們添加js,css,圖片目錄。css目錄中包含了reset.css。js中包含了jQuery。代碼文件如下:

          2. 新的項目

          創建一個HTML文件index.html。在<head>中我們設置了移動設備的viewport,使得內容不支持縮放。添加倆個文件

          reset.css和threesixty.css。包含了自定義的css樣式。

          <!DOCTYPE html><html lang="en"><head> ? ?<meta charset="utf-8"> ? ?<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0" /> ? ?<title>360</title> ? ?<link rel="stylesheet" href="css/reset.css" media="screen" type="text/css" /> ? ?<link rel="stylesheet" href="css/threesixty.css" media="screen" type="text/css" /></head><body> </body></html>

          3. 加載進度條

          創建一個<div>來容納幻燈。其中包含一個<ol>,用來包含圖片序列<li>,同時也包含了一個<span>來顯示進度條。我們將使用javascript來動態加載圖片。

          <!DOCTYPE html><html lang="en"><head> ? ?<meta charset="utf-8"> ? ?<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0" /> ? ?<title>360</title> ? ?<link rel="stylesheet" href="css/reset.css" media="screen" type="text/css" /> ? ?<link rel="stylesheet" href="css/threesixty.css" media="screen" type="text/css" /></head><body> ? ?<div id="threesixty"> ? ? ? ?<div id="spinner"> ? ? ? ? ? ?<span>0%</span> ? ? ? ?</div> ? ? ? ?<ol id="threesixty_images"></ol> ? ?</div></body></html>

          4. 添加互動

          代碼最后,我們添加jQuery用來處理互動,threesixity.js用來處理圖片幻燈。

          <!DOCTYPE html><html lang="en"><head> ? ?<meta charset="utf-8"> ? ?<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0" /> ? ?<title>360</title> ? ?<link rel="stylesheet" href="css/reset.css" media="screen" type="text/css" /> ? ?<link rel="stylesheet" href="css/threesixty.css" media="screen" type="text/css" /></head><body> ? ?<div id="threesixty"> ? ? ? ?<div id="spinner"> ? ? ? ? ? ?<span>0%</span> ? ? ? ?</div> ? ? ? ?<ol id="threesixty_images"></ol> ? ?</div> ? ? ? ?<script src="js/heartcode-canvasloader-min.js"></script> ? ?<script src="js/jquery-1.7.min.js"></script> ? ?<script src="js/threesixty.js"></script></body></html>

          5. 樣式

          我們添加threesixty.css文件。reset.css用來設置缺省的樣式。首先定義#threesixty包裝。缺省的圖片幻燈是960x450。水平垂直居中。

          #threesixty { ? ?position:absolute; ? ?overflow:hidden; ? ?top:50%; ? ?left:50%; ? ?width:960px; ? ?height:540px; ? ?margin-left:-480px; ? ?margin-top:-270px;}#threesixty_images { ? ?display: none;}

          全部代碼請見原文:http://www.gbtags.com/gb/share/5799.htm

          碼地址:https://github.com/Hubww/screenfull.js

          頁面代碼

          <section>
          <p>Try out the Fullscreen API</p>
          <button id="request">Request</button>
          <button id="exit">Exit</button>
          <button id="toggle">Toggle</button>
          <button id="request2">Request document</button>
          </section>
          <section>
          <ul>
          <li id="supported"></li>
          <li id="status"></li>
          <li id="element"></li>
          </ul>
          </section>
          <input autofocus placeholder="Keyboard test">
          <hr>
          <section>
          <p>Click the image to make it fullscreen</p>
          <img id="demo-img" src="https://sindresorhus.com/unicorn" width="500">
          </section>
          </section>
          

          js代碼

           $(function () {
          			$('#supported').text('Supported/allowed: ' + !!screenfull.isEnabled);
           //判斷是否支持插件
           if (!screenfull.isEnabled) {
          				return false;
          			}
           //手動全屏
          			$('#request').click(function () {
          				screenfull.request($('#container')[0]).then(function () {
          					console.log('Browser entered fullscreen mode')
          				})
          				// Does not require jQuery. Can be used like this too:
          				// screenfull.request(document.getElementById('container'));
          			});
           //退出全屏
          			$('#exit').click(function () {
          				screenfull.exit().then(function () {
          					console.log('Browser exited fullscreen mode')
          				});
          			});
           //切換全屏
          			$('#toggle').click(function () {
          				screenfull.toggle($('#container')[0]).then(function () {
          					console.log('Fullscreen mode: ' + (screenfull.isFullscreen ? 'enabled' : 'disabled'))
          				});
          			});
           //全屏整個頁面
          			$('#request2').click(function () {
          				screenfull.request();
          			});
           //點擊圖片全屏
          			$('#demo-img').click(function () {
          				screenfull.toggle(this);
          			});
          			function fullscreenchange() {
          				var elem=screenfull.element;
          				$('#status').text('Is fullscreen: ' + screenfull.isFullscreen);
          				if (elem) {
          					$('#element').text('Element: ' + elem.localName + (elem.id ? '#' + elem.id : ''));
          				}
          				if (!screenfull.isFullscreen) {
          					$('#external-iframe').remove();
          					document.body.style.overflow='auto';
          				}
          			}
          			screenfull.on('change', fullscreenchange);
          			// Set the initial values
          			fullscreenchange();
          		});
          

          API

          .request()
          Make an element fullscreen.
          Accepts a DOM element. Default is <html>. If called with another element than the currently active, it will switch to that if it's a decendant.
          If your page is inside an <iframe> you will need to add a allowfullscreen attribute (+ webkitallowfullscreen and mozallowfullscreen).
          Keep in mind that the browser will only enter fullscreen when initiated by user events like click, touch, key.
          Returns a promise that resolves after the element enters fullscreen.
          .exit()
          Brings you out of fullscreen.
          Returns a promise that resolves after the element exits fullscreen.
          .toggle()
          Requests fullscreen if not active, otherwise exits.
          Returns a promise that resolves after the element enters/exits fullscreen.
          .on(event, function)
          Events: 'change' | 'error'
          Add a listener for when the browser switches in and out of fullscreen or when there is an error.
          .off(event, function)
          Remove a previously registered event listener.
          .onchange(function)
          Alias for .on('change', function)
          .onerror(function)
          Alias for .on('error', function)
          .isFullscreen
          Returns a boolean whether fullscreen is active.
          .element
          Returns the element currently in fullscreen, otherwise null.
          .isEnabled
          Returns a boolean whether you are allowed to enter fullscreen. If your page is inside an <iframe> you will need to add a allowfullscreen attribute (+ webkitallowfullscreen and mozallowfullscreen).
          .raw
          Exposes the raw properties (prefixed if needed) used internally: requestFullscreen, exitFullscreen, fullscreenElement, fullscreenEnabled, fullscreenchange, fullscreenerror
          

          創建一個無縫的iframe來填充屏幕,然后轉到其中的頁面。


          主站蜘蛛池模板: 无码aⅴ精品一区二区三区| 日本不卡一区二区三区| 国产产一区二区三区久久毛片国语 | 美女一区二区三区| 无码免费一区二区三区免费播放| 亚洲AV日韩AV天堂一区二区三区| 中文字幕日韩精品一区二区三区| 久久中文字幕无码一区二区 | 国产产一区二区三区久久毛片国语| 在线日韩麻豆一区| 日本高清成本人视频一区| 亚洲一区免费观看| 波多野结衣一区二区三区高清av | 国产精品无码AV一区二区三区| 国产精品一区二区久久| 全国精品一区二区在线观看| 久久久精品一区二区三区| 人妻互换精品一区二区| 99精品久久精品一区二区| 亚洲av无码一区二区三区人妖| 亚洲av高清在线观看一区二区| 91香蕉福利一区二区三区| 福利一区在线视频| 亚洲一区二区三区高清视频| 日韩社区一区二区三区| 日韩人妻不卡一区二区三区| 福利一区福利二区| 伊人久久大香线蕉AV一区二区 | 国产成人精品第一区二区| 亚洲av高清在线观看一区二区| 日本免费一区二区在线观看| 日本道免费精品一区二区| 国产精品资源一区二区| 精品无码日韩一区二区三区不卡 | 东京热人妻无码一区二区av| 日韩在线视频一区| 91精品国产一区二区三区左线| 国产精品主播一区二区| 国产精品资源一区二区| 日韩中文字幕一区| 一区二区免费视频|