图片拼接与前端四重境之渲染篇

536 阅读5分钟

垃圾话

仅以自己的学习过程为参考, 用一个小项目的渲染技术举例, 不会有具体的实现细节, 其实不管做什么技术都是一个持续学习的过程, 第一次接触前端还是jq, 当时只是做个小网页, 然后毕业后用了几个月vue, 最后入职到现在写了小半年react, 业务上没啥好玩的, 但是也花了点时间过了一些其他东西. 学了, 用不到, 不在乎, 我就是玩~  这篇算是回顾了一下自己的学习过程和作为简历吧, 算是一个阶段性的总结吧, 希望自己能永远保存热情

需求

首先我们面对的是一个简单的需求: 将图片拼起来, 类似下面这种, 主要用于拼接电影字幕

第一重 手中有剑, 心中无剑

功能

能完成基本的图片拼接, 支持调整图片大小和位置

特点

这个是初级前端的入门标准, 基本掌握js/css/html, 有一定的动手能力就行, 俗称npm调包工程师, 自学三月基本可达, 渲染的实现就是一行代码搞定, css排版, 然后直接调库, 打完收工

在这一阶段基本不会去深究类库的原理, 属于能用就行, 不能用就换, 能完成小型项目, 但想找工作有点难

想到达下一阶段, 需要对使用的工具有清晰的认识, 多去github上找找源码, 即使完全看不懂(大部分时候也确实看不懂), 也至少要知道其实现原理, 在对整体有个清晰的认识之后再去深挖其中的细节

技术实现

当时是jq一把梭, script引入dom-to-image直接一行搞定, 简单例子如下

<!DOCTYPE html><html lang="en">  <head>    <meta charset="UTF-8" />    <meta http-equiv="X-UA-Compatible" content="IE=edge" />    <meta name="viewport" content="width=device-width, initial-scale=1.0" />    <title>Document</title>    <script src="../../node_modules/dom-to-image/dist/dom-to-image.min.js"></script>    <style>      .wrap {        display: flex;        position: relative;        width: 400px;        height: 400px;      }      .box {        position: absolute;      }      .box1 {        background: url("../img/t0.png");        width: 400px;        height: 300px;        top: 0;        left: 0;      }      .box2 {        top: 300px;        left: 0;        background: url("../img/t2.png");        width: 400px;        height: 100px;      }    </style>  </head>  <body>    <div class="wrap" id="wrap">      <div class="box box1"></div>      <div class="box box2"></div>    </div>    <script>      const node = document.getElementById("wrap");      domtoimage.toPng(node).then((r) => console.log(r));    </script>  </body></html>

第二重 手中有剑, 心中有剑

功能

能够实现自由拼接并且能支持自定义滤镜, 可以实现下图中一张图两个效果, 左边卡通滤镜, 右边灰度滤镜, 能去除上下黑边

特点

达到这一阶段应该能拿到web方向的offer了, 这一阶段基本上对前端有比较清晰的认识, 能够相对深入理解需求并实现一些复杂功能

和上一阶段相比, 对于工具不再是简单使用, 而是能理解工具的作用原理, 能够选择不同的锤子和姿势去敲不同的钉子, 并且知道为什么这么选

想到达下一阶段需要自己根据具体场景造锤子

技术实现

es module, vue, react, canvas 2d, 图像处理, 打包工具

使用主流框架, canvas2d绘制, 由于支持滤镜, 不支持滤镜的话就drawImage一把梭, 支持滤镜就直接对imageData处理, 可以精确到像素, 此时需要能够理解图像格式和颜色空间, 以及滤镜原理, 有一定的工程能力, 基本迈入前端大门

第三重 手中无剑, 心中有剑

功能

支持实时渲染, 能做基础性能优化, 对于20张2k图, 逐像素处理, 就算1ms百万级的处理速度也不可能在一帧内完成

特点

基本上能拿到大厂offer, 有针对具体场景设计解决方案的能力, 开始接触兼容性这个前端最大的坑

相比上一阶段, 能够自己根据需求造出合适的轮子

想达到下一阶段那就需要跳出前端做全栈了

技术实现

worker, offlineCanvas, pwa

大量同步的计算会直接卡死主线程, 为了实现实时的效果, 用worker模拟多线程, 需要做很多工作, 防抖, 节流, 离屏渲染等, 在Safari上不支持offlineCanvas的情况下, 还需要设计能够兼容不同浏览器的接口, 在chrome上使用异步离屏渲染, Safari上使用同步版本, 为了提高速度还需要做缓存处理, 合成时直接用缓存合成图片, 为了避免异步消息乱序, 需要设计实现异步消息队列等

第四重 手中无剑, 心中无剑

功能

极致的性能和实时绘制

特点

js单线程的限制, 远远满足不了性能要求, 只能选择其他技术栈来实现, 基本上就是比较流行的全栈了

相比上一阶段, 能够不再局限于常规web技术, 而是使用其他领域的技术手段

技术实现

wasm, webgl, webgpu

使用c/c++实现核心算法, 充分利用多核能力, (但是多线程在吃大量内存的情况下比较惨...), 最后用webgl/webgpu来提升性能, 这里的实现非常简单, 因为是一个纯2d的场景, 但是能够理解背后的知识那基本上得花点时间过一遍图形学了, 完全是另外一个领域了, 而且图形学随便一个领域拿出来水都深到不可想象, 在不使用第三方库的情况下, 实现任意阶魔方, 基本上就能入门了

广告

字节前端-教育方向, 想来玩的话可以内推

要是有好玩的岗位, 也可以把我带走... (打杂, 搬砖的就算了)