当前位置:网站首页>Three. JS learning project -- 3D data visualization of anti US aggression and aid Korea
Three. JS learning project -- 3D data visualization of anti US aggression and aid Korea
2022-04-21 12:14:00 【Jedi Hongbin】
List of articles
Part of the scene



Experience address
Operation instructions video
Operation instructions
What I did ( function )
- draco analysis glb Model Process some texture requests at the same time Reduce the pressure of loading texture at one time
- Manually control the track controller lens animation
- Multi audio splicing control
- Encapsulate the animation player Control progress switching
- Animation progress controller Sync audio Analog video experience
- useContext State sharing
- Customize multi-level right-click menu Simulate native menu experience
- Idle time to load subsequent models
- Model texture & Position dynamic switching
- echart The chart uses
- Browser adaptive units vw vmax Use ( Large area use )
- Compatible with mobile browsing
- Model destruction and animation loading
- useRef Expose method multiparty calls ( A lot of use )
- css-in-js Project practice css engine styled-component
- Incomplete requests avoid impact
- Counter cleanup not performed Subtitle playing Switch during the execution of shot switching animation Subsequent functions, etc
- Click on different models to produce different effects Click on the event monitor mouse hover The style of
- …
limited
- Performance collapse For many reasons Without on-demand rendering, the frame rate on the low configuration machine is about 30 Around the frame
- The model is not fine - First modeling
- Play the animation model on the mobile phone or high brush device, and the rendering speed is the same as 60 Frame device inconsistent
Source code address
https://gitee.com/honbingitee/kmyc
Partial logic
Render on demand
controls.addEventListener('change', () => {
renderer.render(scene, camera);
});
Model loading
https://hongbin.blog.csdn.net/article/details/122594047
Animation controller
https://hongbin.blog.csdn.net/article/details/123662686
Model texture condition switching
/** * @description: Load album model Return the callback of relevant operation * @param {number} animationIndex Campaign index * @param {THREE.TextureLoader} textureLoader Texture loader * @return {XCBack} XCBack */
export async function loadXCModel(
animationIndex: number, textureLoader: THREE.TextureLoader
): Promise<XCBack> {
const gltf = await window.gltfLoader.loadAsync(xcModel);
const [model] = gltf.scene.children;
const multiple = 5;
model.position.y = 1.8 * multiple;
if (animationIndex === 1) {
model.rotateY(-Math.PI / 2);
model.rotateX(-Math.PI / 10);
model.rotateZ(Math.PI / 10);
}
const setZero = (mash: typeof model) => {
mash.scale.x = 0;
mash.scale.y = 0;
mash.scale.z = 0;
};
setZero(model);
/** * Set different textures -- Switch pictures */
const setMaterial = (mash: Object3D, url: string) => {
const texture = textureLoader.load(url);
texture.flipY = false;
texture.encoding = 3001;
//@ts-ignore
const mater = mash.material.clone(); // You can't share one material think instance.material Point to the same object
mater.map = texture;
//@ts-ignore
mash.material = mater;
};
const pictures: XCBack["models"] = [];
for (let i = 0; i < 4; i++) {
const instance = model.clone();
//hover tip
instance.userData.type = ModelType["Picture"];
instance.userData.desc = XCDesc[animationIndex]
? XCDesc[animationIndex][i]
: "";
setMaterial(
instance,
`${
process.env.REACT_APP_URL}xc/${
animationIndex}-${
i}-y.jpg`
);
if (animationIndex === 1) {
instance.position.x = (i - 1) * -5 * multiple;
instance.position.z = -14 * multiple;
} else if (animationIndex === 2) {
instance.position.x = -10 * multiple;
instance.position.z = (i - 2) * 5 * multiple;
} else {
instance.position.x = -10 * multiple;
instance.position.z = (i - 1) * 5 * multiple;
}
pictures.push(instance);
}
let timer1: number;
let count = 0;
const range = 30;
const show = () => {
if (count < range) {
pictures.forEach(item => {
item.scale.y += multiple / range;
item.scale.z += (multiple / range) * 1.8;
item.scale.x += multiple / range / 10;
});
count++;
timer1 = requestAnimationFrame(show);
}
};
const hide = () => {
pictures.forEach(setZero);
count = 0;
cancelAnimationFrame(timer1);
requestAnimationFrame(() => {
cancelAnimationFrame(timer1);
});
};
let prevIndex = animationIndex;
const toggle: XCBack["toggle"] = nextIndex => {
pictures.forEach((item, index) => {
/** * hover Show picture introduction */
item.userData.type = ModelType["Picture"];
item.userData.desc = XCDesc[nextIndex][index];
setMaterial(
item,
`${
process.env.REACT_APP_URL}xc/${
nextIndex}-${
index}-y.jpg`
);
// Rotation Angle
if (nextIndex === 1) {
if (prevIndex !== 1) {
item.rotateY(-Math.PI / 2);
item.rotateX(-Math.PI / 10);
item.rotateZ(Math.PI / 10);
}
} else {
if (prevIndex === 1) {
item.rotateY(Math.PI / 2);
item.rotateX(Math.PI / 10);
item.rotateZ(Math.PI / 10);
}
}
// Location
if (nextIndex === 1) {
item.position.x = (index - 1) * -5 * multiple;
item.position.z = -14 * multiple;
} else if (nextIndex === 2) {
item.position.x = -10 * multiple;
item.position.z = (index - 2) * 5 * multiple;
} else {
item.position.x = -10 * multiple;
item.position.z = (index - 1) * 5 * multiple;
}
});
prevIndex = nextIndex;
};
return {
show,
hide,
models: pictures,
toggle,
};
}
Model loading also requests some textures Generate progress bar
// load 10 A texture
const loadTexture = () => {
const textureLoader = new TextureLoader();
for (let i = 0; i < 10; i++) {
const index = i.toString().padStart(2, "0");
const url = `${
process.env.REACT_APP_URL}q/${
i}.jpg`;
const texture = textureLoader.load(
url,
_ => {
setProgress(timeCheck(5));
},
undefined,
err => {
console.error("load texture fail:", err);
setProgress(timeCheck(5));
}
);
texture.flipY = false;
texture.encoding = sRGBEncoding;
addTexture(index, texture);
}
};
//draco Analytical model
const dracoLoader = () => {
let prevModel = 0;
const manager = new LoadingManager();
manager.onProgress = (_, loaded, total) => {
const progress = Math.floor((loaded / total) * 100);
if (progress === 100) return setProgress(timeCheck(50 - prevModel));
prevModel += progress / 4;
setProgress(timeCheck(progress / 4));
};
// Set error message
manager.onError = setIsLoadFail;
// establish draco Parser
const dracoLoader = new DRACOLoader(manager);
dracoLoader.setDecoderConfig({
type: "js" });
dracoLoader.setDecoderPath(process.env.REACT_APP_URL as string);
// gltf loader
const gltfLoader = new GLTFLoader(manager);
gltfLoader.setDRACOLoader(dracoLoader);
gltfLoader.load(mapModel, setMap);
// No LoadingManager The loader of If you use gltfLoader Will trigger an event change progress State causes a memory leak
const normalGltfLoader = new GLTFLoader();
normalGltfLoader.setDRACOLoader(dracoLoader);
window.gltfLoader = normalGltfLoader;
};
/** * Progress growth detection * @param {number} increase The value of growth * @param {number} prev state Original value * @return {number} newValue */
const timeCheck = (increase: number) => (prev: number) => {
if (increase + prev < 100) return prev + increase;
// >= 100 Test time
if (Date.now() - enterTime > maxLoadTime) return 100;
//time < maxLoadTime
timer = setTimeout(() => {
setProgress(100);
}, maxLoadTime - (Date.now() - enterTime));
// Show skip button
setIsCanJump(true);
return prev;
};
Model scaling animation
let timer: number;
let i = 0;
const r = () => {
if (i < 15) {
timer = requestAnimationFrame(r);
}
for (const item of iconScene.children) {
item.scale.x += 0.03;
item.scale.y += 0.03;
item.scale.z += 0.03;
}
i++;
};
r();
版权声明
本文为[Jedi Hongbin]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/04/202204211209068957.html
边栏推荐
- The simpler the Oracle database machine is, the more reliable it is. Oracle buried the "colored egg" 11 years ago
- 【软件测试系列十一】《压力测试场景及测试用例模板》
- Intermediary encircles little red book
- [Software Test Series VII] software test plan
- 基于SSM开发的医院住院管理信息系统(HIMS)-毕业设计-附源码
- 上海疫情中,新消费品牌们的坚守、放弃与救赎
- 天梯赛题目记录(二)
- What's the use of the enterprise's official website? Do you have to build an official website?
- The non display of markerarray caused by the ROS version problem has been solved
- The basic software products of xinghuan science and technology have been fully implemented and blossomed, bringing "Star" momentum to the digital transformation of enterprises
猜你喜欢

Base de données, ajouter les données d'un champ d'une autre table à une autre table et ajouter les données dont vous avez besoin lors de l'ajout

The basic software products of xinghuan science and technology have been fully implemented and blossomed, bringing "Star" momentum to the digital transformation of enterprises

Intermediary encircles little red book

世界读书日|数据库经典书籍推荐书单(文末留言免费送)

Hongshan MOFs distributed storage system won the "2022 Gold Award for distributed storage products"
![[Software Testing Series II] software testing process specification](/img/c1/011480f4dc1dd63935fb29eaf7e088.png)
[Software Testing Series II] software testing process specification

分支 if语句

华润怡宝被传IPO,农夫山泉或将迎来早年“宿敌”

Reverse crawler 30 verification code of a fourth generation slider

php如何判断指定日期是不是前一天
随机推荐
给定字符串提取姓名(字符串、list、re“零宽断言”)
The basic software products of xinghuan science and technology have been fully implemented and blossomed, bringing "Star" momentum to the digital transformation of enterprises
[software test series IX] description of matters to be provided for pressure test application
国内期货开户去哪里开可以费率低,公司又安全?
JD cloud distributed database stardb successfully completed multi-party localization adaptation certification
集成公告|KeyFi现已上线Moonbeam
vscode 经常弹出:尝试在目标目录创建文件时发生一个错误 重试 跳过这个文件 关闭安装程序
俄外交部官员:在乌特别军事行动将在北约造成的安全威胁被消除后结束
企业官网有啥用?一定要搭建官方网站吗?
NoSuchBeanDefinitionException - not resolved currently
去中心化VC平台CULTDAO发起对BetaMars项目投票,目前投票正在进行中
How PHP removes array keys
One minute teaches you to use yolov5 to train your dataset and test it
Study notes of "deep learning" (VII)
基于C#实现文本读取的7种方式
Extract name from given string (string, list, re "zero width assertion")
Jsapi payment is missing appid
星环科技基础软件产品全面落地开花,为企业数字化转型带来“星”动能
Cloud native Daas Service - a brief introduction to distributed object storage
基于SSM开发的医院住院管理信息系统(HIMS)-毕业设计-附源码