canvas在H5中的绘图总结

一、canvas使用场景介绍

需求:用户在H5里面答题,然后根据得分情况生成一个奖状,奖状上会显示用户的个人信息(微信昵称、答题时间),奖状可以保存,实际效果如下图所示。

二、项目中遇到的坑

1、把奖状背景图绘制到canvas上,会出现图片和文字模糊问题;

2、用户微信昵称绘制到奖状上的红线位置,需要在红线区域居中,但是用户昵称千奇百怪,较难处理;

3、奖状上的绘制的文字字体大小在移动端需要自适应。

三、解决方案

1、问题1解决方案:

(1)canvas中存在两种尺寸:

 canvas 的 width/height 是画布的宽/高,用来确定这个画布的内容大小,类似于 img 标签中的图片的宽高属性;
 canvas 的 样式表里的 width/height 代表的是最终绘制到浏览器上的尺寸,是 canvas 的物理宽度,
 类似于 img 标签中 样式表中设置的宽高属性。
复制代码

(2)图片和文字模糊原因

 canvas 中属性的宽高并不代表实际的宽度,所以在高分辨率设备下(高清屏),浏览器就会放大 canvas,导致模糊;
 canvas 的最小单位是像素,通常情况下,设备的一个像素可以绘制一个点,
 但是当 window.ddevicePixelRatio > 1 |的时候,设备就会用大于1的像素个数绘制 canvas
 上的一个点,这时候如果还按照原始的画布大小去绘制图片或者文字时,看到的线条就比较粗,出现模糊的现象。
复制代码

(3)根据 devicePixelRatio 的值,放大 canvas 的内容大小,去掉模糊效果

const canvasBg = new Image(); //省略奖状图片地址
let canvas = document.getElementById("myCanvas");
canvasBg.onload = () => {
    let ctx = canvas.getContext("2d");
    let getPixelRatio = function (context) {
          let backingStore = context.backingStorePixelRatio ||
            context.webkitBackingStorePixelRatio ||
            context.mozBackingStorePixelRatio ||
            context.msBackingStorePixelRatio ||
            context.oBackingStorePixelRatio ||
            context.backingStorePixelRatio || 1;
            
          return (window.devicePixelRatio || 1) / backingStore;
        };
}
let ratio = getPixelRatio(ctx);  //获取设备物理像素与设备独立像素的比例
let imgW = canvasBg.width;
var imgH = canvasBg.height;
canvas.width = $(window).width() * ratio;  //放大画布内容的宽度
canvas.height = imgH * $(window).width() / imgW * ratio;  //放大画布内容的高度
let cW = $('#myCanvas').width();
let cH = $('#myCanvas').height();
canvas.style.width = "100%";
ctx.drawImage(canvasBg, 0, 0, cW, imgH * cW / imgW);  //把奖状模板绘制到canvas上,自适应奖状背景图,不拉伸或压缩图片
复制代码

2、问题2解决方案:

(1)解决思路:

 先计算奖状上红线的宽度,然后在计算出用户昵称的宽度,对于超过红线宽度的用户昵称做特殊处理,
 截断超过红线的字符串,用省略号替代
复制代码
    //截取字符串方法,参数1为传入的用户昵称,参数2为要截取的字符串长度
    function cutstr(str, len) {
     var str_length = 0,
       str_cut = new String(),
       str_len = str.length;
     var charAtStr;
     for (var i = 0; i < str_len; i++) {
       //获取str字符串指定位置的字符
       charAtStr = str.charAt(i);
       str_length++;
       //中文字符的长度经编码之后大于4,其他字符小于4,因此中文字符占两位,其他字符占一位
       if (escape(charAtStr).length > 4) {
         str_length++;
       }
       str_cut = str_cut.concat(charAtStr);
       if (str_length >= len) {
         str_cut = str_cut.concat("..");
         return str_cut;
       }
     }
     //如果给定字符串小于指定长度,则返回源字符串;
     if (str_length < len) {
       return str;
     }
   }
 }
 let userInfo = {
     userName: "xxx张小二xxx"
 };
 let paddingLeft = 0;  //居中的字符串距离 canvas 左边界的距离
 //ctx.measureText(userInfo.userName).width 为字符串的宽度
 //146 * $('#myCanvas').width() / 727 * ratio 根据比例算出红线的宽度
 if (ctx.measureText(userInfo.userName).width > 146 * $('#myCanvas').width() / 727 * ratio) {
     userInfo.userName = cutstr(userInfo.userName, 8);
  }
  //魔鬼数字为固定尺寸奖状上的某些元素的宽度,然后在根据比例求出
  paddingLeft = 68 * $('#myCanvas').width() / 360 * ratio + (146 * $('#myCanvas').width() / 727 * ratio - ctx.measureText(userInfo.userName).width) / 2;
   //绘制用户昵称到奖状上
  ctx.fillText(userInfo.userName, paddingLeft, 210 * $('#myCanvas').height() / 640 * ratio);
复制代码

3、问题3解决方案:

(1)解决思路

 利用rem设置字体大小,使用淘宝的 flexible 插件计算出移动设备根节点的font-size,
 然后在某一固定分辨率的设备上计算出当前用户昵称对应的字体大小,然后根据比例求出其他设备对应的字体大小
复制代码
    ctx.fillStyle = "red";
    let fontSize = getComputedStyle(window.document.documentElement)['font-size'];
    //0.41 为在某个确定分辨率下调试出的字体rem值
    ctx.font = fontSize.replace(/px/, "") * 0.41 * ratio + "px Arial";
    
复制代码

四、H5体验地址,做的不够完美,希望大家多多指导,谢谢!

转载于:https://juejin.im/post/5c73b3e2f265da2dde06f54a

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
简介: 新的 HTML5 规范旨在帮助开发人员更轻松的编写出各类 Web 应用,以顺应当前 SaaS,云计算以及 RIA 等技术的最新趋势。在 HTML5 得以广泛推广之前,开发人员通常使用 SVG,VML 等技术进行 Web 绘图操作,但这些基于 XML 的绘图语言声明式的绘图方式并不能满足复杂绘图操作在性能上的需求,比如 Web 游戏所需要的像素级别的绘图能力。HTML5 canvas 元素的出现填补了这种不足,开发人员可以使用 JavaScript 脚本语言在 canvas 进行一系列基于命令的图形绘制操作,本文将通过讲解如何使用 canvas 元素进行基本绘图操作,以及完成简单的动画和用户交互任务,阐明 canvas 在帮助构建 Web 图形类应用时所能够提供的能力。更多html5相关信息请关注html5国:http://www.html5cn.org 背景介绍 HTML5 新引入的 canvas 元素使得 Web 开发人员在无须借助任何第三方插件(如 Flash,Silverlight)的情况下,可以直接使用 JavaScript 脚本在 Web 页面进行绘图。它首次由苹果公司的 Webkit 框架引入实现,并成功运用在 Safari 浏览器,读者在 这里可以体验到基于 canvas 的精彩示例。目前,canvas 已成为 HTML5 规范的事实性标准,并且已经被 Firefox 3.0+, Safari 3.0+, Chrome 3.0+, Opera10.0+ 等浏览器所支持。最近(本文撰写之时),IE 也正式宣称将在其 9.0 版本之后,开始对 canvas 元素进行支持。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值