要求实现下面这个效果:

观察图片,我们的需求如下:
-  
准备画布和上下文:在开始绘制之前,需要有一个HTML5
<canvas>元素,并且获取其绘图上下文(context),这是进行绘图操作的基础。 -  
定义形状和样式:对于想要绘制的每个形状(文本、矩形、圆形),需要定义它们的位置、尺寸和样式。这通常涉及到创建包含这些属性的对象。
 -  
编写绘制函数:需要编写或使用现有的函数来绘制这些形状。这些函数通常会接受上下文和形状的属性作为参数,并使用Canvas API进行绘制。
 -  
添加视觉效果:增强视觉效果,添加阴影和渐变色。这通常涉及到使用Canvas API中的阴影和渐变相关方法。
 -  
组合元素:将所有的绘制操作组合在一起,形成一个完整的绘图流程。确保每一步都按照正确的顺序执行,以实现预期的视觉效果。
 
function drawCanvas() {
    // 设置文本位置
    var text = {
        x: canvas.width / 2,
        y: canvas.height / 2
    };
    drawText(context, text, 1, 64);
    // 设置矩形位置和尺寸
    var rect = {
        x: canvas.width / 2 - 35,
        y: canvas.height / 2 - 40,
        h: 70,
        w: 70
    };
    drawRectPath(context, rect, 1);
    // 设置圆形位置和半径
    var circle = {
        x: canvas.width / 2,
        y: canvas.height / 2 - 5,
        r: 80,
        clockwise: false
    };
    drawCirclePath(context, circle, 0, 1);
    // 添加阴影效果
    putShadowOnPath(context, "yellow", 10, -10, 20);
    // 创建并应用渐变色
    var grd = createLinearGradient(context, 150, 150, canvas.width - 150, canvas.height - 150, colors);
    putColorOnPath(context, grd, 1, 5);
} 
上面的代码提供了一个框架,具体的每个函数实现还需要更进一步设计,我将提供一些参考:
/**
 * 绘制文本
 * @author zjvivi
 * @version 1.0
 * @buildDate 2024-9-22
 * @param {Object} context 绘制的目标context
 * @param {Object} text 包括字体及大小的font,起始点水平对齐align,起始点垂直基线baseline,起始点坐标(x,y)等信息
 * @param {String} style 填充色/描边色/其他样式
 * @param {Number} isFill 是否填充,true/1表示填充,反之描边
 * @param {Number} lineWidth 绘制线条的宽度
 */
function drawText(context,text,isFill,lineWidth) {
    context.font=`${text.fontSize}px ${text.font}` ; //设置字体大小
    context.textAlign=text.align;
    context.textBaseline=text.baseline;
    if(isFill){
        context.fillStyle=text.style;
        context.fillText(text.text, text.x,text.y); //绘制填充文本
    }else{
        context.strokeStyle=text.style;
        context.lineWidth=lineWidth || 1;
        context.strokeText(text.text, text.x,text.y); //绘制描边文本
    }
} 
/**
 * 绘制矩形路径
 * @author zjvivi
 * @version 1.0
 * @buildDate 2024-9-22
 * @param {Object} context 绘制的目标context
 * @param {Object} rect 包括绘制起始点坐标(x,y)、宽度width和高度height信息
 * @param {*} isNewPath 是否开启新路径  是否开启新路径,true/1表示开启,反之不开启
 */
function drawRectPath(context,rect,isNewPath) {
   if(isNewPath) context.beginPath();
   context.rect(rect.x, rect.y, rect.w, rect.h);
} 
/**
 * 绘制圆形路径
 * @author zjvivi
 * @version 1.0
 * @buildDate 2024-9-22
 * @param {Object} context 绘制的目标context
 * @param {Object} cirle包括绘制圆心坐标(x,y)、半径r、起始弧度startAngle、终止弧度endAngle和是否顺时针clockwise信息
 * @param {Boolean} isNewPath 是否开启新路径  是否开启新路径,true/1表示开启,反之不开启
 * @param {Boolean} isClosePath 是否闭合路径 true/1表示闭合,反之不闭合
 */
function drawCirclePath(context,circle,isNewPath,isClosePath){
    if(isNewPath) context.beginPath();
    context.arc(circle.x,circle.y,circle.r,circle.sAngle,circle.eAngle,!circle.clockwise);
    if(isClosePath) context.closePath();
} 
/**
 * 设置路径阴影
 * @author zjvivi
 * @version 1.0
 * @buildDate 2024-9-22
 * @param {Object} context 绘制的目标canvas
 * @param {String} color  阴影颜色
 * @param {*} offsetX 
 * @param {*} offsetY 
 * @param {*} blur 
 */
function putShadowOnPath(context,color,offsetX,offsetY,blur) {
    if(blur!==undefined) context.shadowBlur=blur;
    if(color!==undefined) context.shadowColor=color;
    if(offsetX!==undefined) context.shadowOffsetX=offsetX;
    if(offsetY!==undefined) context.shadowOffsetY=offsetY;
    
} 
/**
 * 创建线性渐变对象
 * @author zjvivi
 * @version 1.0
 * @buildDate 2024-9-22
 * @param {*} context 绘制目标context对象
 * @param {*} x1  起始点的x坐标
 * @param {*} y1  起始点的y坐标
 * @param {*} x2  终止点的x坐标
 * @param {*} y2  终止点的x坐标
 * @param {*} colors 颜色数组colors=[{pos:0,color:'orange'},...]
 * @returns 
 */
function createLinearGradient(context,x1,y1,x2,y2,colors){
    let grd=context.createLinearGradient(x1, y1, x2, y2);
   
    for(let i=0;i<colors.length;i++){
        grd.addColorStop(colors[i].pos, colors[i].color);
    }
    return grd;  
} 
/**
 * 设置路径样式
 * @author zjvivi
 * @version 1.0
 * @buildDate 2024-9-22
 * @param {Object} context 绘制的目标context
 * @param {String} style 填充色/描边色/其他样式
 * @param {Number} isFill  是否填充,true/1表示填充,反之描边
 * @param {Number} lineWidth 绘制线条的宽度
 */
function putColorOnPath(context,style,isFill,lineWidth) {
    if(isFill){
        context.fillStyle=style;
        context.fill(); 
    }else{
        context.strokeStyle=style;
        context.lineWidth=lineWidth || 1;
        context.stroke();
    }
} 
这些函数被设计为通用函数,可作为函数库在后续开发中使用。将html,js代码都结合起来就可以实现前文的图形效果了。

![[开源]3K+ star!微软Office的平替工具,跨平台,超赞!](https://img-blog.csdnimg.cn/001fee5515e94a6aae350ea593ae8c23.png)
















