• 程序人生 | 与足球共舞的火柴人(致敬格拉利什,赋予足球更深的意义)


    个人简介

    👀个人主页: 前端杂货铺
    🙋‍♂️学习方向: 主攻前端方向,也会涉及到服务端
    📃个人状态: 在校大学生一枚,已拿多个前端 offer(秋招)
    🚀未来打算: 为中国的工业软件事业效力n年
    🥇推荐学习:🍍前端面试宝典 🍉Vue2 🍋Vue3 🍓Vue2&Vue3项目实战 🥝Node.js
    🌕个人推广:每篇文章最下方都有加入方式,旨在交流学习&资源分享&商务合作,快加入进来吧


    一、前言

    2022 年的 卡塔尔足球世界杯 已经开赛 14 天。

    2022.11.21 晚,格拉利什 进球后 庆祝动作 的背后其实有一段 非常感人的故事(格拉利什和患脑瘫的小球迷的暖心约定)

    【格拉利什庆祝动作】【世界杯感动瞬间】

    花有重开日,人无再少年。格拉利什 这类人的存在,赋予了足球更深的意义!

    程序人生,用技术记录世界杯,接下来我们使用 Three.js 技术,来实现一个 与足球共舞的火柴人(致敬格拉利什)

    备注:其实我自己在电脑上运行效果是非常顺滑流畅的,可能是录屏软件的问题,会导致观看效果不佳(看着卡顿,其实很丝滑)

    与足球共舞的火柴人

    二、使用 Three.js 渲染足球

    简介:Three.js 是 JavaScript 编写的 WebGL 第三方库。提供了非常多的 3D 显示功能。

    渲染足球前我们得先有一张足球的材质贴图(football.png),用于把图贴到我们创建的球体上。如下所示:

    在这里插入图片描述

    创建一个HTML文件,World_Cup.html

    备注:以下仅简单的解释了部分代码的含义,详细内容请自行学习

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>2022世界杯</title>
        <style>
            body {
                margin: 0px;
            }
        </style>
    </head>
    <body>
        <script type="text/javascript" src="https://cdn.bootcss.com/three.js/90/three.min.js"></script>
        <script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
        <script type="text/javascript">
            // 初始化相机
            let camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 10000)
            camera.position.z = 500;
    
            // 初始化场景
            let scene = new THREE.Scene()
    
            // 初始化渲染器
            let renderer = new THREE.WebGLRenderer()
            renderer.setSize(window.innerWidth, window.innerHeight)
            document.body.appendChild(renderer.domElement)
    
            // 定义一个球体,这里的参数可以根据需要调节
            let geometry = new THREE.SphereGeometry(50, 32, 32)
            
            let texture = new THREE.TextureLoader().load('./imgs/football.png')
            let material = new THREE.MeshBasicMaterial({map: texture})
    
            // 将材质和几何体进行绑定
            let cube = new THREE.Mesh(geometry, material)
    
            // 将绑定后的几何体放入场景中
            scene.add(cube)
    
            // 进行渲染
            function animate() {
                requestAnimationFrame(animate)
                renderer.render(scene, camera)
            }
    
            animate()
        </script>
    </body> 
    </html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    在这里插入图片描述

    三、使用 Three.js 渲染跳舞的火柴人

    创建一个HTML文件,Matchman.html。该部分代码比较复杂,不仅需要创建场景生成火柴人,还需要给他添加一些列的动作,并完美的渲染出来(不白屏,不卡顿等)。所以需要引入很多内置的 js 文件,在此就不列举了,想要代码的可以找我要。

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
    	<title>three.js webgl - loaders - BVHLoader</title>
    	<meta charset="utf-8">
    	<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
    	<link type="text/css" rel="stylesheet" href="main.css">
    	<style>
    		body {
    			background-color: #eee;
    			color: #444;
    		}
    
    		a {
    			color: #08f;
    		}
    
    		h2 {
    			color: orange;
    		}
    
    	</style>
    </head>
    
    <body>
    	<div id="info">
    		<h2>与足球共舞的火柴人【前端杂货铺】</h2>
    	</div>
    
    	<script async src="https://unpkg.com/es-module-shims@1.3.6/dist/es-module-shims.js"></script>
    
    	<script type="importmap">
    		{
    			"imports": {
    				"three": "../build/three.module.js",
    				"three/addons/": "./jsm/"
    			}
    		}
    	</script>
    
    	<script type="module">
    
    		import * as THREE from 'three';
    
    			import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
    			import { BVHLoader } from 'three/addons/loaders/BVHLoader.js';
    
    			const clock = new THREE.Clock();
    
    			let camera, controls, scene, renderer;
    			let mixer, skeletonHelper;
    
    			init();
    			animate();
    
    			const loader = new BVHLoader();
    			loader.load( 'models/bvh/pirouette.bvh', function ( result ) {
    
    				skeletonHelper = new THREE.SkeletonHelper( result.skeleton.bones[ 0 ] );
    				skeletonHelper.skeleton = result.skeleton; // allow animation mixer to bind to THREE.SkeletonHelper directly
    
    				const boneContainer = new THREE.Group();
    				boneContainer.add( result.skeleton.bones[ 0 ] );
    
    				scene.add( skeletonHelper );
    				scene.add( boneContainer );
    
    				// play animation
    				mixer = new THREE.AnimationMixer( skeletonHelper );
    				mixer.clipAction( result.clip ).setEffectiveWeight( 1.0 ).play();
    
    			} );
    
    			function init() {
    
    				camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 1000 );
    				camera.position.set( 0, 200, 300 );
    
    				scene = new THREE.Scene();
    				scene.background = new THREE.Color( 0xeeeeee );
    
    				scene.add( new THREE.GridHelper( 400, 10 ) );
    
    				// renderer
    				renderer = new THREE.WebGLRenderer( { antialias: true } );
    				renderer.setPixelRatio( window.devicePixelRatio );
    				renderer.setSize( window.innerWidth, window.innerHeight );
    				document.body.appendChild( renderer.domElement );
    
    				controls = new OrbitControls( camera, renderer.domElement );
    				controls.minDistance = 300;
    				controls.maxDistance = 700;
    
    				window.addEventListener( 'resize', onWindowResize );
    
    			}
    
    			function onWindowResize() {
    
    				camera.aspect = window.innerWidth / window.innerHeight;
    				camera.updateProjectionMatrix();
    
    				renderer.setSize( window.innerWidth, window.innerHeight );
    
    			}
    
    			function animate() {
    
    				requestAnimationFrame( animate );
    
    				const delta = clock.getDelta();
    
    				if ( mixer ) mixer.update( delta );
    
    				renderer.render( scene, camera );
    
    			}
    
    		</script>
    </body>
    </html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122

    跳舞的火柴人

    四、总结(充能)

    把这两部分代码 结合一下 就可以完成 与足球共舞的火柴人 了。

    怎么样,是不是觉得 Three.js 还是很有意思的。

    扩展:其实 Three.js 的用途还是很多的

    • 智慧城市
    • 房屋 3D 视图
    • 开发工业软件(CAD,CAE等)

    总的来说 Three.js 就是来渲染 3D 效果的。目前 Three.js 是个很强大好用的 3D 渲染库,接下来我也会进行这方面的学习,到时候可以 和大家一起探索 Three.js 的世界。

    五、写在最后(观世界杯有感)

    随着时代的进步,科技的发展。我们的生活也正变得更加精彩和便利。世界杯的勇士们在足球场上挥洒汗水,去取得属于他们的荣誉。

    同时像 格拉利什 这样的人的存在,也暖心了很多人,给这个世界增添了一分温暖。

    其实每个人都可以 做一颗小星星,用自己的那一分热,去散发着自己的那一分 微弱而又耀眼的光!


    在这里插入图片描述


  • 相关阅读:
    【总结】有三AI所有原创GAN相关的技术文章汇总(2022年8月)
    PackagingTool_x64_v2.0.1.0图片转档打包二进制文件合并字库生成图片软件介绍
    react-demo项目:支持使用CSS Modules(不使用create-react-app脚手架)
    Python自动查重之原理、方法与实践详解
    python+nodejs+php+springboot+vue 导师双选系统
    Linux Nacos2.2.0版本集群搭建,常见报错问题解决
    【学习笔记14】JavaScript的循坏语句
    解决一个Qt程序崩溃的问题
    大前端JS篇之搞懂【Set】
    FT2004(D2000)开发实战之U-boot环境变量
  • 原文地址:https://blog.csdn.net/qq_45902692/article/details/128171267