使用 JavaScript 实现仿 Flash 风格的图片遮罩展开动画

清欢
清欢
发布时间:2026-10-13| 2人浏览过
原创

本文详解如何使用 JavaScript 和 jQuery 实现仿 Flash 的九宫格遮罩展开动画。通过动态分割容器为9个区域并控制其显示与隐藏,打造独特的视觉过渡效果。

实现原理与目标

仿 Flash 遮罩动画的核心在于将一张图片或一个容器视为被切割的九宫格。随着动画进行,中间的格子(第5块)保持透明并逐渐扩大,而周围八个格子(1-4, 6-9)作为遮罩层逐渐缩小直至消失,从而显露出下方原本被遮挡的内容。这种效果常用于网页 Banner 切换或加载过渡,增加页面的动态感。

准备条件

  1. HTML 结构:需要一个固定宽高且 overflow: hidden 的容器,用于放置背景图片或内容。
  2. 依赖库:建议使用 jQuery 以简化 DOM 操作和样式设置。虽然纯原生 JS 也可实现,但 jQuery 在旧版浏览器兼容性上更有优势,适合此类复古特效。
  3. 资源文件:确保 jquery.js 已正确引入。

第1步:构建 HTML 骨架

定义一个外层容器 #banner,内部包含你想要展示的图片。设置容器宽度、高度并隐藏溢出部分,确保遮罩层不会破坏布局。

<div id="banner" style="position:relative;width:858px;height:238px;overflow:hidden;">
  <img src="path/to/your/image.jpg" width="858" height="238" alt="Banner Image" />
</div>

第2步:封装遮罩动画函数

创建一个全局函数 setMaskingAnimation,接收容器选择器、尺寸、时间间隔、像素速度和颜色等参数。该函数负责初始化随机起点、计算速度比例以及管理动画循环。

function setMaskingAnimation(container, width, height, time, pixel, color) {
  // 随机初始位置和大小参数
  var __left = mtRand(parseInt(width * 0.25), parseInt(width * 0.75));
  var __top = mtRand(parseInt(height * 0.25), parseInt(height * 0.75));
  
  // 根据宽高比调整移动速度,保持视觉平衡
  var widthSpeed, heightSpeed, __width, __height;
  if (width >= height) {
    widthSpeed = parseInt((width / height) * 10);
    heightSpeed = 10;
  } else {
    widthSpeed = 10;
    heightSpeed = parseInt((height / width) * 10);
  }
  __width = widthSpeed;
  __height = heightSpeed;
  
  var hander;
  // ... (后续逻辑见步骤3)

第3步:动态计算九宫格位置与渲染

动画的关键在于 getPosition 和 setDiv 函数。每帧调用时,根据当前中心块的尺寸 (__width, __height) 和位置 (__left, __top),计算出周围8个遮罩块的具体 CSS 属性(left, top, width, height)。

  • 中心块(div5):设置为 background-color: transparent,形成“洞口”。
  • 周围块:填充指定颜色(通常为黑色或深色),形成遮罩。
  function getPosition(_width, _height, _left, _top) {
    return {
      'div1': { width: _left, height: _top, left: 0, top: 0 },
      'div2': { width: _width, height: _top, left: _left, top: 0 },
      'div3': { width: width - _left - _width, height: _top, left: _left + _width, top: 0 },
      'div4': { width: _left, height: _height, left: 0, top: _top },
      'div5': { width: _width, height: _height, left: _left, top: _top }, // 中心透明
      'div6': { width: width - _left - _width, height: _height, left: _left + _width, top: _top },
      'div7': { width: _left, height: height - _top - _height, left: 0, top: _top + _height },
      'div8': { width: _width, height: height - _top - _height, left: _left, top: _top + _height },
      'div9': { width: width - _left - _width, height: height - _top - _height, left: _left + _width, top: _top + _height }
    };
  }
  
  function setDiv(i, position) {
    var has = $(container).find('div.mask' + i);
    var htmlTemplate = '<div class="mask mask@{i}" style="position:absolute;left:@{left}px;top:@{top}px;width:@{width}px;height:@{height}px;background-color:@{backgroundColor};"></div>';
    
    if (has.length) {
      // 若元素已存在,直接更新样式,提升性能
      has.css({
        left: position.left,
        top: position.top,
        width: position.width,
        height: position.height
      });
    } else {
      // 首次创建,替换模板中的占位符
      htmlTemplate = htmlTemplate.replace('{@i}', i)
        .replace('{@left}', position.left)
        .replace('{@top}', position.top)
        .replace('{@width}', position.width)
        .replace('{@height}', position.height)
        .replace('{@backgroundColor}', (i == 5 ? 'transparent' : color));
      $(container).append(htmlTemplate);
    }
  }

第4步:执行动画循环与清理

使用 setInterval 定时调用 play 函数。play 函数中:

  1. 状态更新:根据设定的像素速度和方向,调整中心块的大小和位置参数。
  2. 重绘:调用 getPosition 获取新坐标,遍历 1-9 调用 setDiv 更新或创建 DOM 元素。
  3. 结束判断:当四周的遮罩块(如 div1 和 div9)尺寸缩小至接近 0 时,清除定时器并移除所有遮罩 div,露出完整图像。
  function play() {
    __width += pixel * widthSpeed;
    __height += pixel * heightSpeed;
    __left -= pixel * widthSpeed / 2;
    __top -= pixel * heightSpeed / 2;
    
    var position = getPosition(__width, __height, __left, __top);
    for (var i = 1; i <= 9; i++) {
      setDiv(i, position['div' + i]);
    }
    
    // 检查是否完成:四角尺寸归零则停止
    if (position.div1.width <= 0 && position.div1.height <= 0 && 
        position.div9.width <= 0 && position.div9.height <= 0) {
      window.clearInterval(hander);
      $(container).find('div.mask').remove();
    }
  }
  
  hander = window.setInterval(play, time);}

调用方法与参数说明

在 DOM 加载完成后调用函数。参数依次为:容器选择器、总宽、总高、动画时长(ms)、每次移动的基准像素值、遮罩颜色。

$(function(){
  // 示例:针对 #banner 元素,宽858高238,每100ms触发一次,每次扩展基准值为2px,遮罩色为红色
  setMaskingAnimation("#banner", 858, 238, 100, 2, "#ff0000");
});

关键参数技巧

  • 第四参数 (time):建议设为 50-100ms。越小动画越流畅但 CPU 负载越高;越大则卡顿。
  • 第五参数 (pixel):必须为偶数。因为动画向四个方向对称扩展/收缩,基数为偶数可避免像素对齐问题导致闪烁。通常 2-5 之间效果最佳。
  • 速度协调:代码内部已通过宽高比自动调整 X/Y 轴速度,无需手动干预,保证遮罩口近似正方形扩张。

完成判断与排错

若动画未执行,请检查:

  1. 控制台是否有 $ is not defined 错误,确认 jQuery 引入顺序无误。
  2. 容器 #banner 是否具有明确的 width 和 height,否则计算出的遮罩位置可能异常。
  3. 图片路径是否正确,确保背景层可见。

简要总结

以上是通过 JavaScript 结合 jQuery 实现仿 Flash 风格九宫格遮罩动画的详细内容。该方案通过动态分割 DOM 空间模拟遮罩效果,代码结构清晰,易于集成到现有项目中。更多关于前端动画技巧的资料请关注本站其它相关文章!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。