个人项目经验总结

个人项目的亮点/难点

登录态的开发

cookie、session、Token、JWT及对应的登录态机制

Canvas

定义

一块矩形画布,可以控制其中的每一像素

原理

通过控制每一个像素进行绘制,通过每一帧的绘制及更新达到动画的效果

准备

HTML
<canvas id="myCanvas" width="300" height="200"></canvas>
复制代码
JS
<script>
    var canvas = document.getElementById('myCanvas') //【DOM获取canvas节点】
    var ctx = canvas.getContext('2d');  //【绘制2D图像】
</script>
复制代码

理解

拿到一个`CanvasRenderingContext2D`对象,赋值给ctx
CanvasRenderingContext2D对象`有很多绘制方法`
复制代码

应用举例

基础操作
cxt.moveTo(10,10); // 画线条
cxt.lineTo(150,50);
cxt.lineTo(10,50);
cxt.stroke();

cxt.arc(70,18,15,0,Math.PI*2,true); // 画基本形状(此处是画圆)

ctx.fillText("Hello World",10,50); // 画文字

var img = new Image()
img.src = "flower.png"
cxt.drawImage(img,0,0); // 画图像
复制代码
高级操作 —— 像素操作

image.png

// 拷贝对应像素点的内容
<script>
    ctx.fillStyle = "green";
    ctx.fillRect(10, 10, 50, 50);
    function copy() {
        var imgData = ctx.getImageData(0, 0, 60, 60); //获取起点坐标(0,0)宽高为(60,60)区域的画布内容
        ctx.putImageData(imgData, 60, 60); // 将获取到的画布内容拷贝到起点坐标为(60,60)的位置
    }
</script>
复制代码
高级操作 —— 动画绘制

注意理解本质:canvas绘是通过不断的更新帧从而达到动画的效果

image.gif

<script type="text/javascript">
   var canvas = document.getElementById('myCanvas');
   var ctx = canvas.getContext('2d');
   var i = 0;
   function move()
   {
       ctx.fillStyle = 'red';
       ctx.fillRect(i,i,50,50);
       i++;
       if (i==350)
       {
           i=0;
           ctx.clearRect(0,0,400,400);
       }
   }
   setInterval("move()",10);   // 借助 setInterval() 进行动画绘制
</script>
复制代码

像动画、缩放、各种滤镜和像素转换等高级操作,但元素太多、操作复杂时,canvas性能下降,需要优化

优化方案

1. 分层画布

多个相互重叠的canvas根据变化程度分开渲染,越复杂的场景越适合

举个例子:一个画板,比如这样一个简单的画圆,可以看到有原来的绘画的痕迹,那就要 渲染没画圆之前的画布 -> 再画圆,鼠标移动时会清空整块画布去画圆,意味着曲线也会被清空,所以需要不断的重复执行这个渲染过程

canvas.gif

这个时候就可以使用分层画布,画画在一个上层canvas-1上,原来绘画痕迹在下层canvas-2上,那么画圆的过程就是清空 -> 画圆,画好之后再放到下层canvas-2上,这样就不需要去渲染之前的画布,就能节约性能开销

<canvas id="canvas-1"></canvas>
<canvas id="canvas-2"></canvas>
复制代码

2. 离屏渲染 —— 挥手动作优化

举个例子,想用Canvas实现一个人挥手的动作,基于Canvas的原理是每一帧每一帧的绘制然后更新来达到这个效果,显然前前后后要绘制很多帧相似度极高的图片,所以我们采用离屏渲染的方式来进行优化

  • 实现原理

屏幕内创建一块canvas-1画布画除了手以外的部分(不变的部分),在屏幕外再创建另一块canvas-2画布画挥手的部分(变化的部分),将canvas-2绘制的一帧帧画面通过drawImage()的方式拷贝到canvas-1上,相比于只在canvas-1上面画整个画面要快很多

  • 注意事项

并不是说离屏渲染就一定可以提升性能,如果说整个画面每一帧都在变化,那这时非离屏渲染要比离屏渲染好,因为拷贝的过程(也就是drawImage时)也相应地会造成性能损耗

3. 背景图片如果不变的话可以直接用图片放到最底层

如果像大多数游戏那样,你有一张静态的背景图,用一个静态的<div>元素,结合background 特性或<img>标签,将它置于画布元素之后。这么做可以避免在每一帧在画布上绘制大图。

4. 尽量使用整数坐标而不是浮点数

  • 原因:浏览器为了达到抗锯齿的效果会做额外的运算,会造成一定的性能损耗
  • 解决:尽量使用整数坐标而非浮点数坐标【整数坐标计算更加简便】

懒加载优化

在一个列表里,有很多图片,采用懒加载优化可以加快首次进入该页面的加载速度

  • 刚进入页面时,只加载20张图片
  • 通过监听触底事件再请求服务端数据库获取20张图片然后拼接起来

如何监听触底事件:

  • 方法一:对 scrollTop + windowHeightscrollHeight 比较
lazyload();//首次加载别忘了显示图片
window.addEventListener('scroll', lazyload); // 监听滑动条滑动
function lazyload() {
    var scrollTop = document.documentElement.scrollTop //当前屏幕顶部到滚动条顶部的距离
    var clientHeight = document.documentElement.clientHeight //屏幕可视区的高度
    var scrollHeight = document.documentElement.scrollHeight //滚动条的总高度
    if(scrollTop + windowHeight + 50 == scrollHeight){ 
        /*开始请求加载图片,可以先预留50px出来*/
    }
}
复制代码
  • 方法二:利用DOM 元素的 getBoundingClientRect API 获取其所处到滚动条顶部的距离
img[i](将要加载的图片).getBoundingClientRect().top < document.documentElement.clientHeight
复制代码
  • 需要优化的点 —— 节流
window.addEventListener('scroll', throttle(lazyload,200)); // 200ms内只触发一次

// 节流函数
function throttle(fn, interval) {
    let flag = true; //节流开关
    return function(...args) {
        let context = this;
        if (!flag) return; // interval毫秒内开关处于未打开状态,直接跳过
        flag = false; // 走到这里表示开关是打开的,可以执行动作,进入后立即关闭开关
        setTimeout(() => {
            fn.apply(context, args); // 执行动作
            flag = true; // 打开开关
        }, interval); // interval毫秒后打开开关
    };
};

复制代码

其他关于图片加载的详见 浏览器系列 — 优化网页图片加载

自适应布局

不同机型不同屏幕大小的适配是前端开发的重点突破对象
自适应方案有:

各单位区别

  • px: 像素(Pixel)。绝对单位。像素 px 是相对于显示器屏幕分辨率而言的,1px等于一个像素点的大小,是计算 机系统的数字化图像长度单位。
  • em:相对于父级元素的字体大小,因此并不是一个固定的值。如当前对行内文本的字体尺寸未被人为设置, 则相对于浏览器的默认字体尺寸
  • rem:是 HTML 根元素的字体大小(1rem等于字体大小)
  • vw:1vw 等于屏幕宽度1%
  • vh:1vh 等于屏幕高度1%

基于锚点思想同步分类栏和滚动条

666.jpg

点击左侧分类栏,右侧滚动条同步

直接调用 API 控制滚动条位置

// web端
window.scrollTo(0,document.body.scrollHeight)
// 小程序端
wx.pageScrollTo({
  scrollTop: 0,
  duration: 300
})
复制代码

滑动右侧滚动条,左侧分类栏同步

需要监听滑动条所处位置

// web端
// 小程序端
bindscroll: function(e){
    console.log(e.scrollTop)
}
复制代码

需要优化的点:频繁地修改data里面的值

方法是:节流

自定义组件及优化

参考文章

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享