从灭霸的无限手套说起

栏目: Html5 · 发布时间: 5年前

内容简介:本文不是技术文章,只是单纯记录下前两天看到Google搜索有个彩蛋,搜索

本文不是技术文章,只是单纯记录下

最近妇联4在热映,先剧透两个精彩片段。

从灭霸的无限手套说起

从灭霸的无限手套说起

前两天看到Google搜索有个彩蛋,搜索 灭霸 或者 thanos ,点击右边的无限手套触发彩蛋,打个响指,消灭一半的搜索结果条目,消失特效类似电影里的。

从灭霸的无限手套说起

首先分析下这个彩蛋主要包括

  1. 点击手套动画效果
  2. 消失的搜索条目的粒子效果

接下来是从以下方面着手

  1. html页面
  2. DOMcanvas
  3. 粒子效果
  4. 其他包括音效、页面平滑滚动等

html页面(扒网页)

首先排除扒Google搜索页面,因为服务器用的是国内阿里云访问不了。

然后就打算扒百度的搜索页,用的是 PHP 程序,我知道的能够获取页面代码的有 file_get_contentcURL 函数,虽然拿到了页面代码,但是只要搜索结果那些DOM的话用正则比较麻烦,搜了下找到 phpQuery 库,它能像 jQuery 操作那样拿到指定DOM,和Node.js的 cheerio 包类似。但是百度的这个页面样式类是动态的,还要把整个style内容也输出,而且很多图片大概是经过了什么处理,没权限显示不了,遂放弃。

接着扒斗鱼的直播列表页,返回一堆乱码,实力告退了。最后选择了相似的 企鹅电竞直播列表页 ,页面算是搞定了。

DOM转canvas

前端有 html2canvasdom-to-image 两个库可以把页面指定元素转化为画布或图片, html2canvas 比较有名些,早期我也是用这个库做前端截图功能( https://imusic.github.io/clip/ ),但是它对CSS3的处理并不好,后来我发现了 dom-to-image 这个库,它对CSS3的处理就比较好了,而且体积更小,所以又用这个库替换了( https://demo.vczhan.com/clip/ )。

从灭霸的无限手套说起

不过因为要转化的内容里有跨域的图片,canvas对此做了限制,我们需要对图片做代理处理。 dom-to-image 这个库并没有提供相关的代理插件,最后还是用 html2canvas 这个库。页面没有复杂的元素,并且这个库近来做了更新,对CSS3支持好了些,作者还提供了两种语言的代理,分别是 Python版本 的和 Node.js版本 的,不过我选择了其他人写的 PHP版本 。前端只要配置相关参数就可以。服务器端则会在文件目录下新建 cache 目录存放图片并返回给前端渲染到画布上。(不知能否改成不存储图片文件而是改成输出base64或者blob数据)

html2canvas(node, {
  proxy: 'html2canvasproxy.php'
}).then(canvas => {
  // do stuff
})

粒子效果

粒子效果比较难的部分是怎么调整各个参数到合适的值还要保证动画不卡。其实js计算过程并不会让动画卡顿,主要瓶颈在渲染阶段。

渲染部分原来用遍历粒子直接绘制,但因为粒子较多,动画看起来有点卡。

render() {
  context.clearRect(0, 0, sw, sh)

  let particles = this.particles

  for (let i = 0, particle; particle = particles[i++];) {
    if (particle.state === 'dead') continue

    context.save()
    context.translate(particle.x, particle.y)

    context.fillStyle = particle.color
    context.globalAlpha = particle.alpha
    context.beginPath()
    context.fillRect(0, 0, 1, 1)
    context.restore()
  }
}

后来改成每次渲染时,先得到空白画布的图像数据,然后遍历粒子,给图像数据对应的位置加上 rgba ,最后将图像数据放回画布。

render() {
  // context.clearRect(0, 0, sw, sh)
  let particles = this.particles

  const imageData = context.createImageData(sw, sh)
  const buffer32 = new Uint32Array(imageData.data.buffer)

  for (let i = 0, particle; particle = particles[i++];) {
    if (particle.state === 'dead') continue

    const {x, y, color: {r, g, b}, alpha: a} = particle
    const pos = y * sw + x

    buffer32[pos] = r | (g << 8) | (b << 16) | (a << 24)
  }

  context.putImageData(imageData, 0, 0)
}

Google那个页面是用了多个canvas,可以参考下面的粒子

https://codepen.io/birjolaxew...

其他

其他就是些细节调整,比如点击手套的过渡动画并加上音效,过渡时间和延迟要慢慢调到合适的使动画与音效对应。当某个DOM要消失也要加上音效,并且页面平滑滚动,使其位于屏幕中心,可以直接用 scrollIntoView 这个方法。

node.scrollIntoView({behavior: 'smooth', block: 'center'})

素材都可以从Google彩蛋页里提取,还有其他一些细节就不逐一赘述了。

最后放上本次的 demo


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Agile Web Application Development with Yii 1.1 and PHP5

Agile Web Application Development with Yii 1.1 and PHP5

Jeffrey Winesett / Packt Publishing / 2010-08-27

In order to understand the framework in the context of a real-world application, we need to build something that will more closely resemble the types of applications web developers actually have to bu......一起来看看 《Agile Web Application Development with Yii 1.1 and PHP5》 这本书的介绍吧!

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具