<! DOCTYPE html >
< html lang = " en" >
< head> < meta charset = " UTF-8" > < meta name = " viewport" content = " width=device-width, initial-scale=1.0" > < title> 數學粒子動畫</ title> < style> body { margin : 0; padding : 0; background-color : #000; display : flex; justify-content : center; align-items : center; height : 100vh; overflow : hidden; font-family : 'Segoe UI' , Tahoma, Geneva, Verdana, sans-serif; } .container { position : relative; width : 100%; max-width : 900px; text-align : center; } canvas { background-color : black; border-radius : 8px; box-shadow : 0 0 20px rgba ( 0, 100, 255, 0.3) ; } .title { color : rgba ( 255, 255, 255, 0.85) ; margin-bottom : 20px; font-size : 2.2rem; text-shadow : 0 0 10px rgba ( 0, 150, 255, 0.8) ; letter-spacing : 1.5px; } .description { color : rgba ( 200, 220, 255, 0.7) ; max-width : 600px; margin : 20px auto; font-size : 1.1rem; line-height : 1.6; } .controls { margin : 20px 0; } .control-btn { background : rgba ( 30, 60, 120, 0.7) ; color : white; border : none; padding : 10px 20px; margin : 0 10px; border-radius : 4px; cursor : pointer; font-size : 1rem; transition : all 0.3s ease; outline : none; } .control-btn:hover { background : rgba ( 50, 100, 200, 0.9) ; transform : translateY ( -2px) ; box-shadow : 0 5px 15px rgba ( 0, 100, 255, 0.4) ; } .footer { color : rgba ( 150, 180, 220, 0.6) ; margin-top : 25px; font-size : 0.9rem; } </ style>
</ head>
< body> < div class = " container" > < h1 class = " title" > 數學粒子動畫</ h1> < canvas id = " particleCanvas" width = " 900" height = " 900" > </ canvas> < div class = " description" > 這個動畫展示了10,000個粒子按照復雜的數學公式運動。每個粒子的位置由三角函數的組合計算得出,創造出令人著迷的視覺效果。</ div> < div class = " controls" > < button id = " pauseBtn" class = " control-btn" > 暫停</ button> < button id = " resetBtn" class = " control-btn" > 重置</ button> < button id = " speedUpBtn" class = " control-btn" > 加速</ button> < button id = " slowDownBtn" class = " control-btn" > 減速</ button> </ div> < div class = " footer" > HTML5 Canvas實現 | 數學公式驅動的藝術</ div> </ div> < script> const canvas = document. getElementById ( 'particleCanvas' ) ; const ctx = canvas. getContext ( '2d' ) ; const particles = [ ] ; const numParticles = 10000 ; let t = 0 ; let animationSpeed = 1 ; let isPaused = false ; function initParticles ( ) { particles. length = 0 ; for ( let i = 0 ; i <= numParticles; i++ ) { const x = i % 200 ; const y = i / 43 ; const k = 5 * Math. cos ( x / 14 ) * Math. cos ( y / 30 ) ; const e = y / 8 - 13 ; const d = ( k * k + e * e) / 59 + 4 ; const a = Math. atan2 ( k, e) ; particles. push ( { k, e, d, a, x : 0 , y : 0 } ) ; } } function updateParticles ( ) { t += Math. PI / 20 * animationSpeed; for ( let i = 0 ; i < particles. length; i++ ) { const p = particles[ i] ; const q = 60 - 3 * Math. sin ( p. a * p. e) + p. k * ( 3 + 4 / p. d * Math. sin ( p. d * p. d - t * 2 ) ) ; const c = p. d / 2 + p. e / 99 - t / 18 ; p. x = q * Math. sin ( c) + 200 ; p. y = ( q + p. d * 9 ) * Math. cos ( c) + 200 ; } } function drawParticles ( ) { ctx. fillStyle = 'rgba(0, 0, 0, 0.15)' ; ctx. fillRect ( 0 , 0 , canvas. width, canvas. height) ; for ( let i = 0 ; i < particles. length; i++ ) { const p = particles[ i] ; const colorValue = Math. floor ( 150 + 100 * Math. sin ( t/ 5 + p. x/ 50 ) ) ; ctx. fillStyle = ` rgba(150, ${ colorValue} , 255, 0.4) ` ; ctx. beginPath ( ) ; ctx. arc ( p. x, p. y, 1.2 , 0 , Math. PI * 2 ) ; ctx. fill ( ) ; } } function animate ( ) { if ( ! isPaused) { updateParticles ( ) ; drawParticles ( ) ; } requestAnimationFrame ( animate) ; } document. getElementById ( 'pauseBtn' ) . addEventListener ( 'click' , function ( ) { isPaused = ! isPaused; this . textContent = isPaused ? '繼續' : '暫停' ; } ) ; document. getElementById ( 'resetBtn' ) . addEventListener ( 'click' , function ( ) { t = 0 ; animationSpeed = 1 ; initParticles ( ) ; } ) ; document. getElementById ( 'speedUpBtn' ) . addEventListener ( 'click' , function ( ) { animationSpeed = Math. min ( animationSpeed + 0.5 , 5 ) ; } ) ; document. getElementById ( 'slowDownBtn' ) . addEventListener ( 'click' , function ( ) { animationSpeed = Math. max ( animationSpeed - 0.5 , 0.5 ) ; } ) ; initParticles ( ) ; animate ( ) ; </ script>
</ body>
</ html>