• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

Three.js--》实现3d官网模型展示

武飞扬头像
亦世凡华、
帮助1

目录

项目搭建

实现网页简单布局

初始化three.js基础代码

创建环境背景

加载飞船模型

实现滚轮滑动切换3D场景

设置星光流动特效


今天简单实现一个three.js的小Demo,加强自己对three知识的掌握与学习,只有在项目中才能灵活将所学知识运用起来,话不多说直接开始。

项目搭建

本案例还是借助框架书写three项目,借用vite构建工具搭建vue项目,vite这个构建工具如果有不了解的朋友,可以参考我之前对其讲解的文章:vite脚手架的搭建与使用 。搭建完成之后,用编辑器打开该项目,在终端执行 npm i 安装一下依赖,安装完成之后终端在安装 npm i three 即可。

因为我搭建的是vue3项目,为了便于代码的可读性,所以我将three.js代码单独抽离放在一个组件当中,在App根组件中进入引入该组件。具体如下:

  1.  
    <template>
  2.  
    <!-- 3D网页 -->
  3.  
    <WebPage></WebPage>
  4.  
    </template>
  5.  
     
  6.  
    <script setup>
  7.  
    import WebPage from './components/WebPage.vue';
  8.  
    </script>
  9.  
     
  10.  
    <style lang="less">
  11.  
    *{
  12.  
    margin: 0;
  13.  
    padding: 0;
  14.  
    }
  15.  
    </style>
学新通

实现网页简单布局

  1.  
    <template>
  2.  
    <div class="home">
  3.  
    <div class="canvas-container" ref="screenDom"></div>
  4.  
    <div class="header">
  5.  
    <div class="menu">
  6.  
    <a href="#" class="menuItem">首页</a>
  7.  
    <a href="#" class="menuItem">详情</a>
  8.  
    <a href="#" class="menuItem">关于</a>
  9.  
    </div>
  10.  
    </div>
  11.  
    <div class="pages" ref="pages">
  12.  
    <div class="page">
  13.  
    <h2 class="title">前端技术</h2>
  14.  
    <p>轻松、好玩、有趣掌握前沿硬核前端技术</p>
  15.  
    </div>
  16.  
    <div class="page">
  17.  
    <h2 class="title">WEB 3D可视化</h2>
  18.  
    <p>领略WEB 3D的魅力,让页面无比酷炫</p>
  19.  
    </div>
  20.  
    <div class="page">
  21.  
    <h2 class="title">ThreeJS框架</h2>
  22.  
    <p>让前端开发3D效果更方便</p>
  23.  
    </div>
  24.  
    </div>
  25.  
    </div>
  26.  
    </template>
  27.  
     
  28.  
    <style>
  29.  
    * {
  30.  
    margin: 0;
  31.  
    padding: 0;
  32.  
    }
  33.  
    body {
  34.  
    background-color: #000;
  35.  
    }
  36.  
    .canvas-container {
  37.  
    width: 100vw;
  38.  
    height: 100vh;
  39.  
    }
  40.  
    .home {
  41.  
    width: 100vw;
  42.  
    height: 100vh;
  43.  
    transform-origin: 0 0;
  44.  
    }
  45.  
    .header {
  46.  
    position: fixed;
  47.  
    top: 0;
  48.  
    left: 0;
  49.  
    width: 100vw;
  50.  
    height: 100px;
  51.  
    display: flex;
  52.  
    justify-content: space-between;
  53.  
    align-items: center;
  54.  
    }
  55.  
    .canvas-container {
  56.  
    width: 100%;
  57.  
    height: 100%;
  58.  
    }
  59.  
    .menu {
  60.  
    display: flex;
  61.  
    justify-content: space-between;
  62.  
    align-items: center;
  63.  
    margin-right: 50px;
  64.  
    }
  65.  
    .menuItem {
  66.  
    padding: 0 15px;
  67.  
    text-decoration: none;
  68.  
    color: #fff;
  69.  
    font-weight: 900;
  70.  
    font-size: 15px;
  71.  
    }
  72.  
    .progress {
  73.  
    position: fixed;
  74.  
    top: 0;
  75.  
    left: 0;
  76.  
    width: 100vw;
  77.  
    height: 100vh;
  78.  
    z-index: 101;
  79.  
    display: flex;
  80.  
    justify-content: center;
  81.  
    align-items: center;
  82.  
    font-size: 20px;
  83.  
    color: #fff;
  84.  
    }
  85.  
    .progress > img {
  86.  
    padding: 0 15px;
  87.  
    }
  88.  
    .pages {
  89.  
    display: flex;
  90.  
    flex-direction: column;
  91.  
    position: fixed;
  92.  
    top: 0;
  93.  
    left: 0;
  94.  
    }
  95.  
    .pages .page {
  96.  
    width: 100vw;
  97.  
    height: 100vh;
  98.  
    display: flex;
  99.  
    flex-direction: column;
  100.  
    justify-content: center;
  101.  
    align-items: flex-start;
  102.  
    color: #fff;
  103.  
    padding: 15%;
  104.  
    box-sizing: border-box;
  105.  
    }
  106.  
    .pages .page .title {
  107.  
    font-size: 50px;
  108.  
    font-weight: 900;
  109.  
    margin-bottom: 20px;
  110.  
    }
  111.  
    .pages .page p {
  112.  
    font-size: 25px;
  113.  
    }
  114.  
    </style>
学新通

初始化three.js基础代码

three.js开启必须用到的基础代码如下:

导入three库

import * as THREE from 'three'

初始化场景

const scene = new THREE.Scene()

初始化相机

  1.  
    let camera = new THREE.PerspectiveCamera(45,window.innerWidth / window.innerHeight,0.1,100000);
  2.  
    camera.position.set(0, 0, 10);

初始化渲染器

  1.  
    let renderer = new THREE.WebGLRenderer({ antialias: true });
  2.  
    renderer.setSize(window.innerWidth, window.innerHeight);

监听屏幕大小的改变,修改渲染器的宽高和相机的比例

  1.  
    window.addEventListener("resize",()=>{
  2.  
    renderer.setSize(window.innerWidth,window.innerHeight)
  3.  
    camera.aspect = window.innerWidth/window.innerHeight
  4.  
    camera.updateProjectionMatrix()
  5.  
    })

设置渲染函数

  1.  
    // 创建渲染函数
  2.  
    const render = () => {
  3.  
    requestAnimationFrame(render);
  4.  
    renderer.render(scene, camera);
  5.  
    }
  6.  
    render();

进行挂载

  1.  
    onMounted(() => {
  2.  
    // 将画布添加到页面中
  3.  
    screenDom.value.appendChild(renderer.domElement);
  4.  
    render()
  5.  
    });

ok,写完基础代码之后,接下来开始具体的Demo实操。 

创建环境背景

这里通过TextureLoader加载各种类型的纹理图像,包括JPEG、PNG、GIF等。通过TextureLoader,开发人员可以轻松地将纹理加载到自己的Three.js场景中,从而为场景增加更多的细节和视觉效果。

  1.  
    // 创建星空的背景
  2.  
    let url = "src/assets/imgs/25s.jpg";
  3.  
    let envTexture = new THREE.TextureLoader().load(url);
  4.  
    envTexture.mapping = THREE.EquirectangularReflectionMapping;
  5.  
    scene.background = envTexture;
  6.  
    scene.environment = envTexture;

学新通

加载飞船模型

经过前几篇对three.js小demo的训练,相信大家对加载模型可谓是得心应手了吧,无非就四步嘛,这里有个情况就是我还额外使用了动画库进行处理,所以步骤稍微要复杂一点。

第一步引入加载GLTF模型和压缩模型以及gsap的第三方库:

  1.  
    // 加载GLTF模型
  2.  
    import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
  3.  
    // 解压GLTF模型
  4.  
    import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader';
  5.  
    // 动画库
  6.  
    import { gsap } from "gsap";

第二步初始化loader:

  1.  
    let dracoLoader = new DRACOLoader();
  2.  
    dracoLoader.setDecoderPath("./draco/gltf/");
  3.  
    dracoLoader.setDecoderConfig({ type: "js" });
  4.  
    let loader = new GLTFLoader();
  5.  
    loader.setDRACOLoader(dracoLoader);

第三步就是加载gltf模型,这里使用了鼠标监听函数,然后获取相关对应的坐标,然后通过gsap进行实现动画效果,如下:

  1.  
    loader.load("./model/xz.glb", (gltf) => {
  2.  
    gltf.scene.scale.set(0.1, 0.1, 0.1);
  3.  
    gltf.scene.position.set(3, 0, 0);
  4.  
    scene.add(gltf.scene);
  5.  
    window.addEventListener("mousemove", (e) => {
  6.  
    let x = (e.clientX / window.innerWidth) * 2 - 1;
  7.  
    let y = (e.clientY / window.innerHeight) * 2 - 1;
  8.  
     
  9.  
    let timeline = gsap.timeline();
  10.  
    timeline.to(gltf.scene.rotation, {
  11.  
    duration: 0.5,
  12.  
    x: y,
  13.  
    y: x,
  14.  
    duration: 1,
  15.  
    });
  16.  
    });
  17.  
    });
学新通

第四步就是根据具体情况添加光源:

  1.  
    // 添加灯光
  2.  
    let light = new THREE.DirectionalLight(0xffffff, 0.7);
  3.  
    light.position.set(0, 0, 1);
  4.  
    scene.add(light);
  5.  
    let light2 = new THREE.DirectionalLight(0xffffff, 0.3);
  6.  
    light2.position.set(0, 0, -1);
  7.  
    scene.add(light2);
  8.  
    let light3 = new THREE.AmbientLight(0xffffff, 0.3);
  9.  
    light3.position.set(-1, 1, 1);
  10.  
    scene.add(light3);

学新通

实现滚轮滑动切换3D场景

因为我在html设置了三个div进行页面切换如下:

学新通

所以我们需要引入3个glb模型,和上面引入模型的方式一样:

  1.  
    loader.load("./model/xq6.glb", (gltf) => {
  2.  
    gltf.scene.scale.set(0.05, 0.05, 0.05);
  3.  
    gltf.scene.position.set(3, -8, 0);
  4.  
    scene.add(gltf.scene);
  5.  
    window.addEventListener("mousemove", (e) => {
  6.  
    let x = (e.clientX / window.innerWidth) * 2 - 1;
  7.  
    let y = (e.clientY / window.innerHeight) * 2 - 1;
  8.  
    let timeline = gsap.timeline();
  9.  
    timeline.to(gltf.scene.rotation, {
  10.  
    duration: 0.5,
  11.  
    x: y,
  12.  
    y: x,
  13.  
    duration: 1,
  14.  
    });
  15.  
    });
  16.  
    });
  17.  
     
  18.  
    loader.load("./model/gr75.glb", (gltf) => {
  19.  
    gltf.scene.scale.set(0.8, 0.8, 0.8);
  20.  
    gltf.scene.position.set(3, -16, 0);
  21.  
    scene.add(gltf.scene);
  22.  
    window.addEventListener("mousemove", (e) => {
  23.  
    let x = (e.clientX / window.innerWidth) * 2 - 1;
  24.  
    let y = (e.clientY / window.innerHeight) * 2 - 1;
  25.  
    let timeline = gsap.timeline();
  26.  
    timeline.to(gltf.scene.rotation, {
  27.  
    duration: 0.5,
  28.  
    x: y,
  29.  
    y: x,
  30.  
    duration: 1,
  31.  
    });
  32.  
    });
  33.  
    });
学新通

接下来通过监听鼠标滚轮事件来实现page的动态改变:

  1.  
    let page = 0;
  2.  
    let timeline2 = gsap.timeline();
  3.  
    window.addEventListener("mousewheel", (e) => {
  4.  
    if (e.wheelDelta < 0) {
  5.  
    page ;
  6.  
    if (page > 2) {
  7.  
    page = 2;
  8.  
    }
  9.  
    }
  10.  
    if (e.wheelDelta > 0) {
  11.  
    page--;
  12.  
    if (page < 0) {
  13.  
    page = 0;
  14.  
    }
  15.  
    }
  16.  
    if (!timeline2.isActive()) {
  17.  
    timeline2.to(camera.position, {
  18.  
    duration: 0.5,
  19.  
    y: page * -8,
  20.  
    duration: 1,
  21.  
    });
  22.  
    gsap.to(pages.value, {
  23.  
    duration: 1,
  24.  
    y: -page * window.innerHeight,
  25.  
    duration: 1,
  26.  
    });
  27.  
    }
  28.  
    });
学新通

学新通

设置星光流动特效

这里通过加载月球模型,实现星光流动的效果,InstancedMesh是一种在Three.js等WebGL引擎中使用的渲染技术,它允许我们高效地创建具有重复几何体的场景。通常在场景中有很多相同的对象,例如草丛,树木或者敌人等,而这些对象实际上是几何体和材质的组合。

  1.  
    loader.load("./model/moon.glb", (gltf) => {
  2.  
    let moon = gltf.scene.children[0];
  3.  
    for (let j = 0; j < 10; j ) {
  4.  
    let moonInstance = new THREE.InstancedMesh(
  5.  
    moon.geometry,
  6.  
    moon.material,
  7.  
    100
  8.  
    );
  9.  
    for (let i = 0; i < 100; i ) {
  10.  
    let x = Math.random() * 1000 - 500;
  11.  
    let y = Math.random() * 1000 - 500;
  12.  
    let z = Math.random() * 1000 - 500;
  13.  
     
  14.  
    let matrix = new THREE.Matrix4();
  15.  
    let size = Math.random() * 20 - 8;
  16.  
    matrix.makeScale(size, size, size);
  17.  
    matrix.makeTranslation(x, y, z);
  18.  
    moonInstance.setMatrixAt(i, matrix);
  19.  
    }
  20.  
     
  21.  
    gsap.to(moonInstance.position, {
  22.  
    duration: Math.random() * 10 2,
  23.  
    z: -1000,
  24.  
    ease: "linear",
  25.  
    repeat: -1,
  26.  
    });
  27.  
    scene.add(moonInstance);
  28.  
    }
  29.  
    });
学新通

学新通

demo做完,给出本案例的完整代码:(获取素材也可以私信博主)

  1.  
    <template>
  2.  
    <div class="home">
  3.  
    <div class="canvas-container" ref="screenDom"></div>
  4.  
    <div class="header">
  5.  
    <div class="menu">
  6.  
    <a href="#" class="menuItem">首页</a>
  7.  
    <a href="#" class="menuItem">详情</a>
  8.  
    <a href="#" class="menuItem">关于</a>
  9.  
    </div>
  10.  
    </div>
  11.  
    <div class="pages" ref="pages">
  12.  
    <div class="page">
  13.  
    <h2 class="title">前端技术</h2>
  14.  
    <p>轻松、好玩、有趣掌握前沿硬核前端技术</p>
  15.  
    </div>
  16.  
    <div class="page">
  17.  
    <h2 class="title">WEB 3D可视化</h2>
  18.  
    <p>领略WEB 3D的魅力,让页面无比酷炫</p>
  19.  
    </div>
  20.  
    <div class="page">
  21.  
    <h2 class="title">ThreeJS框架</h2>
  22.  
    <p>让前端开发3D效果更方便</p>
  23.  
    </div>
  24.  
    </div>
  25.  
    </div>
  26.  
    </template>
  27.  
     
  28.  
    <script setup>
  29.  
    import * as THREE from "three";
  30.  
    import { ref, onMounted } from "vue";
  31.  
    import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
  32.  
    import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader";
  33.  
    import { gsap } from "gsap";
  34.  
    let screenDom = ref(null);
  35.  
    let pages = ref(null);
  36.  
     
  37.  
    // 创建场景
  38.  
    let scene = new THREE.Scene();
  39.  
    // 创建相机
  40.  
    let camera = new THREE.PerspectiveCamera(45,window.innerWidth / window.innerHeight,0.1,100000);
  41.  
    camera.position.set(0, 0, 10);
  42.  
     
  43.  
    // 创建渲染器
  44.  
    let renderer = new THREE.WebGLRenderer({ antialias: true });
  45.  
    renderer.setSize(window.innerWidth, window.innerHeight);
  46.  
     
  47.  
    window.addEventListener("resize",()=>{
  48.  
    renderer.setSize(window.innerWidth,window.innerHeight)
  49.  
    camera.aspect = window.innerWidth/window.innerHeight
  50.  
    camera.updateProjectionMatrix()
  51.  
    })
  52.  
     
  53.  
    // 创建渲染函数
  54.  
    const render = () => {
  55.  
    requestAnimationFrame(render);
  56.  
    renderer.render(scene, camera);
  57.  
    }
  58.  
    render();
  59.  
     
  60.  
    onMounted(() => {
  61.  
    // 将画布添加到页面中
  62.  
    screenDom.value.appendChild(renderer.domElement);
  63.  
    render()
  64.  
    });
  65.  
     
  66.  
    // 创建星空的背景
  67.  
    let url = "src/assets/imgs/25s.jpg";
  68.  
    let envTexture = new THREE.TextureLoader().load(url);
  69.  
    envTexture.mapping = THREE.EquirectangularReflectionMapping;
  70.  
    scene.background = envTexture;
  71.  
    scene.environment = envTexture;
  72.  
     
  73.  
    // 设置解压缩的加载器
  74.  
    let dracoLoader = new DRACOLoader();
  75.  
    dracoLoader.setDecoderPath("./draco/gltf/");
  76.  
    dracoLoader.setDecoderConfig({ type: "js" });
  77.  
    let loader = new GLTFLoader();
  78.  
    loader.setDRACOLoader(dracoLoader);
  79.  
    loader.load("./model/xz.glb", (gltf) => {
  80.  
    gltf.scene.scale.set(0.1, 0.1, 0.1);
  81.  
    gltf.scene.position.set(3, 0, 0);
  82.  
    scene.add(gltf.scene);
  83.  
    window.addEventListener("mousemove", (e) => {
  84.  
    let x = (e.clientX / window.innerWidth) * 2 - 1;
  85.  
    let y = (e.clientY / window.innerHeight) * 2 - 1;
  86.  
     
  87.  
    let timeline = gsap.timeline();
  88.  
    timeline.to(gltf.scene.rotation, {
  89.  
    duration: 0.5,
  90.  
    x: y,
  91.  
    y: x,
  92.  
    duration: 1,
  93.  
    });
  94.  
    });
  95.  
    });
  96.  
     
  97.  
    // 添加灯光
  98.  
    let light = new THREE.DirectionalLight(0xffffff, 0.7);
  99.  
    light.position.set(0, 0, 1);
  100.  
    scene.add(light);
  101.  
    let light2 = new THREE.DirectionalLight(0xffffff, 0.3);
  102.  
    light2.position.set(0, 0, -1);
  103.  
    scene.add(light2);
  104.  
    let light3 = new THREE.AmbientLight(0xffffff, 0.3);
  105.  
    light3.position.set(-1, 1, 1);
  106.  
    scene.add(light3);
  107.  
     
  108.  
    loader.load("./model/xq6.glb", (gltf) => {
  109.  
    gltf.scene.scale.set(0.05, 0.05, 0.05);
  110.  
    gltf.scene.position.set(3, -8, 0);
  111.  
    scene.add(gltf.scene);
  112.  
    window.addEventListener("mousemove", (e) => {
  113.  
    let x = (e.clientX / window.innerWidth) * 2 - 1;
  114.  
    let y = (e.clientY / window.innerHeight) * 2 - 1;
  115.  
    let timeline = gsap.timeline();
  116.  
    timeline.to(gltf.scene.rotation, {
  117.  
    duration: 0.5,
  118.  
    x: y,
  119.  
    y: x,
  120.  
    duration: 1,
  121.  
    });
  122.  
    });
  123.  
    });
  124.  
     
  125.  
    loader.load("./model/gr75.glb", (gltf) => {
  126.  
    gltf.scene.scale.set(0.8, 0.8, 0.8);
  127.  
    gltf.scene.position.set(3, -16, 0);
  128.  
    scene.add(gltf.scene);
  129.  
    window.addEventListener("mousemove", (e) => {
  130.  
    let x = (e.clientX / window.innerWidth) * 2 - 1;
  131.  
    let y = (e.clientY / window.innerHeight) * 2 - 1;
  132.  
    let timeline = gsap.timeline();
  133.  
    timeline.to(gltf.scene.rotation, {
  134.  
    duration: 0.5,
  135.  
    x: y,
  136.  
    y: x,
  137.  
    duration: 1,
  138.  
    });
  139.  
    });
  140.  
    });
  141.  
     
  142.  
    let page = 0;
  143.  
    let timeline2 = gsap.timeline();
  144.  
    window.addEventListener("mousewheel", (e) => {
  145.  
    if (e.wheelDelta < 0) {
  146.  
    page ;
  147.  
    if (page > 2) {
  148.  
    page = 2;
  149.  
    }
  150.  
    }
  151.  
    if (e.wheelDelta > 0) {
  152.  
    page--;
  153.  
    if (page < 0) {
  154.  
    page = 0;
  155.  
    }
  156.  
    }
  157.  
    if (!timeline2.isActive()) {
  158.  
    timeline2.to(camera.position, {
  159.  
    duration: 0.5,
  160.  
    y: page * -8,
  161.  
    duration: 1,
  162.  
    });
  163.  
    gsap.to(pages.value, {
  164.  
    duration: 1,
  165.  
    y: -page * window.innerHeight,
  166.  
    duration: 1,
  167.  
    });
  168.  
    }
  169.  
    });
  170.  
     
  171.  
    loader.load("./model/moon.glb", (gltf) => {
  172.  
    let moon = gltf.scene.children[0];
  173.  
    for (let j = 0; j < 10; j ) {
  174.  
    let moonInstance = new THREE.InstancedMesh(
  175.  
    moon.geometry,
  176.  
    moon.material,
  177.  
    100
  178.  
    );
  179.  
    for (let i = 0; i < 100; i ) {
  180.  
    let x = Math.random() * 1000 - 500;
  181.  
    let y = Math.random() * 1000 - 500;
  182.  
    let z = Math.random() * 1000 - 500;
  183.  
     
  184.  
    let matrix = new THREE.Matrix4();
  185.  
    let size = Math.random() * 20 - 8;
  186.  
    matrix.makeScale(size, size, size);
  187.  
    matrix.makeTranslation(x, y, z);
  188.  
    moonInstance.setMatrixAt(i, matrix);
  189.  
    }
  190.  
     
  191.  
    gsap.to(moonInstance.position, {
  192.  
    duration: Math.random() * 10 2,
  193.  
    z: -1000,
  194.  
    ease: "linear",
  195.  
    repeat: -1,
  196.  
    });
  197.  
    scene.add(moonInstance);
  198.  
    }
  199.  
    });
  200.  
     
  201.  
    </script>
  202.  
     
  203.  
    <style>
  204.  
    * {
  205.  
    margin: 0;
  206.  
    padding: 0;
  207.  
    }
  208.  
    body {
  209.  
    background-color: #000;
  210.  
    }
  211.  
    .canvas-container {
  212.  
    width: 100vw;
  213.  
    height: 100vh;
  214.  
    }
  215.  
    .home {
  216.  
    width: 100vw;
  217.  
    height: 100vh;
  218.  
    transform-origin: 0 0;
  219.  
    }
  220.  
    .header {
  221.  
    position: fixed;
  222.  
    top: 0;
  223.  
    left: 0;
  224.  
    width: 100vw;
  225.  
    height: 100px;
  226.  
    display: flex;
  227.  
    justify-content: space-between;
  228.  
    align-items: center;
  229.  
    }
  230.  
    .canvas-container {
  231.  
    width: 100%;
  232.  
    height: 100%;
  233.  
    }
  234.  
    .menu {
  235.  
    display: flex;
  236.  
    justify-content: space-between;
  237.  
    align-items: center;
  238.  
    margin-right: 50px;
  239.  
    }
  240.  
    .menuItem {
  241.  
    padding: 0 15px;
  242.  
    text-decoration: none;
  243.  
    color: #fff;
  244.  
    font-weight: 900;
  245.  
    font-size: 15px;
  246.  
    }
  247.  
    .progress {
  248.  
    position: fixed;
  249.  
    top: 0;
  250.  
    left: 0;
  251.  
    width: 100vw;
  252.  
    height: 100vh;
  253.  
    z-index: 101;
  254.  
    display: flex;
  255.  
    justify-content: center;
  256.  
    align-items: center;
  257.  
    font-size: 20px;
  258.  
    color: #fff;
  259.  
    }
  260.  
    .progress > img {
  261.  
    padding: 0 15px;
  262.  
    }
  263.  
    .pages {
  264.  
    display: flex;
  265.  
    flex-direction: column;
  266.  
    position: fixed;
  267.  
    top: 0;
  268.  
    left: 0;
  269.  
    }
  270.  
    .pages .page {
  271.  
    width: 100vw;
  272.  
    height: 100vh;
  273.  
    display: flex;
  274.  
    flex-direction: column;
  275.  
    justify-content: center;
  276.  
    align-items: flex-start;
  277.  
    color: #fff;
  278.  
    padding: 15%;
  279.  
    box-sizing: border-box;
  280.  
    }
  281.  
    .pages .page .title {
  282.  
    font-size: 50px;
  283.  
    font-weight: 900;
  284.  
    margin-bottom: 20px;
  285.  
    }
  286.  
    .pages .page p {
  287.  
    font-size: 25px;
  288.  
    }
  289.  
    </style>
学新通

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgffjhe
系列文章
更多 icon
同类精品
更多 icon
继续加载