大屏看板學(xué)習(xí)

大屏自適應(yīng)

核心是使用css的transform中的scale進(jìn)行縮放以自適應(yīng)紧索,而縮放比例的計(jì)算需要確定一個(gè)基準(zhǔn)淤袜,例如1920*1080:

const getScale = useCallback(() => {
    const ww = document.documentElement.clientWidth / 1920;
    const wh = document.documentElement.clientHeight / 1080;
    return ww < wh ? ww : wh;
 }, []);

然后設(shè)置好resize的監(jiān)聽(tīng)事件踱讨,以及對(duì)應(yīng)樣式就好:

const demoKanBan = () => {
  const [scale, setScale] = useState();

  // 頁(yè)面初始化執(zhí)行
  useEffect(() => {
    changeSize();
    window.addEventListener('resize', changeSize);
  }, []);

  // 大屏縮放比例
  const getScale = useCallback(() => {
    const ww = document.documentElement.clientWidth / 1920;
    const wh = document.documentElement.clientHeight / 1080;
    return ww < wh ? ww : wh;
  }, []);

  // 防抖動(dòng)
  const changeSize = debounce(() => {
    const s = getScale();
    setScale(s);
  }, 500);

  return (
    <div
      style={{
        width: '100%',
        height: '100%',
        position: 'relative',
        backgroundColor: 'black',
      }}
    >
      <div
        style={{
          transform: `scale(${scale}) translate(-50%, -50%)`,
          WebkitTransform: `scale(${scale}) translate(-50%, -50%)`,
          width: `1920px`,
          height: `1080px`,
          transformOrigin: '0 0',
          position: 'absolute',
          left: '50%',
          top: '50%',
          transition: '0.3s',
        }}
      >
        {/* 看板內(nèi)容 */}
      </div>
    </div>
  );
};

截圖如下:


3D旋轉(zhuǎn)

讓物體旋轉(zhuǎn)起來(lái)峭梳,本質(zhì)就是讓它在進(jìn)行x軸運(yùn)動(dòng)的同時(shí)碾篡,y軸也在運(yùn)動(dòng)虱而,我們假定一個(gè)運(yùn)動(dòng)周期是20s,由于我們可以設(shè)置成交替的模式开泽,所以動(dòng)畫(huà)的時(shí)長(zhǎng)就是一半牡拇,10s。
我們先來(lái)介紹下css的animation這一屬性穆律,它是由六個(gè)子屬性組成的惠呼,即:

  • animation-name(動(dòng)畫(huà)名稱(chēng)、一般我們?cè)O(shè)置關(guān)鍵幀即可)
  • animation-duration(定義動(dòng)畫(huà)完成一個(gè)周期所需要的時(shí)間)
  • animation-timing-function(規(guī)定動(dòng)畫(huà)的速度曲線)
  • animation-delay(定義動(dòng)畫(huà)何時(shí)開(kāi)始峦耘,定義為負(fù)值的話可以使動(dòng)畫(huà)跳過(guò)指定時(shí)間)
  • animation-iteration-count(定義動(dòng)畫(huà)的播放次數(shù))
  • animation-direction(定義是否應(yīng)該輪流反向播放動(dòng)畫(huà))
    所以我們先定義相關(guān)的關(guān)鍵幀:
// x軸
@keyframes animX {
    0% {left: 0%;}
    100% {left: 90%;}
}
// y軸
@keyframes animY {
    0% {top: 0%;}
    100% {top: 80%;}
}

然后定義動(dòng)畫(huà)即可(多個(gè)動(dòng)畫(huà)可以','分隔)

.element1 {
    animation: animX 10s cubic-bezier(0.36, 0, 0.64, 1) -5s infinite alternate,
    animY 10s cubic-bezier(0.36, 0, 0.64, 1) 0s infinite alternate,
}

當(dāng)然剔蹋,要實(shí)現(xiàn)多個(gè)動(dòng)畫(huà)元素一起運(yùn)動(dòng)的效果,在這個(gè)例子里我們主要是控制animation-delay這一屬性辅髓,比如上面的x軸動(dòng)畫(huà)是直接從第5s開(kāi)始泣崩,y軸動(dòng)畫(huà)則是從0開(kāi)始,我們可以依次類(lèi)推接下來(lái)所要出現(xiàn)的動(dòng)畫(huà)元素初始的位置洛口,如果我們想要n個(gè)球一起旋轉(zhuǎn)矫付,那么后一個(gè)球只需要在前一個(gè)球的基礎(chǔ)上分別跳過(guò) 動(dòng)畫(huà)總時(shí)長(zhǎng)/n 秒即可;
比如說(shuō)上面我們定義的動(dòng)畫(huà)總時(shí)長(zhǎng)是20s第焰,10個(gè)元素一起旋轉(zhuǎn)买优,那么從第一個(gè)元素往后開(kāi)始,每個(gè)元素的延遲時(shí)間都要增加2s,element2的延時(shí)時(shí)間為-7s杀赢、-2s烘跺,element3的延遲時(shí)間為-9s,-4s葵陵,以此類(lèi)推液荸。
最后的效果如下圖:


Three.js

three.js是JavaScript編寫(xiě)的WebGL第三方庫(kù)。提供了非常多的3D顯示功能脱篙。
在react中進(jìn)行three.js的開(kāi)發(fā)娇钱,通過(guò)查找相關(guān)資料,@react-three/fiber這一個(gè)包使用可重用绊困、自包含的組件以聲明方式構(gòu)建場(chǎng)景文搂,這些組件可以對(duì)狀態(tài)做出反應(yīng),易于交互秤朗,并可以進(jìn)入react的生態(tài)系統(tǒng)煤蹭。而@react-three/drei則是three.js的一些預(yù)先制作好的功能的集合。
我們可以先添加這兩個(gè)包和three.js:

yarn add three @react-three/fiber @react-three/drei

下面是一些概念:
Canvas標(biāo)簽
這個(gè)Canvas是定義 React Three Fiber 場(chǎng)景的地方取视,有點(diǎn)像Three.js中的:

const scene = new THREE.Scene();

注意硝皂,Canvas標(biāo)簽首字母大寫(xiě),且需要從@react-three/fiber中引入作谭,而其它的大部分標(biāo)簽都已經(jīng)被注入稽物,可以直接使用。

import { Canvas } from '@react-three/fiber';

<Canvas>
{/* content */}
</Canvas>

mesh標(biāo)簽
相當(dāng)于Three.js中的網(wǎng)格:

new THREE.Mesh( geometry, material );

只是其相關(guān)屬性的定義可以寫(xiě)在標(biāo)簽體內(nèi)折欠,比如縮放和旋轉(zhuǎn)就可以這樣子定義:

<mesh
  scale={3}
  rotation={[0, Math.PI / 2, 0]}
>
</mesh>

ambientLight標(biāo)簽
相當(dāng)于Three.js中的環(huán)境光:

const light = new THREE.AmbientLight( color : Integer, intensity : Float);

同樣的贝或,現(xiàn)在傳入的參數(shù)可以作為相關(guān)屬性定義在標(biāo)簽體內(nèi):

<ambientLight intensity={intensity} color={color} />

directionalLight標(biāo)簽
相當(dāng)于Three.js中的平行光:

const directionalLight = new THREE.DirectionalLight( color : Integer, intensity : Float );

同樣的,現(xiàn)在傳入的參數(shù)可以作為相關(guān)屬性定義在標(biāo)簽體內(nèi):

<directionalLight intensity={intensity} color={color} position={position} />

OrbitControls標(biāo)簽
相當(dāng)于Three.js中的軌道控制器:

const controls = new OrbitControls( camera, renderer.domElement );

需要從@react-three/drei中引入锐秦,使用時(shí)直接:

import { OrbitControls } from "@react-three/drei";

<OrbitControls />

導(dǎo)入3d模型
可以去網(wǎng)站https://sketchfab.com/下載相關(guān)3d模型咪奖,使用原始的Three.js加載3d模型,方法是:

import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';

const loader = new GLTFLoader();
loader.load( 'path/to/model.glb', function ( gltf ) {
  scene.add( gltf.scene ); 
}, undefined, function ( error ) {
  console.error( error ); 
});

現(xiàn)在我們使用另一種方式來(lái)引入GLTF文件酱床,使用一種工具:gltf-pipeline

gltf-pipeline由Richard Lee和Cesium團(tuán)隊(duì)用來(lái)優(yōu)化glTF的工具羊赵。

    將glTF轉(zhuǎn)換為glb(并反向)
    將緩沖區(qū)/紋理保存為嵌入文件或單獨(dú)文件
    將glTF 1.0模型轉(zhuǎn)換為glTF 2.0
    應(yīng)用Draco網(wǎng)格壓縮

1.安裝:

yarn add global gltf-pipeline

2.將 glTF 轉(zhuǎn)換為 Draco glTF。通過(guò)終端進(jìn)入到3d模型的目錄下扇谣,在終端輸入以下命令:

gltf-pipeline -i scene.gltf -o yourName.gltf -d

然后就會(huì)在當(dāng)前目錄下生成 yourName.gltf 這一文件

3.生成js文件

npx gltfjsx yourName.gltf

就會(huì)在當(dāng)前目錄下生成yourName.js這一文件慷垮,這便是通過(guò)這個(gè)工具進(jìn)行操作后生成的可嵌入的一個(gè)3D模型;

然后我們把這兩個(gè)文件放入項(xiàng)目中揍堕,注意,由于生成的yourName.js中引入gltf默認(rèn)是

const { nodes, materials } = useGLTF('/xxx.gltf')

所以我們需要把gltf文件放到項(xiàng)目根目錄下的publi文件夾下面汤纸,然后在需要使用到模型的地方引入這個(gè)js文件即可:

import Car from "./Car.js";
import { Suspense } from "react";

<Suspense fallback={null}>
  <Car />
</Suspense>

完整的一個(gè)通過(guò)@react-three/fiber輔助創(chuàng)建的Three.js示例代碼如下:

import { Canvas } from '@react-three/fiber';
import { OrbitControls } from "@react-three/drei";
import React, { Suspense } from "react";
import Car from "./Car.js";

const ThreeTest = () => {
  return (
    <div style={{ width: '100%', height: '100%' }}>
      <Canvas style={{ width: '100%', height: '100%' }}>
        <ambientLight intensity={0.5} />
        <directionalLight position={[-2, 5, 2]} intensity={1} />
        <mesh
          scale={3}
          rotation={[0, Math.PI / 2, 0]}
        >
          <OrbitControls />
          <Suspense fallback={null}>
            <Car />
          </Suspense>
        </mesh>
      </Canvas>
    </div>
  );
};

export default ThreeTest;
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末衩茸,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子贮泞,更是在濱河造成了極大的恐慌楞慈,老刑警劉巖幔烛,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異囊蓝,居然都是意外死亡饿悬,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門(mén)聚霜,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)狡恬,“玉大人,你說(shuō)我怎么就攤上這事蝎宇〉芫ⅲ” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵姥芥,是天一觀的道長(zhǎng)兔乞。 經(jīng)常有香客問(wèn)我,道長(zhǎng)凉唐,這世上最難降的妖魔是什么庸追? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮台囱,結(jié)果婚禮上淡溯,老公的妹妹穿的比我還像新娘。我一直安慰自己玄坦,他們只是感情好血筑,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著煎楣,像睡著了一般豺总。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上择懂,一...
    開(kāi)封第一講書(shū)人閱讀 49,166評(píng)論 1 284
  • 那天喻喳,我揣著相機(jī)與錄音,去河邊找鬼困曙。 笑死表伦,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的慷丽。 我是一名探鬼主播蹦哼,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼要糊!你這毒婦竟也來(lái)了纲熏?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎局劲,沒(méi)想到半個(gè)月后勺拣,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡鱼填,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年药有,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片苹丸。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡愤惰,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出谈跛,到底是詐尸還是另有隱情羊苟,我是刑警寧澤,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布感憾,位于F島的核電站蜡励,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏阻桅。R本人自食惡果不足惜凉倚,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望嫂沉。 院中可真熱鬧稽寒,春花似錦、人聲如沸趟章。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)旨指。三九已至桥帆,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間蜀漆,已是汗流浹背谅河。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留确丢,地道東北人绷耍。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像鲜侥,于是被迫代替她去往敵國(guó)和親褂始。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344

推薦閱讀更多精彩內(nèi)容