2020-03 前端技术汇总

本文是2020年3月的前端技术汇总,涵盖了JSON数据转Blob还原、网页深色模式适配、canvas绘制问题、前端文件处理、MD5加密、前端框架Vue和React的思考、webpack与Parcel的区别等内容,深入探讨了前端开发中的常见问题及其解决方案。
摘要由CSDN通过智能技术生成

2020/03/30 周一

#JSON数据转Blob后,怎么还原

在axios请求下载文件接口时,一般设置responseType: ‘blob’,文件返回正常就没问题,但后台如果处理文件或鉴权有问题,接口返回了包含错误信息的json格式数据,那样json数据也会转为Blob对象,而前端有必要将错误信息展示的,那怎么将Blob数据转JSON呢?下面来看看

let fileType = res.headers['content-type']
if (fileType.startsWith('application/json')) {
  let reader = new FileReader();
  reader.addEventListener("loadend", function() {
    let data = JSON.parse(reader.result)
    console.log(data);
  });
  reader.readAsText(res.data, "UTF-8") // 加UTF-8防止中文乱码
  return
}

#2020/03/28 周六

#网页dark mode(深色模式)适配

微信最近推出了深色模式,我试了下,手机切换时页面效果样式是实时刷新的。于是就想着web怎么能够监听深色模式,并设置样式。查了资料后,在Stack Overflow上找到了答案

通过css里的媒体查询就能适配深色模式,先来看看怎么用js获取当前是否是深色模式

// 获取当前是否是深色模式
// window.matchMedia('(prefers-color-scheme: dark)').matches
window.matchMedia && console.log('Is dark mode: ', window.matchMedia('(prefers-color-scheme: dark)').matches)

// 用js监听深色模式的切换事件
window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (event) => {
  console.log('dark mode change,已' + (event.matches ? '进入': '退出') + 'dark mode')
})

window.matchMedia到底是用来做什么的?我查了下mdn,发现了这样一个示例

let mql = window.matchMedia('(max-width: 600px)');

document.querySelector(".mq-value").innerText = mql.matches;

从这个例子看,大概就知道怎么用css来支持dark模式了吧,就是加一个类似小屏适配的一个媒体查询样式,来看个例子

/* dark mode support */
@media (prefers-color-scheme: dark) {
  body {
    background-color: black;
    color: #aaa;
  }

  body .content article, header, aside > div, footer  {
    border-color: #333;
    color: #aaa;
    background-color: black;
    box-shadow: 0 0 10px #333;
  }
}

深色模式下,一般将背景调暗,字体设置为偏白色即可。zuo11.com 已用上面的方法适配了深色模式,可以体验下。网站是开源的,zuo11.com深色模式支持代码 - github(opens new window)

参考:

#2020/03/27 周五

#canvas绘制模糊的问题

今天发现同样的代码在两台电脑上绘制的一个清晰,一个模糊,后来查资料发现确实有这个问题

因为canvas不是矢量图,高dpi屏幕每平方英寸有更多的像素,也就是两倍屏,浏览器会以两个像素点的宽度来渲染一个像素,所以在Retina屏上会导致图片、文字都会模糊,怎么解决呢?

获取设备像素比:window.devicePixelRatio || 1

如果绘制的实际区域大小为 750 * 40,假设设备像素比为2,那么,canvas的width、height需要设置为 1500 * 80,然后用内联样式设置width为750,height为40,相当于canvas绘制2倍的大小,然后再缩放,这样就清晰了。

综上,在canvas绘制时,各种长度一定要考虑乘以devicePixelRatio,不然可能显示的不清晰

参考:解决 canvas 在高清屏中绘制模糊的问题(opens new window)

#2020/03/26 周四

#canvas不支持文本换行怎么处理

今天在stackoveflow里面搜索ctx.fill的问题时,查到了很多关于canvas ctx.fillText()绘制文本时不支持换行的问题,找到了一个比较好的答案

I’m afraid it is a limitation of Canvas’ fillText. There is no multi-line support. Whats worse, there’s no built-in way to measure line height, only width, making doing it yourself even harder!

一般解决思路是,根据 ctx.measureText(‘Hello’).width 来看需要显示的文字是否需要换行,写一个for循环来处理

参考:

#canvas绘制不规则形状填充渐变色

在JS高程3中,有一章专门将使用canvas绘图,今天终于用上了,效果还不错,来看效果,原生js,70行不到

cavas_unnormal_shape.png

<canvas id="drawing1" width="720" height="45" >A draw of something.</canvas>
<script>
  drawStatus('drawing1', 2)
  function drawStatus(domId, position) {
    let str = ['① 状态一', '② 状态二', '③ 状态三', '④ 状态四', '⑤ 状态五', '⑥ 状态六']
    let config = {
      width: 100,
      height: 40,
      extendLength: 20,
      radius: 4
    }
    let config2 = { ...config, width: 110 }
    let cur = str.length - position

    str.reverse().forEach((item, index) => {
      let pos = str.length - index - 1
      let x = 0 + (str.length - 1) * config.radius
      if (pos !== 0) {
        x = (pos * 100) + (pos -1) * 10 + (str.length - 1 - pos) * config.radius
      }
      console.log(pos,x)
      let curConfig = pos === 0 ? config : config2 
      if (pos < (str.length - cur)) {
        curConfig.isFocus = true
      }
      drawUnnormalShape(domId, x , 0, str[index], curConfig)
    })
  }

  function drawUnnormalShape(domId, x, y, text, config) {
    let drawing = document.getElementById(domId);
    let ctx = drawing.getContext('2d');
    let { width, height, extendLength, radius, isFocus } = config 
    ctx.beginPath(); // 如果都需要重新beginPath 不然,后面的fill会覆盖前面的fill

    // 不规则矩形
    ctx.moveTo(x + radius, y) // 从左上角 (x + radius, y) 位置开始
    ctx.arcTo(x, y, x, y + radius, radius) // 左上圆角
    ctx.lineTo(x, y + height - 2 * radius) // 画左边
    ctx.arcTo(x, y + height, x + radius, y + height, radius) // 左下圆角
    ctx.lineTo(x + width - radius, y + height) // 下边
    // ctx.arcTo(x + width - radius, y + height, x + width - radius, y + height - 1, 1) // 圆角

    let extendEndX = x + width + extendLength
    let middleHeight = y + height / 2
    ctx.arcTo(extendEndX, middleHeight, extendEndX - radius, middleHeight - radius, radius) // 线 + 圆角
    ctx.lineTo(x + width - radius, y)
    ctx.lineTo(x + radius, y)

    var gradient = ctx.createLinearGradient(x, y + height / 2, x + width + extendLength, y + height / 2); // 从(130,130)到(160,160)渐变
    gradient.addColorStop(0, isFocus ? '#62ccff' : '#fff'); // 渐变的起点色
    gradient.addColorStop(1, isFocus ? '#0486fe' : '#fff'); // 渐变的结束色

    ctx.shadowOffsetX = 6;
    ctx.shadowOffsetY = 2;
    ctx.shadowBlur = 16; // 模糊像素
    ctx.shadowColor = "rgba(58, 86, 111, 0.15)";

    ctx.fillStyle = gradient
    ctx.fill() // ctx.stroke()

    let textArr = text.split(' ')
    ctx.font = "15px arial"
    ctx.fillStyle = isFocus ? '#fff' : '#ccc'
    ctx.fillText(textArr[0], x + width / 2 - 20, y + height / 2 + 5)
    ctx.font = "11px arial"
    ctx.fillText(textArr[1], x + width / 2, y
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值