feat: 添加SegmentFault container, home container 内容修改.
This commit is contained in:
parent
6cfcf62d7f
commit
7565508e4f
|
|
@ -9,6 +9,7 @@ import Cell from './containers/Cell/index';
|
|||
import Car from './containers/Car/index';
|
||||
import Zelda from './containers/Zelda/index';
|
||||
import Metaverse from './containers/Metaverse/index';
|
||||
import SegmentFault from './containers/SegmentFault/index';
|
||||
|
||||
function App() {
|
||||
return (
|
||||
|
|
@ -24,6 +25,7 @@ function App() {
|
|||
<Route element={ <Car /> } path="/car" />
|
||||
<Route element={ <Zelda /> } path="/zelda" />
|
||||
<Route element={ <Metaverse /> } path="/metaverse" />
|
||||
<Route element={ <SegmentFault /> } path="/segmentfault" />
|
||||
</Routes>
|
||||
</Router>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ import { TWEEN } from "three/examples/jsm/libs/tween.module.min.js";
|
|||
const Animations = {
|
||||
//相机移动实现漫游等动画
|
||||
animateCamera: (camera, controls, newP, newT, time = 2000, callBack) => {
|
||||
console.log(camera, controls, newP, newT)
|
||||
var tween = new TWEEN.Tween({
|
||||
x1: camera.position.x, // 相机x
|
||||
y1: camera.position.y, // 相机y
|
||||
|
|
@ -12,7 +11,6 @@ const Animations = {
|
|||
y2: controls.target.y, // 控制点的中心点y
|
||||
z2: controls.target.z, // 控制点的中心点z
|
||||
});
|
||||
console.log(tween)
|
||||
tween.to({
|
||||
x1: newP.x,
|
||||
y1: newP.y,
|
||||
|
|
@ -34,7 +32,6 @@ const Animations = {
|
|||
});
|
||||
tween.onComplete(function () {
|
||||
controls.enabled = true;
|
||||
console.log('complete')
|
||||
callBack();
|
||||
});
|
||||
tween.easing(TWEEN.Easing.Cubic.InOut);
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 5.3 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 132 KiB |
|
|
@ -14,6 +14,8 @@ import zeldaImage from './images/zelda.png';
|
|||
import zeldaMapImage from './images/zelda_map.png';
|
||||
import scanImage from './images/scan.png';
|
||||
import carImage from './images/car.png';
|
||||
import developingImage from './images/developing.png';
|
||||
import segmentFaultImage from './images/segmengfault.png';
|
||||
import './index.css';
|
||||
|
||||
const Item = styled(Paper)(({ theme }) => ({
|
||||
|
|
@ -45,6 +47,20 @@ const workList = [
|
|||
image: panoramicImage,
|
||||
three: true
|
||||
},
|
||||
{
|
||||
link: '#/lunar',
|
||||
title: '虎年春节创意',
|
||||
description: '🐅 2022虎虎生威!',
|
||||
image: lunarImage,
|
||||
three: true
|
||||
},
|
||||
{
|
||||
link: '#/segmentfault',
|
||||
title: 'SegmentFault突破1000粉纪念',
|
||||
description: '🏆 1000+ followers !',
|
||||
image: segmentFaultImage,
|
||||
three: true
|
||||
},
|
||||
{
|
||||
link: '#/earth',
|
||||
title: '地球',
|
||||
|
|
@ -59,13 +75,6 @@ const workList = [
|
|||
image: cellImage,
|
||||
three: true
|
||||
},
|
||||
{
|
||||
link: '#/lunar',
|
||||
title: '虎年春节创意',
|
||||
description: '🐅 2022虎虎生威!',
|
||||
image: lunarImage,
|
||||
three: true
|
||||
},
|
||||
{
|
||||
link: 'https://dragonir.github.io/zelda-map/',
|
||||
title: '塞尔达:旷野之息地图',
|
||||
|
|
@ -91,6 +100,34 @@ const workList = [
|
|||
description: '📷 林克',
|
||||
image: zeldaImage,
|
||||
three: true
|
||||
},
|
||||
{
|
||||
link: '#/',
|
||||
title: '远航:无尽的拉格朗日',
|
||||
description: '开发中...',
|
||||
image: developingImage,
|
||||
three: true
|
||||
},
|
||||
{
|
||||
link: '#/',
|
||||
title: '探索:无人深空',
|
||||
description: '开发中...',
|
||||
image: developingImage,
|
||||
three: true
|
||||
},
|
||||
{
|
||||
link: '#/',
|
||||
title: '着陆:失落的星球',
|
||||
description: '开发中...',
|
||||
image: developingImage,
|
||||
three: true
|
||||
},
|
||||
{
|
||||
link: '#/',
|
||||
title: '航巡:迷失在黑洞',
|
||||
description: '开发中...',
|
||||
image: developingImage,
|
||||
three: true
|
||||
}
|
||||
];
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,2 @@
|
|||
https://cpetry.github.io/NormalMap-Online/
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 202 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 65 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 127 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 61 KiB |
|
|
@ -0,0 +1,195 @@
|
|||
.segment_fault_page {
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
-o-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
.segment_fault_loading {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 100vh;
|
||||
width: 100vw;
|
||||
background: #00c6ff;
|
||||
background: -webkit-linear-gradient(to right, #0072ff, #00c6ff);
|
||||
background: linear-gradient(to right, #0072ff, #00c6ff);
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
font-size: 64px;
|
||||
color: #FFFFFF;
|
||||
text-shadow: 0 1px 0 hsl(174, 5%, 80%),
|
||||
0 2px 0 hsl(174, 5%, 75%),
|
||||
0 3px 0 hsl(174, 5%, 70%),
|
||||
0 4px 0 hsl(174, 5%, 66%),
|
||||
0 5px 0 hsl(174, 5%, 64%),
|
||||
0 6px 0 hsl(174, 5%, 62%),
|
||||
0 7px 0 hsl(174, 5%, 61%),
|
||||
0 8px 0 hsl(174, 5%, 60%),
|
||||
0 0 5px rgba(0, 0, 0, .05),
|
||||
0 1px 3px rgba(0, 0, 0, .2),
|
||||
0 3px 5px rgba(0, 0, 0, .2),
|
||||
0 5px 10px rgba(0, 0, 0, .2),
|
||||
0 10px 10px rgba(0, 0, 0, .2),
|
||||
0 20px 20px rgba(0, 0, 0, .3);
|
||||
}
|
||||
[class^=firework_] {
|
||||
position: absolute;
|
||||
width: 0.1rem;
|
||||
height: 0.1rem;
|
||||
border-radius: 50%;
|
||||
transform: scale(8)
|
||||
}
|
||||
.firework_1 {
|
||||
-webkit-animation: firework_lg 2s both infinite;
|
||||
animation: firework_lg 2s both infinite;
|
||||
-webkit-animation-delay: 0.3s;
|
||||
animation-delay: 0.3s;
|
||||
top: 5%;
|
||||
left: 5%;
|
||||
}
|
||||
.firework_2 {
|
||||
-webkit-animation: firework_md 2.5s both infinite;
|
||||
animation: firework_md 2.5s both infinite;
|
||||
-webkit-animation-delay: 1.1s;
|
||||
animation-delay: 1.1s;
|
||||
top: 8%;
|
||||
left: 90%;
|
||||
}
|
||||
.firework_3 {
|
||||
-webkit-animation: firework_lg 2s both infinite;
|
||||
animation: firework_lg 2s both infinite;
|
||||
-webkit-animation-delay: 0.3s;
|
||||
animation-delay: 0.3s;
|
||||
top: 95%;
|
||||
left: 95%;
|
||||
}
|
||||
.firework_4 {
|
||||
-webkit-animation: firework_md 2.5s both infinite;
|
||||
animation: firework_md 2.5s both infinite;
|
||||
-webkit-animation-delay: 0.4s;
|
||||
animation-delay: 0.4s;
|
||||
top: 90%;
|
||||
left: 10%;
|
||||
}
|
||||
.firework_5 {
|
||||
-webkit-animation: firework_md 2.5s both infinite;
|
||||
animation: firework_md 2.5s both infinite;
|
||||
-webkit-animation-delay: 0.9s;
|
||||
animation-delay: 0.9s;
|
||||
top: 15%;
|
||||
left: 70%;
|
||||
}
|
||||
.firework_6 {
|
||||
-webkit-animation: firework_sm 2.5s both infinite;
|
||||
animation: firework_sm 2.5s both infinite;
|
||||
-webkit-animation-delay: 1.3s;
|
||||
animation-delay: 1.3s;
|
||||
top: 95%;
|
||||
left: 45%;
|
||||
}
|
||||
.firework_7 {
|
||||
-webkit-animation: firework_md 2.5s both infinite;
|
||||
animation: firework_md 2.5s both infinite;
|
||||
-webkit-animation-delay: 0.5s;
|
||||
animation-delay: 0.5s;
|
||||
top: 95%;
|
||||
left: 70%;
|
||||
}
|
||||
.firework_8 {
|
||||
-webkit-animation: firework_sm 2.5s both infinite;
|
||||
animation: firework_sm 2.5s both infinite;
|
||||
-webkit-animation-delay: 0.8s;
|
||||
animation-delay: 0.8s;
|
||||
top: 10%;
|
||||
left: 40%;
|
||||
}
|
||||
.firework_9 {
|
||||
-webkit-animation: firework_sm 2.5s both infinite;
|
||||
animation: firework_sm 2.5s both infinite;
|
||||
-webkit-animation-delay: 0.3s;
|
||||
animation-delay: 0.3s;
|
||||
top: 40%;
|
||||
left: 90%;
|
||||
}
|
||||
.firework_10 {
|
||||
-webkit-animation: firework_lg 2.5s both infinite;
|
||||
animation: firework_lg 2.5s both infinite;
|
||||
-webkit-animation-delay: 0.8s;
|
||||
animation-delay: 0.8s;
|
||||
top: 35%;
|
||||
left: 5%;
|
||||
}
|
||||
@-webkit-keyframes firework_sm {
|
||||
0%, 100% {
|
||||
opacity: 0;
|
||||
}
|
||||
10%, 70% {
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
box-shadow: -0.5rem 0rem 0 #fffc00, 0.5rem 0rem 0 #fffc00, 0rem -0.5rem 0 #fffc00, 0rem 0.5rem 0 #fffc00, 0.35rem -0.35rem 0 #fffc00, 0.35rem 0.35rem 0 #fffc00, -0.35rem -0.35rem 0 #fffc00, -0.35rem 0.35rem 0 #fffc00;
|
||||
}
|
||||
}
|
||||
@keyframes firework_sm {
|
||||
0%, 100% {
|
||||
opacity: 0;
|
||||
}
|
||||
10%, 70% {
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
box-shadow: -0.5rem 0rem 0 #fffc00, 0.5rem 0rem 0 #fffc00, 0rem -0.5rem 0 #fffc00, 0rem 0.5rem 0 #fffc00, 0.35rem -0.35rem 0 #fffc00, 0.35rem 0.35rem 0 #fffc00, -0.35rem -0.35rem 0 #fffc00, -0.35rem 0.35rem 0 #fffc00;
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes firework_md {
|
||||
0%, 100% {
|
||||
opacity: 0;
|
||||
}
|
||||
10%, 70% {
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
box-shadow: -0.7rem 0rem 0 #fff, 0.7rem 0rem 0 #fff, 0rem -0.7rem 0 #fff, 0rem 0.7rem 0 #fff, 0.49rem -0.49rem 0 #fff, 0.49rem 0.49rem 0 #fff, -0.49rem -0.49rem 0 #fff, -0.49rem 0.49rem 0 #fff;
|
||||
}
|
||||
}
|
||||
@keyframes firework_md {
|
||||
0%, 100% {
|
||||
opacity: 0;
|
||||
}
|
||||
10%, 70% {
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
box-shadow: -0.7rem 0rem 0 #fff, 0.7rem 0rem 0 #fff, 0rem -0.7rem 0 #fff, 0rem 0.7rem 0 #fff, 0.49rem -0.49rem 0 #fff, 0.49rem 0.49rem 0 #fff, -0.49rem -0.49rem 0 #fff, -0.49rem 0.49rem 0 #fff;
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes firework_lg {
|
||||
0%, 100% {
|
||||
opacity: 0;
|
||||
}
|
||||
10%, 70% {
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
box-shadow: -0.9rem 0rem 0 #fff, 0.9rem 0rem 0 #fff, 0rem -0.9rem 0 #fff, 0rem 0.9rem 0 #fff, 0.63rem -0.63rem 0 #fff, 0.63rem 0.63rem 0 #fff, -0.63rem -0.63rem 0 #fff, -0.63rem 0.63rem 0 #fff;
|
||||
}
|
||||
}
|
||||
@keyframes firework_lg {
|
||||
0%, 100% {
|
||||
opacity: 0;
|
||||
}
|
||||
10%, 70% {
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
box-shadow: -0.9rem 0rem 0 #fff, 0.9rem 0rem 0 #fff, 0rem -0.9rem 0 #fff, 0rem 0.9rem 0 #fff, 0.63rem -0.63rem 0 #fff, 0.63rem 0.63rem 0 #fff, -0.63rem -0.63rem 0 #fff, -0.63rem 0.63rem 0 #fff;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,187 @@
|
|||
import React from 'react';
|
||||
import * as THREE from "three";
|
||||
import { FBXLoader } from "three/examples/jsm/loaders/FBXLoader";
|
||||
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
|
||||
import { TWEEN } from "three/examples/jsm/libs/tween.module.min.js";
|
||||
import Stats from "three/examples/jsm/libs/stats.module";
|
||||
import textModel from './models/text.fbx';
|
||||
import segmentTexture from './images/texture.png';
|
||||
import normalMapTexture from './images/normalMap.png';
|
||||
import metalTexture from './images/metal.png';
|
||||
import backgroundTexture from './images/bg.webp';
|
||||
import Animations from '../../assets/utils/animations';
|
||||
import './index.css';
|
||||
|
||||
export default class SegmentFault extends React.Component {
|
||||
|
||||
state = {
|
||||
loadingProcess: 0
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.initThree();
|
||||
}
|
||||
|
||||
initThree = () => {
|
||||
var container, controls, stats;
|
||||
var camera, scene, renderer, light, box = null, meshes = [];
|
||||
var _this = this;
|
||||
init();
|
||||
animate();
|
||||
function init() {
|
||||
container = document.getElementById('container');
|
||||
renderer = new THREE.WebGLRenderer({ antialias: true });
|
||||
renderer.setPixelRatio(window.devicePixelRatio);
|
||||
renderer.setSize(window.innerWidth, window.innerHeight);
|
||||
renderer.shadowMap.enabled = true;
|
||||
renderer.shadowMap.needsUpdate = true;
|
||||
container.appendChild(renderer.domElement);
|
||||
|
||||
scene = new THREE.Scene();
|
||||
scene.background = new THREE.TextureLoader().load(backgroundTexture);
|
||||
camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 1000);
|
||||
camera.position.set(0, 0, 0);
|
||||
camera.lookAt(new THREE.Vector3(0, 0, 0));
|
||||
|
||||
// 直射光
|
||||
const cubeGeometry = new THREE.BoxGeometry(0.001, 0.001, 0.001);
|
||||
const cubeMaterial = new THREE.MeshLambertMaterial({ color: 0xffffff });
|
||||
const cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
|
||||
cube.position.set(0, 0, 0);
|
||||
light = new THREE.DirectionalLight(0xffffff, 1);
|
||||
light.intensity = 1;
|
||||
light.position.set(18, 20, 60);
|
||||
light.castShadow = true;
|
||||
light.target = cube;
|
||||
light.shadow.mapSize.width = 512 * 12;
|
||||
light.shadow.mapSize.height = 512 * 12;
|
||||
light.shadow.camera.top = 80;
|
||||
light.shadow.camera.bottom = -80;
|
||||
light.shadow.camera.left = -80;
|
||||
light.shadow.camera.right = 80;
|
||||
scene.add(light);
|
||||
// 半球光
|
||||
const ambientLight = new THREE.AmbientLight(0xffffff);
|
||||
ambientLight.intensity = .8;
|
||||
scene.add(ambientLight);
|
||||
// 环境光
|
||||
const hemisphereLight = new THREE.HemisphereLight(0xffffff, 0xfffc00);
|
||||
hemisphereLight.intensity = .3;
|
||||
scene.add(hemisphereLight);
|
||||
|
||||
controls = new OrbitControls(camera, renderer.domElement);
|
||||
controls.target.set(0, 0, 0);
|
||||
controls.enableDamping = true;
|
||||
controls.enableZoom = false;
|
||||
controls.enablePan = false;
|
||||
controls.rotateSpeed = .2;
|
||||
window.addEventListener('resize', onWindowResize, false);
|
||||
|
||||
// 性能工具
|
||||
stats = new Stats();
|
||||
// document.documentElement.appendChild(stats.dom);
|
||||
|
||||
// 网格
|
||||
const grid = new THREE.GridHelper(200, 200, 0xffffff, 0xffffff);
|
||||
grid.position.set(0, -30, -50);
|
||||
grid.material.transparent = true;
|
||||
grid.material.opacity = 0.1;
|
||||
scene.add(grid);
|
||||
|
||||
// 创建地面
|
||||
var planeGeometry = new THREE.PlaneGeometry(200, 200);
|
||||
// 透明材质显示阴影
|
||||
var planeMaterial = new THREE.ShadowMaterial({ opacity: .5 });
|
||||
var plane = new THREE.Mesh(planeGeometry, planeMaterial);
|
||||
plane.rotation.x = -0.5 * Math.PI;
|
||||
plane.position.set(0, -30, -50);
|
||||
plane.receiveShadow = true;
|
||||
scene.add(plane);
|
||||
|
||||
// 添加自定义模型
|
||||
let segmentMap = new THREE.MeshPhysicalMaterial({map: new THREE.TextureLoader().load(segmentTexture), normalMap: new THREE.TextureLoader().load(normalMapTexture) });
|
||||
let metalMap = new THREE.MeshPhysicalMaterial({map: new THREE.TextureLoader().load(metalTexture)});
|
||||
//创建纹理数组
|
||||
const boxMaps = [metalMap, metalMap, metalMap, metalMap, segmentMap, segmentMap];
|
||||
box = new THREE.Mesh(new THREE.BoxGeometry(297, 456, 12), boxMaps);
|
||||
box.material.map(item => {
|
||||
item.metalness = .5;
|
||||
item.roughness = .4;
|
||||
item.refractionRatio = 1;
|
||||
return item;
|
||||
});
|
||||
box.scale.set(0.085, 0.085, 0.085);
|
||||
box.position.set(-22, 2, 0);
|
||||
box.castShadow = true;
|
||||
meshes.push(box);
|
||||
scene.add(box);
|
||||
|
||||
// 加载文字模型
|
||||
const manager = new THREE.LoadingManager();
|
||||
manager.onProgress = async(url, loaded, total) => {
|
||||
if (Math.floor(loaded / total * 100) === 100) {
|
||||
_this.loadingProcessTimeout && clearTimeout(_this.loadingProcessTimeout);
|
||||
_this.loadingProcessTimeout = setTimeout(() => {
|
||||
_this.setState({ loadingProcess: Math.floor(loaded / total * 100) });
|
||||
Animations.animateCamera(camera, controls, { x: 0, y: 4, z: 60 }, { x: 0, y: 0, z: 0 }, 3600, () => {});
|
||||
}, 800);
|
||||
} else {
|
||||
_this.setState({ loadingProcess: Math.floor(loaded / total * 100) });
|
||||
}
|
||||
};
|
||||
const fbxLoader = new FBXLoader(manager);
|
||||
fbxLoader.load(textModel, mesh => {
|
||||
mesh.traverse(child => {
|
||||
if (child.isMesh) {
|
||||
child.castShadow = true;
|
||||
child.material.metalness = 1;
|
||||
child.material.roughness = .2;
|
||||
meshes.push(mesh);
|
||||
}
|
||||
});
|
||||
mesh.position.set(16, -4, 0);
|
||||
mesh.rotation.x = Math.PI / 2
|
||||
mesh.scale.set(.08, .08, .08);
|
||||
scene.add(mesh);
|
||||
});
|
||||
}
|
||||
|
||||
function onWindowResize() {
|
||||
camera.aspect = window.innerWidth / window.innerHeight;
|
||||
camera.updateProjectionMatrix();
|
||||
renderer.setSize(window.innerWidth, window.innerHeight);
|
||||
}
|
||||
|
||||
function animate() {
|
||||
requestAnimationFrame(animate);
|
||||
renderer.render(scene, camera);
|
||||
stats && stats.update();
|
||||
controls && controls.update();
|
||||
TWEEN && TWEEN.update();
|
||||
box && (box.rotation.y += .04);
|
||||
}
|
||||
}
|
||||
|
||||
render () {
|
||||
return (
|
||||
<div className="segment_fault_page">
|
||||
<div id="container"></div>
|
||||
{this.state.loadingProcess === 100 ? '' : (
|
||||
<div className="segment_fault_loading">
|
||||
<div className="box">{this.state.loadingProcess} %</div>
|
||||
</div>
|
||||
)}
|
||||
<div className="firework_1"></div>
|
||||
<div className="firework_2"></div>
|
||||
<div className="firework_3"></div>
|
||||
<div className="firework_4"></div>
|
||||
<div className="firework_5"></div>
|
||||
<div className="firework_6"></div>
|
||||
<div className="firework_7"></div>
|
||||
<div className="firework_8"></div>
|
||||
<div className="firework_9"></div>
|
||||
<div className="firework_10"></div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
|
@ -9,7 +9,6 @@ import linkModel from './models/link.fbx';
|
|||
import Animations from '../../assets/utils/animations';
|
||||
import './index.css';
|
||||
import bgImage from './images/bg.jpg';
|
||||
import { Color } from 'three';
|
||||
|
||||
export default class Zelda extends React.Component {
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue