three+gsap实现一个真实三维眼球眼珠跟随鼠标转动的效果代码
代码语言:html
所属分类:三维
代码描述:three+gsap实现一个真实三维眼球眼珠跟随鼠标转动的效果代码,可以改变眼睛瞳孔的颜色和亮度及大小。
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html> <html lang="en" > <head> <meta charset="UTF-8"> <style> body { overflow: hidden; padding: 0; margin: 0; } canvas { display: block; } #zoom-range { position: absolute; width: 200px; bottom: 0; right: 10px; padding: 30px 0; } .cr.color .selector { width: 50px !important; } .cr.color .saturation-field, .cr.color .field-knob { display: none !important; } .cr.color .hue-field { width: calc(100% - 8px) !important; } .cr.color .hue-knob { margin-left: 26px !important; height: 5px !important; border-right: 10px solid #000 !important; } </style> </head> <body > <div class="container"> <input type="range" min="0" max="0" value="0" step="1" id="zoom-range" /> </div> <script type="x-shader/x-fragment" id="fragmentShader"> precision highp float; varying vec2 vUv; uniform float shrink; uniform vec3 base_color_1; uniform vec3 base_color_2; uniform vec3 mid_color; uniform float vignette; uniform float brightness; uniform float darkness; float random (in vec2 st) { return fract(sin(dot(st.xy,vec2(12.9898,78.233)))*43758.5453123); } // Based on Morgan McGuire @morgan3d // https://www.shadertoy.com/view/4dS3Wd float noise (in vec2 st) { vec2 i = floor(st); vec2 f = fract(st); float a = random(i); float b = random(i + vec2(1.0, 0.0)); float c = random(i + vec2(0.0, 1.0)); float d = random(i + vec2(1.0, 1.0)); vec2 u = f * f * (3.0 - 2.0 * f); return mix(a, b, u.x) + (c - a)* u.y * (1.0 - u.x) + (d - b) * u.x * u.y; } float fbm (in vec2 st) { float value = 0.0; float amplitude = .5; float frequency = 0.; for (int i = 0; i < 4; i++) { value += amplitude * noise(st); st *= 2.; amplitude *= .5; } return value; } float length2( vec2 p ) { vec2 q = p*p*p*p; return pow( q.x + q.y, 1.0/4.0 ); } void main() { vec2 st = vec2(.5) - vUv; st *= 1.3; st.x *= 6.28318531; // 2Pi st.y *= 3.14159265359; // Pi float r = length(st); float a = atan(st.y, st.x); float pulsing = 1. + clamp(1. - r, 0., 1.) * shrink; // noisy fullscreen mix of 2 colors float f = fbm(5. * st); vec3 col = mix(base_color_1, base_color_2, f); // blury spot in the middle col = mix(col, mid_color, 1. - smoothstep(0.2, 0.6, r * (.2 + .8 * pulsing))); // white streaks a += .05 * fbm(20. * st) * fbm(20. * st); f = smoothstep((1. - brightness), 1., fbm(vec2(20. * a, 6. * r * pulsing))); col = mix(col, vec3(1.), f); // dark insertions a = fbm(vec2(15. * a, 10. * r * pulsing)); f = smoothstep(.4, .9, a); col *= 1. - darkness * f; // vignette col *= 1. - vignette * smoothstep(.6, .8, r * (.9 + .1 * pulsing)); // pupil f = 1. - smoothstep(.2, .25, r * pulsing); col = mix(col, vec3(.0), f); // crop f = smoothstep(.79, 0.85, r); col = mix(col, vec3(1.), f); gl_FragColor = vec4(col, 1.); } </script> <script id="vertexShader" type="x-shader/x-vertex"> varying vec2 vUv; void main() { vUv = uv; vec4 mvPosition = modelViewMatrix * vec4(position, 1.0); gl_Position = projectionMatrix * mvPosition; } </script> <script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/three.128.js"></script> <script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/dat.gui-min.js"></script> <script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/gsap.3.5.2.js"></script> <script > // ------------------------------- // ------------------------------- // Interactive eyeball animation based on the famous shader created by Inigo Quilez. // ------------------------------- let visualization, pointer, controls, animations; const container = document.querySelector('.container'); let eyeConfig = { zoomLevel: 600, zoomLevelBounds: [300, 1000], shrink: 0, fstBaseColor: '#03565c', scdBaseColor: '#42cf44', midColor: '#f2aa00', vignette: 0.65, brightness: 0.6, darkness: 0.5 }; document.addEventListener('DOMContentLoaded', () => { controls = new Controls(); pointer = new Pointer(); visualization = new Visualization(); animations = new Animations(); pointer.updateCenter(); visualization.updateSize(); controls.addShaderControls(); controls.addSceneControls(); window.addEventListener('resize', () => visualization.updateSize()); visualization.loop(); container.querySelector('canvas').addEventListener("click", e => pointer.onClick(e)); document.addEventListener("mousedown", e => pointer.onMouseDown(e)); document.addEventListener("mouseup", e => pointer.onMouseUp(e)); document.addEventListener("mousemove", e => pointer.onMouseMove(e)); document.addEventListener("touchmove", e => pointer.onTouchMove(e)); document.addEventListener("touchend", e => pointer.onTouchEnd(e)); document.addEventListener("touchstart", e => pointer.onTouchStart(e)); container.addEventListener("wheel", e => { eyeConfig.zoomLevel += 0.1 * e.deltaY; eyeConfig.zoomLevel = Math.min(eyeConfig.zoomLevel, eyeConfig.zoomLevelBounds[1]); eyeConfig.zoomLevel = Math.max(eyeConfig.zoomLevel, eyeConfig.zoomLevelBounds[0]); visualization.setCameraPosition(eyeConfig.zoomLevel); }); animations.eyeAppear.play(0); gsap.delayedCall(1.1, () => {animations.playShrink.play(0);}); }); class Pointer { constructor() { this.mouse = { x: 0, y: 0 }; this.deltaMove = { x: 0, y: 0 }; this.previousMousePosition = { x: 0, y: 0 }; this.pressed = false; this.touchMode = false; this.dragging = false; this.deltaRotationQuaternion = new THREE.Quaternion(); } updateCenter() { this.windowHalf = { x: window.innerWidth / 2, y: window.innerHeight / 2 }; } onMouseDown() { this.pressed = true; } onMouseUp() { this.pressed = false; this.deltaRotationQuaternion. setFromEuler(new THREE.Euler( 0, 0, 0, 'XYZ')); } onMouseMove(e) { this.mouse = { x: (e.clientX - this.windowHalf.x) / this.windowHalf.x, y: (e.clientY - this.windowHalf.y) / this.windowHalf.y }; this.deltaMove = { x: e.offsetX - this.previousMousePosition.x, y: e.offsetY - this.previousMousePosition.y }; this.previousMousePosition = { x: e.offsetX, y: e.offsetY }; if (this.pressed) { this.deltaRotationQuaternion. setFromEuler(new THREE.Euler( this.deltaMove.y * (Math.PI / 180), this.deltaMove.x * (Math.PI / 180), 0, 'XYZ')); this.dragging = true; } } onTouchMove(e) { this.touchMode = true; setTimeout(() => this.dragging = true, 100); if (e.touches.length === 1) { this.deltaMove = { x: e.touches[0].pageX - this.previousMousePosition.x, y: e.touches[0].pageY - this.previousMousePosition.y }; this.previousMousePosition = { x: e.touches[0].pageX, y: e.touches[0].pageY }; this.deltaRotationQuaternion. setFromEuler(new THREE.Euler( this.deltaMove.y * 0.5 * (Math.PI / 180), this.deltaMove.x * 0.5 * (Math.PI / 180), 0, 'XYZ')); } } onTouchStart(e) { this.previousMousePosition = { x: e.touches[0].pageX, y: e.touches[0].pageY }; } onTouchEnd() { this.deltaRotationQuaternion. setFromEuler(new THREE.Euler( 0, 0, 0, 'XYZ')); } onClick() { if (!this.dragging) { animations.playShrink.play(0); } this.dragging = false; }}.........完整代码请登录后点击上方下载按钮下载查看
网友评论0