【html】iOS26 液態玻璃實現效果

?

?

<!DOCTYPE html>
<html lang="zh"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>液體玻璃效果演示</title><style>body {margin: 0;overflow: hidden;background-color: #000;}canvas {display: block;width: 100vw;height: 100vh;}/* 控制面板 */#controls {position: absolute;top: 10px;left: 10px;padding: 10px;background-color: rgba(0, 0, 0, 0.5);color: white;font-family: sans-serif;border-radius: 5px;user-select: none;}#controls label {cursor: pointer;}</style></head><body><canvas id="glslCanvas"></canvas><imgid="backgroundImage"src="https://pic2.zhimg.com/v2-a53c740141ab75eb4fe16af3ef8c35c5_r.jpg"crossorigin="anonymous"style="display: none"/><div id="controls"><label><input type="checkbox" id="useCircleCheckbox" />使用圓形</label></div><script id="vertex-shader" type="x-shader/x-vertex">// 將頂點位置傳遞出去,這樣片段著色器就可以在構成平面的兩個三角形上運行attribute vec2 a_position;void main() {gl_Position = vec4(a_position, 0.0, 1.0);}</script><script id="fragment-shader" type="x-shader/x-fragment">precision mediump float; // 為浮點數設置中等精度// 從 JavaScript 傳入的變量uniform vec3 iResolution;uniform float iTime;uniform vec4 iMouse;uniform vec3 iImageResolution;uniform sampler2D iImage1;uniform float useCircle;// 已適配 WebGL ---vec2 R;const float PI = 3.14159265;// 創建旋轉矩陣mat2 Rot(float a) {float c = cos(a);float s = sin(a);return mat2(c, -s, s, c);}// 像素歸一化處理float PX(float a) {return a / R.y;}// 矩形距離場float Box(vec2 p, vec2 b) {vec2 d = abs(p) - b;return length(max(d, 0.0)) + min(max(d.x, d.y), 0.0);}// 圓形距離場float Circle(vec2 p, float r) {return length(p) - r;}// 根據 useCircle 選擇形狀(圓形或圓角矩形)float Shape(vec2 p, vec2 b, float r) {return useCircle > 0.5 ? Circle(p, r) : Box(p, b);}// 液體玻璃效果vec4 LiquidGlass(vec2 uv, float direction, float quality, float size) {vec2 radius = size / R;vec4 color = texture2D(iImage1, uv);float d_step = PI / direction; // 方向步長float i_step = 1.0 / quality;  // 質量步長float d = 0.0;// 循環被展開以兼容一些舊的GPUfor (int j = 0; j < 10; j++) {if (float(j) >= direction) break;float i = i_step;for (int k = 0; k < 10; k++) {if (float(k) >= quality) break;color += texture2D(iImage1, uv + vec2(cos(d), sin(d)) * radius * i);i += i_step;}d += d_step;}color /= quality * direction + 1.0; // 歸一化return color;}// 形狀扭曲效果vec4 Distortion(vec2 uv) {float shape = Shape(uv, vec2(PX(50.0)), PX(50.0));float shapeShape = smoothstep(PX(1.5), 0.0, shape - PX(50.0)); // 形狀平滑過渡float shapeDisp = smoothstep(PX(75.0), 0.0, shape - PX(25.0)); // 邊框寬度float shapeLight = shapeShape * smoothstep(0.0, PX(20.0), shape - PX(40.0)); // 光照強度return vec4(shapeShape, shapeDisp, shapeLight, 0.0);}void main() {R = iResolution.xy;vec2 uv = gl_FragCoord.xy / R; // 歸一化UV坐標vec2 st = (gl_FragCoord.xy - 0.5 * R) / R.y; // 屏幕空間坐標vec2 M = iMouse.xy == vec2(0.0) ? vec2(0.0) : (iMouse.xy - 0.5 * R) / R.y; // 鼠標位置// 如果鼠標沒有移動過,則將效果定位在中心if (iMouse.x == 0.0 && iMouse.y == 0.0) {M = vec2(0.0);}vec4 dist = Distortion(st - M); // 計算扭曲效果vec2 uv2 = uv;uv2 *= 0.5 + 0.5 * smoothstep(0.5, 1.0, dist.y); // 縮放UVvec3 col = mix(vec3(0.0), // 透明黑色背景0.2 + LiquidGlass(uv2, 10.0, 10.0, 5.0).rgb * 0.7, // 應用液體玻璃效果dist.x); // 根據圖標形狀混合col += dist.z * 0.9 + dist.w; // 添加圖標光照和圖案// 應用陰影效果col *= 1.0 - 0.2 * smoothstep(PX(80.0), 0.0, Shape(st - M + vec2(0.0, PX(40.0)), vec2(PX(50.0)), PX(50.0)));// 使用 dist.x 控制透明度:圖標區域不透明,其他區域透明float alpha = dist.x;gl_FragColor = vec4(col, alpha); // 返回最終顏色和透明度}</script><script>const canvas = document.getElementById('glslCanvas');const gl = canvas.getContext('webgl');if (!gl) {alert('抱歉,您的瀏覽器不支持 WebGL。');}// 獲取 DOM 元素const backgroundImage = document.getElementById('backgroundImage');const useCircleCheckbox = document.getElementById('useCircleCheckbox');// 創建著色器程序function createShader(gl, type, source) {const shader = gl.createShader(type);gl.shaderSource(shader, source);gl.compileShader(shader);const success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);if (success) {return shader;}console.error(gl.getShaderInfoLog(shader));gl.deleteShader(shader);}const vertexShaderSource = document.getElementById('vertex-shader').text;const fragmentShaderSource =document.getElementById('fragment-shader').text;const vertexShader = createShader(gl,gl.VERTEX_SHADER,vertexShaderSource);const fragmentShader = createShader(gl,gl.FRAGMENT_SHADER,fragmentShaderSource);function createProgram(gl, vertexShader, fragmentShader) {const program = gl.createProgram();gl.attachShader(program, vertexShader);gl.attachShader(program, fragmentShader);gl.linkProgram(program);const success = gl.getProgramParameter(program, gl.LINK_STATUS);if (success) {return program;}console.error(gl.getProgramInfoLog(program));gl.deleteProgram(program);}const program = createProgram(gl, vertexShader, fragmentShader);gl.useProgram(program);// 準備數據 獲取 uniform 和 attribute 的位置const positionAttributeLocation = gl.getAttribLocation(program,'a_position');const resolutionUniformLocation = gl.getUniformLocation(program,'iResolution');const timeUniformLocation = gl.getUniformLocation(program, 'iTime');const mouseUniformLocation = gl.getUniformLocation(program, 'iMouse');const imageResolutionUniformLocation = gl.getUniformLocation(program,'iImageResolution');const imageSamplerUniformLocation = gl.getUniformLocation(program,'iImage1');const useCircleUniformLocation = gl.getUniformLocation(program,'useCircle');// 創建一個緩沖區來放置一個覆蓋整個畫布的矩形const positionBuffer = gl.createBuffer();gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);const positions = [-1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1];gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(positions),gl.STATIC_DRAW);gl.enableVertexAttribArray(positionAttributeLocation);gl.vertexAttribPointer(positionAttributeLocation,2,gl.FLOAT,false,0,0);// 設置紋理let imageTexture;backgroundImage.onload = function () {imageTexture = gl.createTexture();gl.bindTexture(gl.TEXTURE_2D, imageTexture);// 設置紋理參數gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);// 將圖片數據上傳到紋理gl.texImage2D(gl.TEXTURE_2D,0,gl.RGBA,gl.RGBA,gl.UNSIGNED_BYTE,backgroundImage);// 設置圖像分辨率 uniformgl.uniform3f(imageResolutionUniformLocation,backgroundImage.width,backgroundImage.height,0);// 啟動渲染requestAnimationFrame(render);};// 如果圖片已經加載完成 (例如從緩存加載)if (backgroundImage.complete) {backgroundImage.onload();}// 渲染循環let startTime = Date.now();let mouseX = 0;let mouseY = 0;function render(time) {// 調整畫布大小以匹配顯示大小const displayWidth = gl.canvas.clientWidth;const displayHeight = gl.canvas.clientHeight;if (gl.canvas.width !== displayWidth ||gl.canvas.height !== displayHeight) {gl.canvas.width = displayWidth;gl.canvas.height = displayHeight;gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);}gl.clearColor(0, 0, 0, 0);gl.clear(gl.COLOR_BUFFER_BIT);// 更新 uniformsgl.uniform3f(resolutionUniformLocation,gl.canvas.width,gl.canvas.height,1.0);gl.uniform1f(timeUniformLocation, (Date.now() - startTime) * 0.001);gl.uniform4f(mouseUniformLocation,mouseX,gl.canvas.height - mouseY,0,0); // y坐標需要翻轉gl.uniform1f(useCircleUniformLocation,useCircleCheckbox.checked ? 1.0 : 0.0);// 綁定紋理gl.activeTexture(gl.TEXTURE0);gl.bindTexture(gl.TEXTURE_2D, imageTexture);gl.uniform1i(imageSamplerUniformLocation, 0);// 繪制gl.drawArrays(gl.TRIANGLES, 0, 6);// 請求下一幀requestAnimationFrame(render);}// 事件監聽window.addEventListener('mousemove', (e) => {mouseX = e.clientX;mouseY = e.clientY;});</script></body>
</html>

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/87584.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/87584.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/87584.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

探索算法秘境:量子隨機游走算法及其在圖論問題中的創新應用

目錄 ?編輯 一、量子隨機游走算法的起源與原理 二、量子隨機游走算法在圖論問題中的創新應用 三、量子隨機游走算法的優勢與挑戰 四、結語 在算法研究的浩瀚星空中&#xff0c;總有一些領域如同遙遠星系&#xff0c;閃爍著神秘而誘人的光芒。今天&#xff0c;我們將一同深…

C# 一維數組和矩形數組全解析

在編程的世界里&#xff0c;數組是一種非常重要的數據結構。今天&#xff0c;我們就來詳細了解一下一維數組和矩形數組。 數組基礎認知 數組實例是從 System.Array 繼承類型的對象。由于它從 BCL 基類派生而來&#xff0c;所以繼承了許多有用的成員&#xff1a; Rank 屬性&a…

WebStorm編輯器側邊欄

目錄 編輯器側邊欄行號配置行號隱藏行號 代碼折疊側邊欄圖標書簽添加匿名書簽添加助記符書簽 運行和調試管理斷點配置斷點圖標 版本控制配置Git Blame注釋 編輯器側邊欄 編輯器左側的垂直區域。當編寫代碼時&#xff0c;提供重要信息和操作圖標。外觀和行為可以根據你的喜好進…

騰訊云TCCA認證考試報名 - TDSQL數據庫交付運維工程師(PostgreSQL版)

數據庫交付運維工程師-騰訊云TDSQL(PostgreSQL版)認證 適合人群&#xff1a; 適合從事TDSQL(PostgreSQL版)交付、運維、售前咨詢以及TDSQL(PostgreSQL版)相關項目的管理人員。 認證考試 單選*40道多選*20道 成績查詢 70分及以上通過認證&#xff0c;官網個人中心->認證考…

attn_mask 為 (1, 1) 時什么意思? 7,7又是什么意思?

在深度學習中&#xff0c;特別是在 Transformer 模型和注意力機制&#xff08;Attention Mechanism&#xff09;中&#xff0c;attn_mask&#xff08;注意力掩碼&#xff09;是一個用于控制注意力計算的張量。它決定了在計算注意力分數時&#xff0c;哪些位置應該被關注&#x…

Qt聯合Halcon開發二:Halcon窗口綁定Qt控件顯示Hobject圖像【詳細圖解流程】

1. 項目準備 在本項目中&#xff0c;我們將使用Qt框架與Halcon庫結合&#xff0c;展示圖像并進行圖像處理。首先&#xff0c;確保你已經配置好Qt和Halcon的開發環境。 環境配置可查看上篇文章 2. 創建Qt界面 在Qt中&#xff0c;創建一個窗口并拖入按鈕和Graphics View控件。G…

Redis 持久化機制詳解:RDB、AOF 原理與面試最佳實踐(AOF篇)

在上一章我們深入學習了 Redis 中重要的數據持久化機制 ——RDB&#xff08;Redis Database&#xff09;&#xff0c;了解了其通過周期性快照將數據以二進制文件形式保存到磁盤的原理&#xff0c;包括觸發條件、文件結構以及優缺點等核心內容。 Redis 持久化機制詳解&#xff…

【GateWay】和權限驗證

【GateWay】網關詳解和權限驗證 一、Gateway 核心概念與架構二、路由斷言&#xff08;Route Predicates&#xff09;詳解三、過濾器&#xff08;Filters&#xff09;機制四、權限認證的核心理論模型五、Spring Cloud Gateway Security OAuth2 集成方案六、OAuth2.0 集成 一、…

QSqlDatabase: QSQLITE driver not loaded

提示&#xff1a;文章寫完后&#xff0c;目錄可以自動生成&#xff0c;如何生成可參考右邊的幫助文檔 文章目錄 前言可能的原因解決辦法1. 確認 SQLite 驅動插件文件2. 拷貝插件文件到應用程序目錄3. 設置插件搜索路徑4. 安裝 SQLite 依賴庫5. 解決 QCoreApplication 實例問題 …

20250619在榮品的PRO-RK3566開發板的Android13下解決海羅光電有限公司HL070T58C-05屏在啟動的時候出現白色條紋的問題【時序】

20250619在榮品的PRO-RK3566開發板的Android13下解決海羅光電有限公司HL070T58C-05屏在啟動的時候出現白色條紋的問題 2025/6/19 20:39 緣起&#xff1a;榮品的PRO-RK3566開發板的Android13下&#xff0c;點亮海羅光電有限公司HL070T58C-05屏。 在啟動的時候會出現花屏/白色條紋…

docker使用Volume對Nginx進行掛載

需求&#xff1a; 需要將Nginx的歡迎頁面也就是index.html文件進行修改。 原始方法&#xff1a;由于docker會為每一個容器創建其對應的文件信息&#xff0c;但是創建的信息內容只有其最基礎的運行信息&#xff0c;所以想要直接去訪問其index.html就無法做到。 使用volume&am…

基于springboot的寵物服務預約系統

博主介紹&#xff1a;java高級開發&#xff0c;從事互聯網行業六年&#xff0c;熟悉各種主流語言&#xff0c;精通java、python、php、爬蟲、web開發&#xff0c;已經做了六年的畢業設計程序開發&#xff0c;開發過上千套畢業設計程序&#xff0c;沒有什么華麗的語言&#xff0…

idea 2025會在用戶目錄創建IdeaSnapshots文件夾

推薦一個api管理測試工具 一個簡單的API測試和編寫文檔的工具 idea 2025會在用戶目錄創建IdeaSnapshots文件夾 解決方案 打開 Profiler 點擊 setting 參考 https://youtrack.jetbrains.com/articles/SUPPORT-A-1086/How-to-change-or-turn-off-the-IdeaSnapshots-folder-…

【Mini-F5265-OB開發板試用測評】2、PWM驅動遙控車RX2接收解碼帶馬達驅動控制IC

手頭有帶轉向電機和動力電機小車底盤&#xff0c;買了很久一直在吃灰。 最近查了一下小車的驅動IC是富滿微的8D420L,是一款傳統的RX2接收解碼芯片&#xff0c;帶馬達驅動。 手頭沒有TX2發送芯片&#xff0c;所以考慮用MCU直接發送PWM直接接入RX2&#xff0c;可能可以驅動。 一…

Tcpdump網絡抓包工具詳解!

一、簡介 tcpdump就是&#xff1a;dump the traffic on a network&#xff0c;根據使用者的定義對網絡上的數據包進行截獲的包分析工具。 tcpdump是一個用于截取網絡分組&#xff0c;并輸出分組內容的工具。憑借強大的功能和靈活的截取策略&#xff0c;使其成為類UNIX系統下用…

Spring Boot的Security安全控制——應用SpringSecurity!

應用Spring Security 前面介紹了在項目開發時為什么選擇Spring Security&#xff0c;還介紹了它的原理。本節開始動手實踐Spring Security的相關技術。 實戰&#xff1a;Spring Security入門 現在開始搭建一個新項目&#xff0c;實踐一個Spring Security的入門程序。 &…

FPGA基礎 -- Verilog行為級建模之alawys語句

Verilog 中的 always 語句塊&#xff0c;這是行為級建模的核心結構之一&#xff0c;在 RTL 級設計中廣泛用于時序邏輯和組合邏輯的建模。 一、什么是 always 語句&#xff1f; ? 定義&#xff1a; always 語句用于描述可綜合的硬件行為邏輯&#xff0c;表示一個**“事件驅動…

【力扣 簡單 C】704. 二分查找

目錄 題目 解法一&#xff1a;二分查找 題目 解法一&#xff1a;二分查找 int find(const int* nums, int size, int target) {int left 0, right size - 1;while (left < right){int mid (left right) / 2;if (nums[mid] < target)left left 1;else if (nums[m…

Java并發編程實戰 Day 30:并發編程未來展望與最佳實踐總結

【Java并發編程實戰 Day 30】并發編程未來展望與最佳實踐總結 文章簡述 經過30天的系統學習&#xff0c;我們從Java并發編程的基礎知識逐步深入到高并發系統的架構設計與性能優化。本文作為“Java并發編程實戰”系列的收官之作&#xff0c;將全面回顧整個系列的核心內容&#…

量化面試綠皮書:23. 醉酒乘客

文中內容僅限技術學習與代碼實踐參考&#xff0c;市場存在不確定性&#xff0c;技術分析需謹慎驗證&#xff0c;不構成任何投資建議。 23. 醉酒乘客 100名乘客排隊登機&#xff0c;每人持有一張對應座位的機票&#xff08;第n位乘客的座位號為n&#xff09;。 第一位乘客喝醉后…