• canvas的学习


    在base64和blob笔记里,使用了canvas进行图片压缩,但是画布的基础就是画画

    文章来自三期画布基础教程

    // 生成画布
    var c = document.getElementById("myCanvas");
    c.width = 500;
    c.height = 500;
    // 生成画笔
    var ctx = c.getContext("2d");
    
    // 线,闭合线,填充线
    ctx.beginPath();  // 开始画
    ctx.moveTo(100, 100);  // 画笔移动到
    ctx.lineWidth = 2; // 画笔粗细
    ctx.lineCap = 'round';  // 线条首尾
    ctx.lineJoin = 'round';  // 线条连接处
    ctx.lineTo(300,100);  // 画一条线,开始的x是100,结束的x是300,开始的y是100,结束是0
    ctx.lineTo(200,200);  // 画笔初始位置是上一个方法执行后的点
    ctx.closePath();  // 闭合线,把开始的位置和上一句代码的位置连接起来
    ctx.fill();   //写这句就不需要写closePath了,这句是closePath+填充
    ctx.stroke();
    
    // 闭合方形
    ctx.beginPath();  // 开始画
    ctx.strokeStyle = "red";
    ctx.globalAlpha = 0.3;//设置全局透明度
    ctx.strokeRect(50,50, 200, 200); //绘制边框
    ctx.stroke();
    
    // 填充方形
    ctx.beginPath();  // 开始画
    ctx.fillStyle = "blue"; //设置颜色
    ctx.fillRect(50,50, 200, 200); //绘制方块
    ctx.stroke();
    
    // 圆
    ctx.beginPath();  // 重新开始一笔
    ctx.arc(400, 400, 50, 0, Math.PI*2, false); // 绘制圆圈轨迹,最后一个参数是从上半圆还是下半圆
    ctx.stroke();
    
    // 气泡聊天窗
    ctx.beginPath();
    ctx.moveTo(100,130);
    ctx.quadraticCurveTo(100,100,130,100);
    ctx.lineTo(270,100);
    ctx.quadraticCurveTo(300,100,300,130);
    ctx.lineTo(300,200);
    ctx.quadraticCurveTo(300,230,270,230);
    ctx.lineTo(175,230);
    ctx.quadraticCurveTo(140,280,100,280);
    ctx.quadraticCurveTo(130,280,150,230);
    ctx.lineTo(130,230);
    ctx.quadraticCurveTo(100,230,100,200);
    ctx.closePath();
    ctx.stroke();  // 这一笔结束
    
    // 心形
    ctx.beginPath();
    ctx.moveTo(100,100);
    ctx.bezierCurveTo(100,50,170,50,200,100);
    ctx.bezierCurveTo(230,50,300,50,300,130);
    ctx.bezierCurveTo(300,140,300,210,200,250);
    ctx.bezierCurveTo(100,200,100,140,100,130);
    ctx.stroke();
    
    // 点
    ctx.beginPath();
    ctx.fillRect(51+2*16,35,4,4);
    ctx.stroke();
    
    //线性渐变
    ctx.beginPath();
    var lineargradient = ctx.createLinearGradient(0,0,0,140);// 准备调料
    lineargradient.addColorStop(0,'#00ABEB');
    lineargradient.addColorStop(0.5, "#fff");
    lineargradient.addColorStop(0.5, "green");
    lineargradient.addColorStop(1,'#fff');
    ctx.fillStyle = lineargradient;
    ctx.fillRect(10,10,130,130);
    ctx.stroke();
    
    /*径向渐变*/
    ctx.beginPath();
    var radgrad = ctx.createRadialGradient(45,45,10,52,50,30);  // 准备调料
    radgrad.addColorStop(0, "#fff");
    radgrad.addColorStop(0.9, "green");
    radgrad.addColorStop(1, "rgba(255,255,255,0)"); //最后一个颜色最好写成透明的,这样圆圈以外部分会以这个颜色填充
    ctx.fillStyle = radgrad;
    ctx.fillRect(0,0,150,150);
    ctx.stroke();
    
    // 虚线
    ctx.beginPath();
    ctx.setLineDash([10, 10]); //设置设置虚线的间隔 x1表示虚线自身长度 x2表示间隔长度  默认单位:px
    ctx.lineDashOffset = 5; //设置偏移量
    ctx.strokeRect(100,100,100,100); //绘制虚线边框
    ctx.stroke();
    
    // 文字
    ctx.shadowOffsetX = 2;  //阴影x方向偏移量
    ctx.shadowOffsetY = 2;  //阴影y方向偏移量
    ctx.shadowBlur = 5;  //阴影模糊度
    ctx.shadowColor = "rgba(0,0,0,0.5)";  //阴影颜色
    ctx.font = "20px Times New Roman";
    ctx.fillStyle = "black";
    ctx.fillText("Sample String", 5, 30);
    
    //  save和restore,保存画布的状态
    ctx.fillStyle = "darkblue";
    ctx.lineWidth = 1;
    ctx.fillRect(0,0,150,150);
    ctx.save();    //第一次保存 保存了  fillStyle "darkblue"
    ctx.fillStyle = "#09f";
    ctx.fillRect(15,15,120,120);
    ctx.save();    //第二次保存 保存了  fillStyle "#09f"
    ctx.fillStyle = "#fff";
    ctx.fillRect(30,30,90,90);
    ctx.restore();  //恢复到第二次保存的状态
    ctx.fillRect(45,45,60,60);
    ctx.restore();  //恢复到第一次保存的状态
    ctx.fillRect(60,60,30,30);
    
    //先画一个路径然后裁剪
    ctx.clip();
    
    // 偏移
    ctx.transform(水平方向的移动,竖直方向的移动);
    ctx.transform(水平方向的缩放,水平方向的偏移,竖直方向的偏移,竖直方向的缩放,水平方向的移动,竖直方向的移动);
    ctx.scale(0.4,0.4); // 缩放
    ctx.rotate(-Math.PI/2);  // 角度,参数是pi
    
    // 橡皮擦
    ctx.clearRect(50,50, 200, 200);  //清除范围,这里清除的是方块,如果要清除方块描边的话,需要把范围扩大
    
    // 画图,参数有三种填发,2个,4个,8个
    sx,开始剪切的 x 坐标位置。
    sy,开始剪切的 y 坐标位置。
    swidth,被剪切图像的宽度。
    sheight,被剪切图像的高度。
    x,在画布上放置图像的 x 坐标位置。
    y,在画布上放置图像的 y 坐标位置。
    width,要使用的图像的宽度。(伸展或缩小图像)
    height,要使用的图像的高度。(伸展或缩小图像)
    ctx.drawImage(img,x,y);
    ctx.drawImage(img,x,y,width,height);
    ctx.drawImage(img,sx,sy,swidth,sheight,x,y,width,height);
    

    封装一个划线的方法

    function drawLine(sx, sy, ex, ey){
        ctx.beginPath();
        ctx.moveTo(sx,sy);
        ctx.lineTo(ex,ey);
        ctx.stroke();
        ctx.closePath();
    }
    

    一像素画笔

    function draw(){
        // 当只绘制1像素的线的时候,坐标点需要偏移,这样才能画出1像素实线
        ctx.translate(0.5,0.5);  
        ctx.lineWidth = 1;
        drawLine(50, 50, 100, 50);  // 上面的划线方法
        ctx.translate(-0.5,-0.5);  // 还原位置
    }
    

    动画效果

    // 计时器和清除计时器就不说了
    
    //  动画专用的计时器
    var nextAnimation = ""
    function draw(){
       nextAnimation = window.requestAnimationFrame(draw);
    }
    window.requestAnimationFrame(draw); // 执行
    window.cancelAnimationFrame(nextAnimation); // 把下一帧清除就等于停止递归
    

    画布事件

    var mousePosition = {};
    var mouseTimer = null;
    canvas.addEventListener("mousemove",function(e){
        e = e || window.event;
        if( e.layerX || e.layerX==0 ){
            mousePosition.x = e.layerX;
            mousePosition.y = e.layerY;
        }else if( e.offsetX || e.offsetX==0 ){
            mousePosition.x = e.offsetX;
            mousePosition.y = e.offsetY;
        }
    
        clearTimeout(mouseTimer);
        mouseTimer = setTimeout(function(){
            // 清空画布
            ctx.clearRect(0,0,canvas.width, canvas.height);
            drawBarAnimate(true);
        },10);
    });
    
    function drawBarAnimate(mouseMove){
       // for循环去生成方块
       drawRect(x, y, X, Y,mouseMove)
    }
    
    // 绘制方块
    function drawRect( x, y, X, Y, mouseMove ){
        ctx.beginPath();
        ctx.rect( x, y, X, Y );
        // 判断参数的两个值是否在当前的 beginPath 和 closePath 的绘制区域内
        if(mouseMove && ctx.isPointInPath(mousePosition.x, mousePosition.y)){ 
            ctx.fillStyle = "green";
        }else{
            ctx.fillStyle = "red";
        }
        ctx.fill();
        ctx.closePath();
    }
    
  • 相关阅读:
    day 29-2 socket 文件传输、udp协议
    day 29-1 socket
    day 28-1 元类、异常处理
    day 27-1 反射、内置方法
    day 26-1 property、绑定与非绑定方法
    day 25-1 接口类、抽象类、多态
    day 24-1 继承
    day 23-1 类的命名空间、组合
    day 22
    PyMySQL操作mysql数据库(py3必学)
  • 原文地址:https://www.cnblogs.com/pengdt/p/12303977.html
Copyright © 2020-2023  润新知