PageSourceSearch

https://goldapple.vercel.app/assets/js/threemodel.js

js goldapple.vercel.app collected 2026-10-03 05:48:08 UTC 13,229 bytes, 333 lines download raw bytes

1(function(){    
2    // 3D PERSON ------------
3        // Set our main variables
4        let scene,  
5            renderer,
6            camera,
7            model,                              // Our character
8            neck,                               // Reference to the neck bone in the skeleton
9            waist,                               // Reference to the waist bone in the skeleton
10            possibleAnims,                      // Animations found in our file
11            mixer,                              // THREE.js animations mixer
12            idle,                               // Idle, the default state our character returns to
13            clock = new THREE.Clock(),          // Used for anims, which run to a clock instead of frame rate 
14            currentlyAnimating = false,         // Used to check whether characters neck is being used in another anim
15            raycaster = new THREE.Raycaster(),  // Used to detect the click on our character
16            loaderAnim = document.getElementById('js-loader');
17            
18            init(); 
19        
20        function init() {
21            const MODEL_PATH = 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/1376484/stacy_lightweight.glb';
22            
23            const canvas = document.querySelector('#c');
24            const backgroundColor = 0x00000000;
25        
26            // Init the scene
27            scene = new THREE.Scene();
28        //   scene.background = new THREE.Color(backgroundColor);
29        //   scene.fog = new THREE.Fog(backgroundColor, 60, 100);
30            
31            // Init the renderer
32            renderer = new THREE.WebGLRenderer({ canvas, antialias: true });
33            renderer.shadowMap.enabled = true;
34            renderer.setPixelRatio(devicePixelRatio);
35            document.body.appendChild(renderer.domElement);
36            
37            // Add a camera
38            camera = new THREE.PerspectiveCamera(
39            50,
40            innerWidth / innerHeight,
41            0.1,
42            1000
43            );
44            camera.position.z = 30 
45            camera.position.x = 0;
46            camera.position.y = -3;
47            
48            let stacy_txt = new THREE.TextureLoader().load('https://fantasticfullstackdev.github.io/jinwangdev/assets/images/stacy.jpg');
49        
50            stacy_txt.flipY = false; // we flip the texture so that its the right way up
51        
52            const stacy_mtl = new THREE.MeshPhongMaterial({
53            map: stacy_txt,
54            color: 0xffffff,
55            skinning: true
56            });
57            var loader = new THREE.GLTFLoader();
58            loader.setCrossOrigin('Access-Control-Allow-Origin');
59            loader.load(
60            MODEL_PATH,
61            function(gltf) {
62                // A lot is going to happen here
63                model = gltf.scene;
64                let fileAnimations = gltf.animations;
65                model.traverse(o => {
66                if (o.isMesh) {
67                    o.castShadow = true;
68                    o.receiveShadow = true;
69                    o.material = stacy_mtl; // Add this line
70                }
71                
72                
73                    // Reference the neck and waist bones
74                    if (o.isBone && o.name === 'mixamorigNeck') { 
75                    neck = o;
76                    }
77                    if (o.isBone && o.name === 'mixamorigSpine') { 
78                    waist = o;
79                    }
80                });
81                    
82                
83                // Set the models initial scale
84                model.scale.set(10, 10, 7);
85                
86                model.position.y = -14
87                
88                
89                scene.add(model);
90                loaderAnim.remove();
91                
92                mixer = new THREE.AnimationMixer(model);
93                let clips = fileAnimations.filter(val => val.name !== 'idle');
94                possibleAnims = clips.map(val => {
95                let clip = THREE.AnimationClip.findByName(clips, val.name);
96                clip.tracks.splice(3, 3);
97                clip.tracks.splice(9, 3);
98                clip = mixer.clipAction(clip);
99                return clip;
100                });
101                
102                let idleAnim = THREE.AnimationClip.findByName(fileAnimations, 'idle');
103                idleAnim.tracks.splice(3, 3);
104                idleAnim.tracks.splice(9, 3);
105                idle = mixer.clipAction(idleAnim);
106                idle.play();
107                
108            },
109            undefined, // We don't need this function
110            function(error) {
111                console.error(error);
112            }
113            );
114            
115            // Add lights
116            let hemiLight = new THREE.HemisphereLight(0xffffff, 0xffffff, 0.61);
117            hemiLight.position.set(0, 50, 0);
118            // Add hemisphere light to scene
119            scene.add(hemiLight);
120        
121            let d = 8.25;
122            let dirLight = new THREE.DirectionalLight(0xffffff, 0.54);
123            dirLight.position.set(-8, 12, 8);
124            dirLight.castShadow = true;
125            dirLight.shadow.mapSize = new THREE.Vector2(1024, 1024);
126            dirLight.shadow.camera.near = 0.1;
127            dirLight.shadow.camera.far = 1500;
128            dirLight.shadow.camera.left = d * -1;
129            dirLight.shadow.camera.right = d;
130            dirLight.shadow.camera.top = d;
131            dirLight.shadow.camera.bottom = d * -1;
132            // Add directional Light to scene
133            scene.add(dirLight);
134            
135            // Floor
136        //   let floorGeometry = new THREE.PlaneGeometry(5000, 5000, 1, 1);
137        //   let floorMaterial = new THREE.MeshPhongMaterial({
138        //     color: 0xeeeeee,
139        //     shininess: 0,
140        //   });
141        
142        //   let floor = new THREE.Mesh(floorGeometry, floorMaterial);
143        //   floor.rotation.x = -0.5 * Math.PI; // This is 90 degrees by the way
144        //   floor.receiveShadow = true;
145        //   floor.position.y = -11;
146        //   scene.add(floor);
147            
148            
149        //   let geometry = new THREE.SphereGeometry(8, 32, 32);
150        //   let material = new THREE.MeshBasicMaterial({ color: 0x9bffaf }); // 0xf2ce2e 
151        //   let sphere = new THREE.Mesh(geometry, material);
152        //   sphere.position.z = -15;
153        //   sphere.position.y = -2.5;
154        //   sphere.position.x = -0.25;
155        //   scene.add(sphere);
156        }
157        
158        function update() {
159            
160            if (mixer) {
161            mixer.update(clock.getDelta());
162            }
163            if (resizeRendererToDisplaySize(renderer)) {
164            const canvas = renderer.domElement;
165            camera.aspect = canvas.clientWidth / canvas.clientHeight;
166            camera.updateProjectionMatrix();
167            }
168            renderer.render(scene, camera);
169            requestAnimationFrame(update);
170        }
171        update();
172        
173        function resizeRendererToDisplaySize(renderer) {
174            const canvas = renderer.domElement;
175            let width = innerWidth;
176            let height = innerHeight;
177            let canvasPixelWidth = canvas.width / devicePixelRatio;
178            let canvasPixelHeight = canvas.height / devicePixelRatio;
179        
180            const needResize =
181            canvasPixelWidth !== width || canvasPixelHeight !== height;
182            if (needResize) {
183            renderer.setSize(width, height, false);
184            }
185            return needResize;
186        }
187            
188        addEventListener('click', e => raycast(e));
189        addEventListener('touchend', e => raycast(e, true));
190        
191        function raycast(e, touch = false) {
192            var mouse = {};
193            if (touch) {
194            mouse.x = 2 * (e.changedTouches[0].clientX / innerWidth) - 1;
195            mouse.y = 1 - 2 * (e.changedTouches[0].clientY / innerHeight);
196            } else {
197            mouse.x = 2 * (e.clientX / innerWidth) - 1;
198            mouse.y = 1 - 2 * (e.clientY / innerHeight);
199            }
200            // update the picking ray with the camera and mouse position
201            raycaster.setFromCamera(mouse, camera);
202        
203            // calculate objects intersecting the picking ray
204            var intersects = raycaster.intersectObjects(scene.children, true);
205        
206            if (intersects[0]) {
207            var object = intersects[0].object;
208        
209            if (object.name === 'stacy') {
210        
211                if (!currentlyAnimating) {
212                currentlyAnimating = true;
213                playOnClick();
214                }
215            }
216            }
217        }
218            
219            // Get a random animation, and play it 
220            function playOnClick() {
221            let anim = Math.floor(Math.random() * possibleAnims.length) + 0;
222            playModifierAnimation(idle, 0.25, possibleAnims[anim], 0.25);
223        }
224
225        function playOnScroll(name) {
226            const anims = ['pocket', 'rope', 'swingdance', 'jump', 'react', 'shrug', 'wave', 'golf', 'idle'];
227            let anim = anims.indexOf(name);
228            playModifierAnimation(idle, 0.25, possibleAnims[anim], 0.25);
229        }
230            
231            function playModifierAnimation(from, fSpeed, to, tSpeed) {
232            to.setLoop(THREE.LoopOnce);
233            to.reset();
234            to.play();
235            from.crossFadeTo(to, fSpeed, true);
236            setTimeout(function() {
237            from.enabled = true;
238            to.crossFadeTo(from, tSpeed, true);
239            currentlyAnimating = false;
240            }, to._clip.duration * 1000 - ((tSpeed + fSpeed) * 1000));
241        }
242            
243            document.addEventListener('mousemove', function(e) {
244            var mousecoords = getMousePos(e);
245            if (neck && waist) {
246                moveJoint(mousecoords, neck, 50);
247                moveJoint(mousecoords, waist, 30);
248            }
249            });
250        
251            function getMousePos(e) {
252            return { x: e.clientX, y: e.clientY };
253            }
254            
255            document.addEventListener('mousemove', function(e) {
256            var mousecoords = getMousePos(e);
257                if (neck && waist) {
258        
259                moveJoint(mousecoords, neck, 50);
260                moveJoint(mousecoords, waist, 30);
261                }
262            });
263        
264            function getMousePos(e) {
265            return { x: e.clientX, y: e.clientY };
266            }
267            
268            function moveJoint(mouse, joint, degreeLimit) {
269                let degrees = getMouseDegrees(mouse.x, mouse.y, degreeLimit);
270                joint.rotation.y = THREE.Math.degToRad(degrees.x);
271                joint.rotation.x = THREE.Math.degToRad(degrees.y);
272            //   console.log(joint.rotation.x);
273            }
274            
275            function getMouseDegrees(x, y, degreeLimit) {
276            let dx = 0,
277                dy = 0,
278                xdiff,
279                xPercentage,
280                ydiff,
281                yPercentage;
282        
283            let w = { x: innerWidth, y: innerHeight };
284        
285            // Left (Rotates neck left between 0 and -degreeLimit)
286                // 1. If cursor is in the left half of screen
287            if (x <= w.x / 2) {
288                // 2. Get the difference between middle of screen and cursor position
289                xdiff = w.x / 2 - x; 
290                // 3. Find the percentage of that difference (percentage toward edge of screen)
291                xPercentage = (xdiff / (w.x / 2)) * 100; 
292                // 4. Convert that to a percentage of the maximum rotation we allow for the neck
293                dx = ((degreeLimit * xPercentage) / 100) * -1; 
294            }
295            
296            // Right (Rotates neck right between 0 and degreeLimit)
297            if (x >= w.x / 2) {
298                xdiff = x - w.x / 2;
299                xPercentage = (xdiff / (w.x / 2)) * 100;
300                dx = (degreeLimit * xPercentage) / 100;
301            }
302            // Up (Rotates neck up between 0 and -degreeLimit)
303            if (y <= w.y / 2) {
304                ydiff = w.y / 2 - y;
305                yPercentage = (ydiff / (w.y / 2)) * 100;
306                // Note that I cut degreeLimit in half when she looks up
307                dy = (((degreeLimit * 0.5) * yPercentage) / 100) * -1;
308            }
309            // Down (Rotates neck down between 0 and degreeLimit)
310            if (y >= w.y / 2) {
311                ydiff = y - w.y / 2;
312                yPercentage = (ydiff / (w.y / 2)) * 100;
313                dy = (degreeLimit * yPercentage) / 100;
314            }
315            return { x: dx, y: dy };
316            }      
317
318            function makeAnimation (num) {
319            console.log(num);
320            const anims = ['wave', 'shrug', 'rope', 'pocket', 'jump', 'golf', 'swingdance',  'react', 'wave'];
321            if (!currentlyAnimating) {
322                currentlyAnimating = true;
323                playOnScroll(anims[num]);
324            }
325            }
326
327            $(window).scroll(function(e){
328            var value = $(window).scrollTop();
329            if(value % 1100 < 50) {
330                makeAnimation(Math.floor(value / 1100));
331            }
332            });
333})(); 

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.