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

[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;
}));

个人简介

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

主目录

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/410751.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

动态规划-直方图最大长方形

/* 1017: C03-单调栈算法-最大长方形时间限制: 1 Sec 内存限制: 128 MB 提交: 17 解决: 10 [提交] [状态] [讨论版] [命题人:外部导入] 题目描述给你一个直方图&#xff0c;告诉你各个条形矩形的高度&#xff0c;求基线对齐构成的矩形中面积最大的矩形的面积。对于每一个矩形…

android记事本项目案例,Android实现记事本项目完整实例源代码

【实例简介】记事本项目源码&#xff0c;我的博客有详细描述。一个记事本&#xff0c;能够输入标题和内容&#xff0c;创建日期、最新修改日期等信息。如果没有输入标题则使用内容的第一句话作为标题&#xff0c;创建日期和修改日期均由系统自动生成&#xff0c;无需用户干预。…

Metropolis Hasting算法

Metropolis Hasting Algorithm: MH算法也是一种基于模拟的MCMC技术&#xff0c;一个很重要的应用是从给定的概率分布中抽样。主要原理是构造了一个精妙的Markov链&#xff0c;使得该链的稳态是你给定的概率密度。它的好处&#xff0c;不用多说&#xff0c;自然是可以对付数学形…

[html] html的开始与结束标签嵌套错误会导致哪些问题?

[html] html的开始与结束标签嵌套错误会导致哪些问题&#xff1f; 有的可以被正常解析&#xff0c;有的不行。题目中的例子可以被正常解析&#xff0c;如果是 <div><a>标题</div></a>&#xff0c;a 标签不能被正常解析。个人简介 我是歌谣&#xff0…

荣耀变鸿蒙系统,鸿蒙系统首批升级机型曝光!荣耀手机遗憾缺席,原因很简单...

原标题&#xff1a;鸿蒙系统首批升级机型曝光&#xff01;荣耀手机遗憾缺席&#xff0c;原因很简单大家好&#xff0c;我是科技君的探讨&#xff0c;欢迎关注我&#xff0c;与我一起进行科技的探讨。华为鸿蒙系统可以说是目前数码圈关注度最高的事件之一了。从早期公布&#xf…

bzoj2733永无乡

永无乡 HYSBZ - 2733 永无乡包含 n 座岛&#xff0c;编号从 1 到 n&#xff0c;每座岛都有自己的独一无二的重要度&#xff0c;按照重要度可 以将这 n 座岛排名&#xff0c;名次用 1 到 n 来表示。某些岛之间由巨大的桥连接&#xff0c;通过桥可以从一个岛 到达另一个岛。如果…

在 Delphi 下使用 DirectSound (14): 测试镶边效果器 IDirectSoundFXFlanger8

{相关结构:} TDSFXFlanger packed recordfWetDryMix: Single; // 0 .. 100 : 50 (%)fDepth: Single; // 0 .. 100 : 100 (%)fFeedback: Single; //-99 .. 99 : -50 (%)fFrequency: Single; // 0 .. 10 : 0.25lWaveform: Longint; // 0 .. 1 : 1fDelay: Sin…

[html] 说说如果a链接href=““(空)时点击时会有什么表现?

[html] 说说如果a链接href""&#xff08;空&#xff09;时点击时会有什么表现&#xff1f; 不会进行跳转&#xff0c;会刷新当前页面个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后端知识。放弃很容易&#xff0c; 但坚持一定很酷。欢迎大家一起讨论 主目录…

html判断是否在页面,html判断当前页面是否在iframe中的实例

html判断当前页面是否在iframe中的实例在做HTML页面的时候&#xff0c;经常会遇到“如果当前页面显示在iframe中&#xff0c;我们就相应的处理”判断方法为&#xff1a;//判断是否在iframe中if(self!top){parent.window.location.replace(window.location.href);}以上这篇html判…

一种用户体验-显示对话框时灰化你的主窗体

袁永福 ( http://www.xdesigner.cn ) 2007&#xff0d;8&#xff0d;10 程序全部源代码下载(工程文件使用VS.NET2003格式):/Files/xdesigner/DisableMask.rar 在一些Web程序中,有一种页面效果,当弹出一个模拟的对话框时,主页面就整体灰化了,其他的元素不能动弹,只有这个对话框能…

sql经典语句

一、基础 1、说明&#xff1a;创建数据库 CREATE DATABASE database-name 2、说明&#xff1a;删除数据库 drop database dbname 3、说明&#xff1a;备份sql server --- 创建 备份数据的 device USE master EXEC sp_addumpdevice disk, testBack, c:\mssql7backup\MyNwind_1.d…

[html] html元素哪些标签是不可替换元素?哪些是可替换元素?

[html] html元素哪些标签是不可替换元素&#xff1f;哪些是可替换元素&#xff1f; 可替换元素&#xff08;replaced element&#xff09;的展现效果不是由 CSS 来控制的。这些元素是一种外部对象&#xff0c;它们外观的渲染&#xff0c;是独立于 CSS 的。也就是说&#xff0c…

html文档中用于表示页面标题的标记对是,汽车发动机拆装与检修实训超星尔雅答案...

摘要&#xff1a;汽车生活事件也称为应激源( )在教师的直接领导下整个班级的学生一起进行的学习&#xff0c;机拆检修称为( )实训教学二字连用最早出自( )...汽车生活事件也称为应激源( )发动下列不属于课程与教学关系观的是( )在教师的直接领导下整个班级的学生一起进行的学习…

一些类的概念

1、异常处理 try: pass except: pass2、面向对象 怎么用类 面向过程#1、4s店#2、保险公司&#xff0c;上保险#3、税务局交税#4、车管所 面向对象1&#xff1a;买车处 #1、4s店 #2、保险公司&#xff0c;上保险 #3、税务局交税…

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

[html] 请使用canvas画一个椭圆 <script> var cdocument.getElementById("myCanvas"); var ctxc.getContext("2d"); ctx.beginPath(); ctx.arc(95,50,40,0,2*Math.PI); ctx.stroke(); </script> 个人简介 我是歌谣&#xff0c;欢迎和大家一起…

html 跟随鼠标移动线条,canvas跟随鼠标移动的随机线条

/** type {HTMLCanvasElement} */let canvas document.querySelector(#canvas);let cxt canvas.getContext(2d);let w canvas.width window.innerWidth;let h canvas.height window.innerHeight;mousePosition {x: Number,y: Number}//随机颜色function ranColor() {ret…

go 优秀文档

go语言资料汇总 &#xff1a; https://blog.zhnytech.com/articles/2016/07/15/Golang%E5%AD%A6%E4%B9%A0%E8%B5%84%E6%96%99%E6%94%B6%E9%9B%86.html github资料基础&#xff1a;https://github.com/Unknwon/the-way-to-go_ZH_CN/blob/master/eBook/directory.md k8s国外镜像 …

Python 程序 运行过程

一. Python 解释器 Python 是一门编程语言&#xff0c;同时也是一个解释器的软件包。 解释器是一种让其他程序运行起来的程序。 当你编写了一段Python 程序&#xff0c;Python 解释器将读取程序&#xff0c;并按照其中的命令执行&#xff0c;得出结果。解释器是代码与计算机硬…

[html] 在H5中如何预加载音频?

[html] 在H5中如何预加载音频&#xff1f; audio标签默认会预加载个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后端知识。放弃很容易&#xff0c; 但坚持一定很酷。欢迎大家一起讨论 主目录 与歌谣一起通关前端面试题

H5|web移动前端自适应适配布局解决方案

方案&#xff1a; 固定一个某些宽度&#xff0c;使用一个模式&#xff0c;加上少许的媒体查询方案使用flexbox解决方案使用百分比加媒体查询使用rem1. 简单问题简单解决 我觉得有些web app并一定很复杂&#xff0c;比如拉勾网&#xff0c;你看看它的页面在iphone4,iphone6,ipad…