You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Tilda站点Canvas故障动画在Safari显示黑屏问题求助

Safari中Canvas Glitch动画黑屏问题排查与修复

核心问题分析与修复步骤

1. 变量引用顺序错误(初始化直接报错)

你的代码中resize()函数在mesh创建前就被调用,此时mesh未定义,会抛出ReferenceError直接终止WebGL渲染流程,这是黑屏的核心原因。

修复方案:
将resize事件监听和resize()调用,移到mesh创建完成之后:

// ... 创建program、mesh之后
const mesh = new ogl.Mesh(gl, { geometry, program });

// 移到此处执行
window.addEventListener("resize", resize, false);
resize();

2. 图片加载与纹理初始化时机不匹配

当前代码在图片未加载完成时就创建了渲染程序和网格,Safari对未初始化的纹理处理更严格,直接导致渲染黑屏。

修复方案:
把所有依赖纹理的初始化逻辑(program、mesh、事件监听、渲染启动等)放到图片onload回调中,确保纹理加载完成后再启动渲染:

const img = new Image();
img.crossOrigin = "Anonymous";
img.onload = () => {
  texture.image = img;

  // 计算纹理适配参数
  let a1, a2;
  const imageAspect = imgSize[1] / imgSize[0];
  if (window.innerHeight / window.innerWidth < imageAspect) {
    a1 = 1;
    a2 = window.innerHeight / window.innerWidth / imageAspect;
  } else {
    a1 = (window.innerWidth / window.innerHeight) * imageAspect;
    a2 = 1;
  }

  // 创建渲染程序与网格
  const program = new ogl.Program(gl, {
    vertex,
    fragment,
    uniforms: {
      uTime: { value: 0 },
      tWater: { value: texture },
      res: {
        value: new ogl.Vec4(window.innerWidth, window.innerHeight, a1, a2)
      },
      img: { value: new ogl.Vec2(imgSize[0], imgSize[1]) },
      tFlow: flowmap.uniform
    }
  });
  const mesh = new ogl.Mesh(gl, { geometry, program });

  // 绑定resize事件
  window.addEventListener("resize", resize, false);
  resize();

  // 绑定鼠标/触摸事件
  const isTouchCapable = "ontouchstart" in window;
  if (isTouchCapable) {
    window.addEventListener("touchstart", updateMouse, false);
    window.addEventListener("touchmove", updateMouse, { passive: false });
  } else {
    window.addEventListener("mousemove", updateMouse, false);
  }

  // 启动渲染循环
  requestAnimationFrame(update);
};
img.src = "https://dl.dropboxusercontent.com/s/064wgjmnq6m49ca/глитч%20фон.jpg?dl=1";

3. 非2幂纹理的Wrap模式兼容问题

你的图片尺寸为1650x1000(非2的幂次方),OGL默认纹理Wrap模式为REPEAT,Safari不支持非2幂纹理使用该模式,会导致纹理失效。

修复方案:
创建Texture时显式设置Wrap模式为CLAMP_TO_EDGE:

const texture = new ogl.Texture(gl, {
  minFilter: gl.LINEAR,
  magFilter: gl.LINEAR,
  wrapS: gl.CLAMP_TO_EDGE,
  wrapT: gl.CLAMP_TO_EDGE
});

4. 片段着色器精度兼容性优化(可选)

部分旧版Safari对highp精度支持有限,可添加降级声明:

// 片段着色器开头修改为
precision highp float;
precision highp int;
#ifdef GL_ES
precision mediump float;
#endif

内容的提问来源于stack exchange,提问作者Rodion Roddion

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 13:37:01