feat: 添加SegmentFault container, home container 内容修改.

This commit is contained in:
dragonir 2022-01-19 15:50:34 +08:00
parent 6cfcf62d7f
commit 7565508e4f
15 changed files with 430 additions and 11 deletions

View File

@ -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>

View File

@ -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

View File

@ -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
}
];

View File

@ -0,0 +1,2 @@
https://cpetry.github.io/NormalMap-Online/

View File

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

View File

@ -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;
}
}

View File

@ -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.

View File

@ -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 {