<! DOCTYPE html >
< html lang = " zh-CN" >
< head> < meta charset = " UTF-8" > < meta name = " viewport" content = " width=device-width, initial-scale=1.0" > < title> 数字雨动画背景</ title> < style> * { margin : 0; padding : 0; box-sizing : border-box; } body { background-color : #000; color : #0f0; font-family : 'Courier New' , monospace; overflow : hidden; height : 100vh; display : flex; flex-direction : column; justify-content : center; align-items : center; position : relative; } canvas { position : absolute; top : 0; left : 0; z-index : -1; } .content { text-align : center; z-index : 1; padding : 20px; background : rgba ( 0, 20, 0, 0.7) ; border-radius : 10px; max-width : 80%; backdrop-filter : blur ( 5px) ; border : 1px solid rgba ( 0, 255, 0, 0.3) ; box-shadow : 0 0 20px rgba ( 0, 255, 0, 0.3) ; } h1 { font-size : 2.8rem; margin-bottom : 20px; text-shadow : 0 0 10px #0f0; letter-spacing : 3px; } p { font-size : 1.2rem; margin-bottom : 20px; line-height : 1.6; } .controls { display : flex; gap : 15px; justify-content : center; margin-top : 20px; flex-wrap : wrap; } button { background : rgba ( 0, 30, 0, 0.8) ; color : #0f0; border : 1px solid #0f0; padding : 10px 20px; font-size : 1rem; cursor : pointer; transition : all 0.3s; font-family : 'Courier New' , monospace; border-radius : 5px; } button:hover { background : rgba ( 0, 100, 0, 0.8) ; box-shadow : 0 0 15px rgba ( 0, 255, 0, 0.7) ; transform : translateY ( -2px) ; } .stats { position : absolute; bottom : 20px; right : 20px; background : rgba ( 0, 20, 0, 0.6) ; padding : 10px 15px; border-radius : 5px; border : 1px solid rgba ( 0, 255, 0, 0.3) ; } .footer { position : absolute; bottom : 20px; color : #0a0; font-size : 0.9rem; } @media ( max-width : 768px) { h1 { font-size : 2rem; } p { font-size : 1rem; } .content { max-width : 95%; } } </ style>
</ head>
< body> < canvas id = " matrixCanvas" > </ canvas> < div class = " content" > < h1> 数字矩阵</ h1> < p> 0和1组成的数字雨从上向下流动,形成科幻感十足的数字矩阵背景</ p> < p> 点击屏幕任意位置可创建数字涟漪效果</ p> < div class = " controls" > < button id = " speedUp" > 加速</ button> < button id = " speedDown" > 减速</ button> < button id = " densityUp" > 增加密度</ button> < button id = " densityDown" > 减少密度</ button> < button id = " toggleTheme" > 切换主题</ button> </ div> </ div> < div class = " stats" > < span id = " fpsCounter" > FPS: 60</ span> | < span id = " dropsCounter" > 数字雨滴: 150</ span> </ div> < div class = " footer" > Matrix Digital Rain Animation</ div> < script> const canvas = document. getElementById ( 'matrixCanvas' ) ; const ctx = canvas. getContext ( '2d' ) ; canvas. width = window. innerWidth; canvas. height = window. innerHeight; const chars = '010101' ; const fontSize = 14 ; const columns = canvas. width / fontSize; let drops = [ ] ; for ( let i = 0 ; i < columns; i++ ) { drops[ i] = Math. floor ( Math. random ( ) * canvas. height / fontSize) ; } let speed = 5 ; let density = 2 ; let colorTheme = 'green' ; let lastTime = 0 ; let fps = 0 ; let frameCount = 0 ; let startTime = Date. now ( ) ; let rippleEffect = null ; function draw ( ) { ctx. fillStyle = 'rgba(0, 0, 0, 0.05)' ; ctx. fillRect ( 0 , 0 , canvas. width, canvas. height) ; ctx. font = ` ${ fontSize} px monospace ` ; for ( let i = 0 ; i < columns; i++ ) { if ( i % density !== 0 ) continue ; const char = chars[ Math. floor ( Math. random ( ) * chars. length) ] ; const gradient = ctx. createLinearGradient ( 0 , 0 , 0 , canvas. height) ; if ( colorTheme === 'green' ) { gradient. addColorStop ( 0 , '#0f0' ) ; gradient. addColorStop ( 0.5 , '#0a0' ) ; gradient. addColorStop ( 1 , '#050' ) ; } else { gradient. addColorStop ( 0 , '#0af' ) ; gradient. addColorStop ( 0.5 , '#08a' ) ; gradient. addColorStop ( 1 , '#035' ) ; } ctx. fillStyle = gradient; const x = i * fontSize; const y = drops[ i] * fontSize; ctx. fillText ( char, x, y) ; if ( y > canvas. height && Math. random ( ) > 0.975 ) { drops[ i] = 0 ; } drops[ i] += speed / 10 ; } if ( rippleEffect) { const { x, y, radius, maxRadius} = rippleEffect; const gradient = ctx. createRadialGradient ( x, y, 0 , x, y, radius) ; gradient. addColorStop ( 0 , 'rgba(0, 255, 0, 0.8)' ) ; gradient. addColorStop ( 1 , 'rgba(0, 255, 0, 0)' ) ; ctx. fillStyle = gradient; ctx. beginPath ( ) ; ctx. arc ( x, y, radius, 0 , Math. PI * 2 ) ; ctx. fill ( ) ; rippleEffect. radius += 2 ; if ( rippleEffect. radius > maxRadius) { rippleEffect = null ; } } frameCount++ ; const now = Date. now ( ) ; if ( now - startTime >= 1000 ) { fps = frameCount; frameCount = 0 ; startTime = now; document. getElementById ( 'fpsCounter' ) . textContent = ` FPS: ${ fps} ` ; document. getElementById ( 'dropsCounter' ) . textContent = ` 数字雨滴: ${ Math. floor ( columns / density) } ` ; } } function animate ( ) { draw ( ) ; requestAnimationFrame ( animate) ; } animate ( ) ; window. addEventListener ( 'resize' , ( ) => { canvas. width = window. innerWidth; canvas. height = window. innerHeight; drops = [ ] ; for ( let i = 0 ; i < columns; i++ ) { drops[ i] = Math. floor ( Math. random ( ) * canvas. height / fontSize) ; } } ) ; canvas. addEventListener ( 'click' , ( e ) => { rippleEffect = { x: e. clientX, y: e. clientY, radius: 5 , maxRadius: 100 } ; } ) ; document. getElementById ( 'speedUp' ) . addEventListener ( 'click' , ( ) => { speed = Math. min ( speed + 1 , 20 ) ; } ) ; document. getElementById ( 'speedDown' ) . addEventListener ( 'click' , ( ) => { speed = Math. max ( speed - 1 , 1 ) ; } ) ; document. getElementById ( 'densityUp' ) . addEventListener ( 'click' , ( ) => { density = Math. max ( density - 0.5 , 1 ) ; } ) ; document. getElementById ( 'densityDown' ) . addEventListener ( 'click' , ( ) => { density = Math. min ( density + 0.5 , 10 ) ; } ) ; document. getElementById ( 'toggleTheme' ) . addEventListener ( 'click' , ( ) => { colorTheme = colorTheme === 'green' ? 'blue' : 'green' ; } ) ; </ script>
</ body>
</ html>