不知道大家有没有看这段时间最火的一部电影《复仇者联盟4:终局之战》,作为漫威迷的我还没看,为什么呢?因为太贵了,刚上映的那周,一张IMAX厅的票价已经达到了299的天价,作为搬砖民工是舍不得花这么高的钱来看一场电影的,太奢侈了,当然也可能我是个假漫威迷吧,哈哈哈哈逃~

我刚看下现在的票价,IMAX厅是89元,已经接近正常,虽然还是些许偏高,但是已经可以接受了。对于看电影,我并不是那么崇尚看首映,或者非要第一时间看到,但是对于喜欢的电影我一定会找个最佳的位置观看,现在票价合理,最佳观影区充足,正是看电影的好时机。从这方面看,我可能只算是一个漫威爱好者,而绝不是一个狂热者。

而今天要说的主题自然和漫威有关,是一个Google的小彩蛋。想必大家已经知道了,在Google中搜索“灭霸”,然后在右侧点击的“无限手套”,页面的一些搜索项就会随机性像沙子一样的消失(后面统称沙化效果),特别的炫酷。有不知道的可以看下面的动图:

我觉得特别有意思,就参考了一些文章,实现了类似上面的沙化效果。

首先我制作了一个模板如下,点击按钮后,列表随机沙化(手套的效果是很多图片的合成,这里就不处理了)。

模板代码如下:

<div class="box">
<div class="bomb">啪嗒!</div>
<ul>
<li class="item">
<h3>襟三江而带五湖,控蛮荆而引瓯越。</h3>
</li>
<li class="item">
<h3>潦水尽而寒潭清,烟光凝而暮山紫。</h3>
</li>
<li class="item">
<h3>落霞与孤鹜齐飞,秋水共长天一色。</h3>
</li>
<li class="item">
<img src="./1.jpg" />
</li>
</ul>
</div>

样式就不贴了,后面会给出源码。

然后我们一步步说明如何实现沙化效果。

首先,我们将每一个li元素的沙化封装成一个函数 disintegrate ,这个函数参数就是要沙化的目标元素,这里是li元素。

一、实现原理

简单来说就是将页面的元素先转化为canvas,然后提取出所有的像素点分别按照规律排布在32个canvas上面,,再将这些canvas转换为和原始元素大小一样的dom元素堆叠在一起,看起来就和原始元素一样的,然后将原始元素隐藏。最后将这些堆叠在一起的元素散开,就形成“沙化”的效果。

二、实现步骤

首先引入 html2canvas 插件。

由于需要将页面的元素转换成 canvas 图像,所以要用到 html2canvas 插件(插件可自行到官网下载,官网地址:https://html2canvas.hertzen.com/)。

<script src="./html2canvas.js"></script>

接着将元素转化为32个canvas。

创建32个canvas(当然,个数越多,沙子就越细),把元素的每一个像素复制到这32个canvas上面,这个每个canvas上面都会有一部分元素的像素点,加起来就是整个元素所有的像素点。(具体的代码作用,参考每句代码的注释)

html2canvas(ele).then(dom => {
const { width, height } = dom; // canvas宽高 let ctx = dom.getContext('2d'); // canvas绘图对象 // 返回一个ImageData对象,用来描述canvas区域隐含的像素数据,这个区域通过矩形表示,起始点为(sx, sy)、宽为sw、高为sh。
let originalFrame = ctx.getImageData(0, 0, width, height); // 创建一个32个新的、空白的、指定大小的 ImageData 对象。 所有的像素在新对象中都是透明的。
let frames = [];
for (let i = 0; i < COUNT; i++) {
frames[i] = ctx.createImageData(width, height);
} // 将canvas所有的数据随机复制到32个frames上面
for (x = 0; x < width; ++x) {
for (y = 0; y < height; ++y) {
// frames 的下表索引值。
// 不是一般的(从0到COUNT的)随机值,而是递增的随机数,为了将像素点先集中在前几个frame,然后再往后集中,否则32个frames钟的像素太分散。
var frameIndex = Math.floor((COUNT * (Math.random() + (2 * x) / width)) / 3); // imageData.data:描述一个一维数组,包含以 RGBA 顺序的数据,数据使用 0 至 255(包含)的整数表示。
// 数组的个数为 width*height*4,所以除了宽乘高以外还要乘以4
var pixelIndex = 4 * (y * width + x); // 之所以要循环4次是因为上面乘了4,得到的 pixelIndex 在 width*height*4 范围内会有一些空缺,所以要补上这些空缺,保证所有的canvas像素全部复制到32个frames上面
for (offset = 0; offset < 4; offset++) {
frames[frameIndex].data[pixelIndex + offset] = originalFrame.data[pixelIndex + offset];
}
}
}
});

然后将这32个分布了不同像素点的 ImageData 对象转换成原始li元素大小的dom元素,用一个容器container来容纳,然后将容器覆盖到原始li元素的位置,现在就相当于每个li元素的位置是一个container元素,这个container元素内容是32个dom元素,这32个dom重叠起来的样子和原始li元素是一样的。

// 创建一个div容纳frames
let container = document.createElement('div');
container.classList.add('container');
container.style.width = `${width}px`;
container.style.height = `${height}px`; // 将所有包含RGBA数据的frames绘制到绘图中,生成32份和原始dom一样的元素,只是内容不同,最后将这些元素放入container中。
let frames2doms = frames.map((frameData, i) => {
let domCopy = dom.cloneNode(true);
domCopy.getContext('2d').putImageData(frameData, 0, 0); // 将数据从已有的 ImageData 对象绘制到位图的方法。
domCopy.style.transitionDelay = `${(1.35 * i) / frames.length}s`; //过渡效果开始前的delay时间(可自行调整),使得frames先从下标小的开始运动。
container.appendChild(domCopy);
return domCopy;
});

现在我们看到的效果和原始的是一样的,但是所有的li元素被隐藏了起来,显示的是由许许多多零散的元素拼凑出来的假象。目前所有的零散元素是聚集在一起的,我们只需要有规律的让他们动起来,动到一定位置后再让它们不可见,感觉就像沙化的效果一般。

// 让所有的canvas动起来
// 原始dom相对定位,container绝对定位
ele.classList.add('disintegrated');
ele.appendChild(container);
ele.style.border = '0';
container.offsetLeft; // 没有该句,则无法实现动画效果 // 为32份不同内容的dom元素添加过渡效果(可自行调整)
frames2doms.map(item => {
let random = 2 * Math.PI * (Math.random() - 0.5);
item.style.transform = `
rotate(${15 * (Math.random() - 0.5)}deg)
translate(${60 * Math.cos(random)}px, ${30 * Math.sin(random)}px)
rotate(${-15 * (Math.random() - 0.5)}deg)
`;
item.style.opacity = 0;
});

三、实验效果

点击按钮之后,每个li元素位置的32个dom旋转跳跃并闭上眼,哦不是逐渐消失。因为每个dom上都只有一些小点而且在向不同的方向扩散,所以感觉上就像沙化了。

四、注意事项

如果元素中有图片的话,需要使用服务器的方式加载,不能使用本地浏览器直接打开,否则包含图片的元素无法沙化。

想要了解更多前端方面的内容可以关注我的微信公众号[前端队长],我们一同成长,一同领略技术与生活“落霞与孤鹜齐飞,秋水共长天一色”的美好。

关注公众号,后台回复“灭霸”获取源码和素材。

参考链接:https://www.weibo.com/1727858283/HrxYFq0fG?type=comment

弹指间,网页灰飞烟灭——Google灭霸彩蛋实现的更多相关文章

  1. Google 灭霸 彩蛋

    Google 灭霸 彩蛋 在Google中搜索"灭霸",然后在右侧点击的"无限手套",页面的一些搜索项就会随机性像沙子一样的消失(后面统称沙化效果),特别的炫酷 ...

  2. Chrome 中的彩蛋——T-Rex

    今天,从网页上看到chrome的T-Rex的彩蛋,眨眼间完了10分钟.分享出来,只是好玩. 当 Chrome 无法连接到互联网时,或者上着网突然掉线,刷新页面时报错,我们都会看到T-Rex的身影,没错 ...

  3. cookie初探——封装和使用cookie(内含彩蛋)

    一.什么是cookie? 页面用来保存信息,如:自动登录.记住用户名 二.cookie的特性1.同一个网站中所有页面共享一套cookie2.数量.大小有限3.有过期时间 三.js中使用cookie d ...

  4. Chrome 中的彩蛋,一款小游戏,你知道吗?

    今天看到一篇文章,介绍chrome中的彩蛋,带着好奇心进去看了一眼,没想到发现了一款小游戏,个人觉得还不错,偶尔可以玩一下,放松放松心情!^_^ 当 Chrome 无法连接到互联网时, 或者上着网突然 ...

  5. [深入浅出Windows 10]模拟实现微信的彩蛋动画

    9.7 模拟实现微信的彩蛋动画 大家在玩微信的时候有没有发现节日的时候发一些节日问候语句如“情人节快乐”,这时候会出现很多爱心形状从屏幕上面飘落下来,我们这小节就是要模拟实现这样的一种动画效果.可能微 ...

  6. 阻止PHP彩蛋信息泄漏 [转]

    Easter Eggs(复活节彩蛋)外行人估计不了解这是神木玩意,彩蛋的网络解释是:用于电脑.电子游戏.电脑游戏.影碟或其他互动多媒体之中的隐藏功能或信息.PHP包含一个安全漏洞,可能导致未经授权的信 ...

  7. Python彩蛋--zen of python

    今天早上在公交上浏览博客的时候,发现了python里面的一个小彩蛋--zen of python 一首python之歌 我们来看一看... ​ 是不是很简单,在python shell 里 输入 im ...

  8. .NET开发者的机遇与WebAssembly发展史(有彩蛋)

    一.唠唠WebAssembly的发展历程 目前有很多支持WebAssembly的项目,但发展最快的是Blazor,这是一个构建单页面的.NET技术,目前已经从Preview版本升级到了beta版本,微 ...

  9. Python彩蛋、字典、列表高级用法、元类、混入、迭代器、生成器、生成式、git

    一.类与类的关系 关注公众号"轻松学编程"了解更多. is-a 继承 继承是指一个类(称为子类.子接口)继承另外一个类(称为父类.父接口)的功能, 并可以增加它自己的新功能的能力. ...

随机推荐

  1. php5.4.16执行shell脚本

    因为要用到Python脚本,所以打算直接在PHP中直接调用系统命令system(). 要注意两点: 一.PHP5.3以上不存在安全模式,即要直接执行脚本不需要作任何其他配置. 二.system函数格式 ...

  2. 【玩转SpringBoot】翻身做主人,一统web服务器

    寄人篱下的日子 一直以来受传统影响,我们的web工程总是打成war包,然后放入tomcat的webapps目录下面. 如下图01: 当tomcat启动时,会去解压war包,然后运行web工程.这大家都 ...

  3. (2019版本可用)Pycharm的安装,破解

    前言 python的操作工具pycharm,是专门用来写python语言的. 因为之前在网上找到了,但是太麻烦了,所以整理整理. pycharm安装 官网可以选择下载(pycharm最新版有可能破解不 ...

  4. [ASP.NET Core 3框架揭秘] 依赖注入[8]:服务实例的生命周期

    生命周期决定了IServiceProvider对象采用怎样的方式提供和释放服务实例.虽然不同版本的依赖注入框架针对服务实例的生命周期管理采用了不同的实现,但总的来说原理还是类似的.在我们提供的依赖注入 ...

  5. 微信小程序视图层介绍及用法

    一. 视图层 WXML(WeiXin Markup Language)是框架设计的一套标签语言,结合基础组件.事件系统,可以构建出页面的结构. 1.1. 数据绑定 1.1.1. 普通写法 <vi ...

  6. C#线程学习笔记三:线程池中的I/O线程

    本笔记摘抄自:https://www.cnblogs.com/zhili/archive/2012/07/20/MultiThreads.html,记录一下学习过程以备后续查用.     一.I/O线 ...

  7. CentOS 7上的进程管理

    一些杂乱的基础概念 程序是一种静态的文件,躺在磁盘上.而进程则是将程序运行起来放置于内存中.因此进程就是运行中的程序,是程序运行起来的一个实例.同一个程序可以运行为多个进程/实例. 进程之间有父子关系 ...

  8. Kali_Linux 中文乱码 修改更新源及更新问题

    Kali_Linux 中文乱码 修改更新源及更新问题 中文乱码问题 kali默认没有中文字符 当以中文安装或者切换编码换为中文后会出现乱码的情况 解决方法: 确定locales已经安装好, 使用 ap ...

  9. 数据卷(Data Volumes)

    Docker宿主机和容器之间文件拷贝docker copy 前言: Docker 数据管理 在生产环境中使用 Docker ,往往需要对数据进行持久化,或者需要在多个容器之间进行 数据共享,这必然涉及 ...

  10. 如何安装 IntelliJ IDEA 最新版本——详细教程

    IntelliJ IDEA 简称 IDEA,被业界公认为最好的 Java 集成开发工具,尤其在智能代码助手.代码自动提示.代码重构.代码版本管理(Git.SVN.Maven).单元测试.代码分析等方面 ...