[html] 请使用canvas画一个渐变的长方形

// 普通canvas绘图工具类// umd适配多种引入方式
(function(root, factory) {if (typeof define === 'function' && define.amd) {// AMDdefine(['CanvasTool'], factory);} else if (typeof exports === 'object' && typeof module === 'object') {// Node, CommonJS之类的module.exports = factory();} else {// 浏览器全局变量(root 即 window)root.CanvasTool = factory();}
}(window, function() {// 方法const textBreakline = Symbol('textBreakline');const validateRlues = Symbol('validateRlues');const letterSpacingText = Symbol('letterSpacingText');const setFillStyle = Symbol('setFillStyle');const setStrokeStyle = Symbol('setStrokeStyle');const setFontSize = Symbol("setFontSize");class CanvasTool {constructor(ctx, scale) {this.ctx = ctx;this.scale = scale || 1;}/*** 画菱形* @param {Object} rhombObj 传入菱形的参数* sx: 开始的x轴* sy: 开始的y轴* cx: 中心位置的x轴* cy: 中心位置的y轴* width: 宽度* height: 高度* bgColor: 背景色*/rhomb(rhombObj) {let { sx, sy, cx, cy, width, height, bgColor } = rhombObj;// 参数校验规则let ruleMap = new Map([[sx, { type: 'number', param: 'sx' }],[sy, { type: 'number', param: 'sy' }],[cx, { type: 'number', param: 'cx' }],[cy, { type: 'number', param: 'cy' }],[width, { type: 'number', param: 'width' }],[height, { type: 'number', param: 'height' }],[bgColor, { type: 'string', param: 'bgColor' }]]);this[validateRlues](ruleMap);// 设置默认值sx = sx || 0;sy = sy || 0;cx = cx || 0;cy = cy || 0;bgColor = bgColor || '#fff';this.ctx.translate(cx, cy);this.ctx.rotate(45 * Math.PI / 180);// 修正画布坐标this.ctx.translate(-cx, -cy);this.ctx.fillStyle = bgColor;this.ctx.fillRect(sx, sy, width, height);this.ctx.save();}/*** 画直线* @param { Object } lineObj 传入的直线对象* line 画直线* sx: 开始x轴* sy: 开始y轴* ex: 结束x轴* ey: 结束y轴* strokeWidth: 线宽* strokeStyle: 线条样式*/line(lineObj) {// 获取传入的文本对象let { sx, sy, ex, ey, strokeWidth, strokeStyle } = lineObj;// 参数校验规则let ruleMap = new Map([[sx, { type: 'number', param: 'sx' }],[sy, { type: 'number', param: 'sy' }],[ex, { type: 'number', param: 'ex' }],[ey, { type: 'number', param: 'ey' }],[strokeWidth, { type: 'number', param: 'strokeWidth' }],[strokeStyle, { type: 'string', param: 'strokeStyle' }]]);this[validateRlues](ruleMap);// 设置默认值sx = sx || 0;sy = sy || 0;ex = ex || 100;ey = ey || 100;strokeStyle = strokeStyle || '#000';strokeWidth = strokeWidth || 2;this.ctx.beginPath();this.ctx.moveTo(sx, sy);this.ctx.lineTo(ex, ey);this[setStrokeStyle](strokeWidth, strokeStyle);this.ctx.stroke();}/*** 画三角形* @param { Object } triangleObj 传入的三角形对象*/triangle(triangleObj) {// 获取传入的三角形对象let { fx, fy, sx, sy, tx, ty, stroke, strokeWidth, strokeStyle, fill, bgColor } = triangleObj;// 参数校验规则let ruleMap = new Map([[fx, { type: 'number', param: 'fx' }],[fy, { type: 'number', param: 'fy' }],[sx, { type: 'number', param: 'sx' }],[sy, { type: 'number', param: 'sy' }],[tx, { type: 'number', param: 'tx' }],[ty, { type: 'number', param: 'ty' }],[strokeWidth, { type: 'number', param: 'strokeWidth' }],[bgColor, { type: 'string', param: 'bgColor' }],[strokeStyle, { type: 'string', param: 'strokeStyle' }],[stroke, { type: 'boolean', param: 'stroke' }],[fill, { type: 'boolean', param: 'fill' }]]);this[validateRlues](ruleMap);// 设置默认值fx = fx || 0;fy = fy || 0;bgColor = bgColor || '#fff';strokeStyle = strokeStyle || '#000';fill = fill || false;strokeWidth = strokeWidth || 1;this.ctx.beginPath();this.ctx.moveTo(fx, fy);this.ctx.lineTo(sx, sy);this.ctx.lineTo(tx, ty);// 填充颜色fill && (this[setFillStyle](bgColor),this.ctx.fill());stroke && (this[setStrokeStyle](strokeWidth, strokeStyle),this.ctx.stroke());}/*** rect 绘制矩形的方法* @param { Object } rectObj 传入的矩形对象* x 页面x轴的坐标* y 页面y轴的坐标* width 矩形的宽度* height 矩形的高度* bgColor 矩形的背景色* fill 是否填充* strokeStyle 填充边框的颜色* stroke 是否需要边框*/rect(rectObj) {// 获取传入的文本对象let { x, y, width, height, bgColor, fill, stroke, strokeStyle, strokeWidth } = rectObj;// 参数校验规则let ruleMap = new Map([[x, { type: 'number', param: 'x' }],[y, { type: 'number', param: 'y' }],[width, { type: 'number', param: 'width' }],[height, { type: 'number', param: 'height' }],[strokeWidth, { type: 'number', param: 'strokeWidth' }],[bgColor, { type: 'string', param: 'bgColor' }],[strokeStyle, { type: 'string', param: 'strokeStyle' }],[stroke, { type: 'boolean', param: 'stroke' }],[fill, { type: 'boolean', param: 'fill' }]]);this[validateRlues](ruleMap);// 设置默认值x = x || 0;y = y || 0;bgColor = bgColor || '#fff';strokeStyle = strokeStyle || '#000';fill = fill || false;strokeWidth = strokeWidth || 1;this.ctx.rect(x, y, width, height);fill && (this[setFillStyle](bgColor),this.ctx.fill());stroke && (this[setStrokeStyle](strokeWidth, strokeStyle),this.ctx.strokeRect(x, y, width + strokeWidth, height + strokeWidth));}/*** 绘制圆角矩形* @param {number} x 圆角矩形选区的左上角 x坐标* @param {number} y 圆角矩形选区的左上角 y坐标* @param {number} w 圆角矩形选区的宽度* @param {number} h 圆角矩形选区的高度* @param {number} r 圆角的半径* @memberof CanvasTool*/roundRect(roundRectObj) {let { x, y, width: w, height: h, r, bgColor } = roundRectObj;// 参数校验规则let ruleMap = new Map([[x, { type: 'number', param: 'x' }],[y, { type: 'number', param: 'y' }],[w, { type: 'number', param: 'width' }],[h, { type: 'number', param: 'height' }],[r, { type: 'number', param: 'r' }],[bgColor, { type: 'string', param: 'bgColor' }]]);this[validateRlues](ruleMap);// 开始绘制this.ctx.beginPath();this[setFillStyle](bgColor),// 左上角this.ctx.arc(x + r, y + r, r, Math.PI, Math.PI * 1.5);// border-topthis.ctx.moveTo(x + r, y);this.ctx.lineTo(x + w - r, y);this.ctx.lineTo(x + w, y + r);// 右上角this.ctx.arc(x + w - r, y + r, r, Math.PI * 1.5, Math.PI * 2);// border-rightthis.ctx.lineTo(x + w, y + h - r);this.ctx.lineTo(x + w - r, y + h);// 右下角this.ctx.arc(x + w - r, y + h - r, r, 0, Math.PI * 0.5);// border-bottomthis.ctx.lineTo(x + r, y + h);this.ctx.lineTo(x, y + h - r);// 左下角this.ctx.arc(x + r, y + h - r, r, Math.PI * 0.5, Math.PI);// border-leftthis.ctx.lineTo(x, y + r);this.ctx.lineTo(x + r, y);this.ctx.fill();};/*** square 绘制正方形的方法* @param { Object } squareObj 传入的圆形对象* 参数同矩形的参数一致,只需要传入width就可以了*/square(squareObj) {squareObj.height = squareObj.width;this.rect(squareObj);}/*** arc 绘制圆形的方法* @param { Object } arcObj 传入的圆形对象* x 圆心的x轴* y 圆心的y轴* r 半径* sAngle 开始弧度* eAngle 终止弧度* counterclockwise 弧度方向是否是逆时针* fill 是否填充* storke 是有边框* bgColor 背景色* strokeStyle 边框色*/arc(arcObj) {let { x, y, r, sAngle, eAngle, counterclockwise, fill, bgColor, strokeStyle, strokeWidth, storke } = arcObj;// 参数校验规则let ruleMap = new Map([[x, { type: 'number', param: 'x' }],[y, { type: 'number', param: 'y' }],[r, { type: 'number', param: 'r' }],[sAngle, { type: 'number', param: 'sAngle' }],[eAngle, { type: 'number', param: 'eAngle' }],[strokeWidth, { type: 'number', param: 'strokeWidth' }],[counterclockwise, { type: 'number', param: 'counterclockwise' }],[fill, { type: 'boolean', param: 'fill' }],[storke, { type: 'boolean', param: 'storke' }],[bgColor, { type: 'string', params: 'bgColor' }],[strokeStyle, { type: 'string', params: 'strokeStyle' }],]);this[validateRlues](ruleMap);// 设置默认值x = x || 0;y = y || 0;sAngle = sAngle || 0;eAngle = eAngle || 0;fill = fill || false;bgColor = bgColor || '#000';this.ctx.beginPath();this.ctx.arc(x, y, r, sAngle * Math.PI, eAngle * Math.PI, counterclockwise);// 圆的边框暂时不生效storke && (this[setStrokeStyle](strokeWidth, strokeStyle),this.ctx.stroke());fill && (this[setFillStyle](bgColor),this.ctx.fill());}/*** 绘制圆形头像* @param img 图片资源* @param opts 参数* @param beforeFn 函数钩子* @param afterFn 函数钩子*/circleAvatar(circleAvatarObj) {let { img, opts, beforeFn, afterFn } = circleAvatarObj;let { x, y, r } = opts;// 参数校验规则let ruleMap = new Map([[x, { type: 'number', param: 'x' }],[y, { type: 'number', param: 'y' }],[r, { type: 'number', param: 'r' }]]);this[validateRlues](ruleMap);(isFunction(beforeFn)) && beforeFn();this.drawCircle({x,y,r});ctx.clip();ctx.drawImage(img, x, y, r);ctx.restore();(isFunction(afterFn)) && afterFn();return this;}/*** text 绘制文本的方法 * text 文本* x 页面x轴坐标* y 页面y轴坐标* width 文本的最大宽度* color 颜色* fontSize 字号* align 对其方式* textBaseline 文本的基线* wrap 是否换行* lineHeight 行高* letterSpacing 字间距*/text(textObj) {// 获取传入的文本对象let { text, color, fontSize, fontStyle, align, x, y, width, textBaseline, wrap, lineHeight, letterSpacing } = textObj;// 参数校验规则let ruleMap = new Map([[text, { type: 'string', param: 'text' }],[color, { type: 'string', param: 'color' }],[textBaseline, { type: 'string', param: 'textBaseline' }],[align, { type: 'string', param: 'align' }],[fontStyle, { type: 'string', param: 'fontStyle' }],[fontSize, { type: 'number', param: 'fontSize' }],[x, { type: 'number', param: 'x' }],[y, { type: 'number', param: 'y' }],[width, { type: 'number', param: 'width' }],[lineHeight, { type: 'number', param: 'lineHeight' }],[letterSpacing, { type: 'number', param: 'letterSpacing' }],[wrap, { type: 'boolean', param: 'wrap' }],]);this[validateRlues](ruleMap);// 设置默认值color = color || '';fontSize = fontSize || 16;align = align || 'center';x = x || 0;y = y || 0;width = width || 0;wrap = wrap || false; // 默认不换行letterSpacing = letterSpacing || 0;// 绘图this[setFillStyle](color);this[setFontSize](fontSize * this.scale);this.ctx.textAlign = align;textBaseline && (this.ctx.setTextBaseline = textBaseline);!wrap && !letterSpacing && this.ctx.fillText(text, x, y, width);wrap && this[textBreakline](text, x, y, width, lineHeight);letterSpacing && this[letterSpacingText](text, align, x, y, letterSpacing);}// -------私有属性--------/*** 设置填充颜色*/[setFillStyle](fillStyle) {this.ctx.fillStyle = fillStyle;}/*** 设置边框颜色 / 宽度*/[setStrokeStyle](strokeWidth, strokeStyle) {this.ctx.lineWidth = strokeWidth;this.ctx.strokeStyle = strokeStyle;}/*** 设置字体大小*/[setFontSize](fontSize, fontStyle = "Microsoft YaHei") {console.log(fontSize, fontStyle);this.ctx.font = `${fontSize}px ${fontStyle}`;}/*** textBreakline 文本换行功能,支持行高* @param {String} text 文本* @param {Number} x 页面x轴的位置* @param {Number} y 页面y轴的位置* @param {Number} maxWidth 最大宽度* @param {Number} lineHeight 行高*/[textBreakline](text, x, y, maxWidth, lineHeight) {// 字符分隔为数组let arrText = text.split('');let line = '';for (let n = 0; n < arrText.length; n++) {let testLine = line + arrText[n];let metrics = this.ctx.measureText(testLine);let testWidth = metrics.width;if (testWidth > maxWidth && n > 0) {this.ctx.fillText(line, x, y);line = arrText[n];y += lineHeight;} else {line = testLine;}}this.ctx.fillText(line, x, y);}/*** 文本支持字间距* @param {String} text 文本* @param {Number} x 页面x轴的位置* @param {Number} y 页面y轴的位置* @param {Number} letterSpacing 字间距*/[letterSpacingText](text, textAlign, x, y, letterSpacing) {let context = this.ctx;// let canvas = context.canvas;// if (!letterSpacing && canvas) {//     letterSpacing = parseFloat(window.getComputedStyle(canvas).letterSpacing);// }// if (!letterSpacing) {//     return this.fillText(text, x, y);// }let arrText = text.split('');let align = textAlign || 'left';// 这里仅考水平排列let originWidth = context.measureText(text).width;// 应用letterSpacing占据宽度let actualWidth = originWidth + letterSpacing * (arrText.length - 1);// 根据水平对齐方式确定第一个字符的坐标if (align == 'center') {x = x - actualWidth / 2;} else if (align == 'right') {x = x - actualWidth;}// 临时修改为文本左对齐context.textAlign = 'left';// 开始逐字绘制arrText.forEach(function(letter) {let letterWidth = context.measureText(letter).width;context.fillText(letter, x, y);// 确定下一个字符的横坐标x = x + letterWidth + letterSpacing;});// 对齐方式还原context.textAlign = align;}// 校验功能[validateRlues](ruleMap) {try {for (let [key, val] of ruleMap.entries()) {if (key && typeof key != val.type) {throw new Error(val.param + '的参数类型错误,要求是' + val.type + '类型');// 把所有参数都校验一遍continue;}}} catch (err) {console.error(err);}}}// 暴露公共方法return CanvasTool;
}));

个人简介

我是歌谣,欢迎和大家一起交流前后端知识。放弃很容易,
但坚持一定很酷。欢迎大家一起讨论

主目录

与歌谣一起通关前端面试题

[html] 请使用canvas画一个渐变的长方形相关推荐

  1. [html] 请使用canvas画一个椭圆

    [html] 请使用canvas画一个椭圆 <script> var c=document.getElementById("myCanvas"); var ctx=c. ...

  2. html5 --- 使用canvas画一个渐变矩形

    我们希望得到如下效果: 首先准备画布 // HTML <canvas width="500" height="375" id ="a" ...

  3. python程序、画一个笑脸_如何使用canvas画一个微笑的表情(代码示例)

    本篇文章给大家带来的内容是关于如何使用canvas画一个微笑的表情(代码示例),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 实习期间让我用canvas画一个表情,比较简单,话不多说 ...

  4. [css] 请使用css画一个圆,方法可以多种

    [css] 请使用css画一个圆,方法可以多种 <div class="circle"></div>1.border-radius.cirlce{width ...

  5. [css] 请使用CSS画一个带锯齿形边框圆圈

    [css] 请使用CSS画一个带锯齿形边框圆圈 @import 个人简介 我是歌谣,欢迎和大家一起交流前后端知识.放弃很容易, 但坚持一定很酷.欢迎大家一起讨论 主目录 与歌谣一起通关前端面试题

  6. 用canvas画一个太极图(八卦图)

    用canvas画一个太极图(八卦图) 源码展示链接: https://yanhappiness.github.io/Notes/canvas_src.html 理解什么是canvas canvas是H ...

  7. 如何利用canvas画一个圆,并且填充颜色

    如何利用canvas画一个圆,并且填充颜色(小白专用,大佬勿看) canvas基础 相信在此之前,你对canvas已经有一定的了解了,接下来我将介绍,如何利用canvas画一个圆. 1.新建一个htm ...

  8. 用canvas画一个五星红旗

    利用canvas画一个好看的五星红旗!!! 简单,容易上手! <!DOCTYPE html> <html lang="utf-8"> <meta ht ...

  9. 用canvas画一个简易的机器猫头像

    用canvas画一个机器猫的头像,原图如下: 代码实现效果如下: 代码如下: <!DOCTYPE html> <html lang="en"> <he ...

最新文章

  1. Writing Images to the Excel Sheet using PHPExcel--转载
  2. 云开发系列课程让你从入门到精通快速上手Serverless和云开发技术
  3. salad--8||9
  4. RegularExpressions(2) RegularExpressions 支持的正则表达式语法
  5. BUG搬运工:CSCvp31778-3802 apsw_watchdog: WARNING: System memory is running low
  6. mysql数据库连接空闲超时设置不生效,未区分全局变量及interactive_timeout设置
  7. Android实现QQ音乐QMC格式转MP3格式
  8. 论文阅读笔记 | 分类网络——ParNet
  9. Netty权威指南2.2伪异步IO,Demo代码
  10. 设计模式第一篇---懒汉模式
  11. Carson带你学Android:这是一份详细的 Retrofit使用教程(含实例讲解)
  12. 板线分离嵌入式RFID读卡模块NFC读写模块HX880系列的应用案例
  13. matlab画y等于x平方,如何用matlab画Y=X^2的图啊?
  14. 常见光纤连接头 ST、SC、FC、LC
  15. 批量修改Excel单元格内某些文字的颜色
  16. python画饼图程序_Scribus中的Python脚本:制作饼图
  17. MATLAB#183;提取图像中多个目标
  18. 近1、2年来设计的几个飞机构型
  19. EPSON打印机清零复位操作
  20. deepinv2 添加打印机_如何在Deepin 20下安装brother打印机驱动及设置网络打印机?...

热门文章

  1. 我如何使用React和Typescript在freeCodeCamp中构建天气应用
  2. 使用r语言做garch模型_使用GARCH估计货币波动率
  3. 批梯度下降 随机梯度下降_梯度下降及其变体快速指南
  4. 主线程中有多个handler的情况
  5. *** Python版一键安装脚本
  6. 关于std::ios::sync_with_stdio(false)
  7. [Android]在Dagger 2中使用RxJava来进行异步注入(翻译)
  8. Web Js 按键事件……Enter提交事件 Enter Js事件
  9. SQL Server开发接口生成方法
  10. NDoc修改版,支持中文注释及中文界面。