zoukankan      html  css  js  c++  java
  • canvas入门,就是这个feel!

    钙素

    Canvas 是在HTML5中新增的标签用于在网页实时生成图像,并且可以操作图像内容,基本上它是一个可以用JavaScript操作的位图。也就是说我们将通过JS完成画图而不是css

    canvas 默认布局为 inline-block,可以认为是一种特殊的图片。

    走起 ~

    canvas 划线

    <canvas id="can" width="800" height="800"></canvas>
    

    (宽高不能放在style里面,否则比例不对)

    canvas里面的widthheight相当于图片的原始尺寸,加了外部style的宽高,就相当于对图片进行压缩和拉伸。

    // 1、获取原生dom对象
    let dom = document.getElementById('can');
    
    // 2、获取绘图对象
    let can = dom.getContext('2d'); // 3d是webgl
    
    // 定义线条起点
    can.moveTo(0,0);
    
    // 定义线条中点(非终点)
    can.lineTo(400,400);
    can.lineTo(800,0);
    
    // 对标记范围进行描边
    can.stroke()
    
    // 对标记范围进行填充
    can.fill();
    

    设置线条属性

    线条默认宽度是 1

    (一定要在绘图之前设置。)

    can.lineWidth = 2; //设置线条宽度
    can.strokeStyle = '#f00';  // 设置线条颜色
    
    can.fillStyle = '#f00';  // 设置填充区域颜色
    

    折线样式

    • miter:尖角(当尖角长度值过长时会自动变成折角,如果强制显示尖角:can.miterLimit = 100 设置尖角长度阈值。
    • round:圆角
    • bevel:折角
    can.lineJoin = 'miter';
    can.moveTo(100, 100);
    can.lineTo(300, 100);
    can.lineTo(100, 200);
    can.stroke()
    
    can.lineJoin = 'round';
    can.moveTo(400, 100);
    can.lineTo(600, 100);
    can.lineTo(400, 200);
    can.stroke()
    
    can.lineJoin = 'bevel';
    can.moveTo(700, 100);
    can.lineTo(900, 100);
    can.lineTo(700, 200);
    can.stroke()
    

    设置线帽

    • round:加圆角线帽
    • square:加直角线帽
    • butt:不加线帽
    	can.lineCap = 'round';
        can.moveTo(100, 100);
        can.lineTo(300, 100);
    	can.stroke()
    	
         // 新建绘图,使得上一次的绘画样式不会影响下面的绘画样式(代码加在上一次绘画和下一次绘画中间。)
    	can.beginPath()
    	
    	can.lineCap = 'square';
    	can.moveTo(100, 200);
    	can.lineTo(300, 200);
    	can.stroke()
    	
    	can.beginPath()
    	
    	can.lineCap = 'butt';
    	can.moveTo(100, 300);
    	can.lineTo(300, 300);
    	can.stroke()
    

    画矩形

    // 参数:x,y,宽,高
    
    can.rect(100,100,100,100);
    can.stroke();
    

    // 画完即填充
    can.fillRect(100,100,100,100);
    

    画圆弧

    // 参数:圆心x,圆心y,半径,圆弧起点与圆心的夹角度数,圆弧终点与圆心的夹角度数,true(逆时针绘画)
    
    can.arc(500,300,200,0,2*Math.PI/360*90,false);
    can.stroke()
    

    示例:

    can.moveTo(500,300);
    can.lineTo(500 + Math.sqrt(100), 300 + Math.sqrt(100))
    can.arc(500, 300, 100, 2 * Math.PI / 360 *startDeg, 2 * Math.PI / 360 *endDeg, false);
    can.closePath()//将图形起点和终点用线连接起来使之成为封闭的图形
    can.fill()
    

    Tips:

    1、can.beginPath() // 新建绘图,使得上一次的绘画样式不会影响下面的绘画样式(代码加在上一次绘画和下一次绘画中间。)

    2、can.closePath() //将图形起点和终点用线连接起来使之成为封闭的图形。

    旋转画布

    can.rotate(2*Math.PI/360*45); // 一定要写在开始绘图之前
    can.fillRect(0,0,200, 10);
    

    旋转整个画布的坐标系(参考坐标为画布的(0,0)位置)

    缩放画布

    can.scale(0.5,2);
    can.fillRect(0,0,200, 10);
    

    示例:

    整个画布:x方向缩放为原来的0.5,y方向拉伸为原来的2倍。

    画布位移

    can.translate(100,100)
    can.fillRect(0,0,200, 10);
    

    保存与恢复画布状态

    can.save() // 存档:保存当前画布坐标系状态
    can.restore() // 读档:恢复之前保存的画布坐标系状态
    

    需要正确坐标系绘图的时候,再读档之前的正确坐标系。

    can.restore() // 将当前的画布坐标系状态恢复成上一次保存时的状态
    can.fillRect(dom.width/2, dom.height/2, 300, 100)
    

    指针时钟(案例)

    <!DOCTYPE html>
    <html>
    
    <head>
        <meta charset="utf-8">
        <title>clock</title>
        <style type="text/css">
            #can {
                 1000px;
                height: 600px;
                background: linear-gradient(45deg, green, skyblue);
            }
        </style>
    </head>
    
    <body>
        <canvas id="can" width="2000" height="1200"></canvas>
    </body>
    
    <script type="text/javascript">
        let dom = document.getElementById('can');
    
        let can = dom.getContext('2d');
    
        // 把画布的圆心移动到画布的中心
        can.translate(dom.width / 2, dom.height / 2);
        // 保存当前的画布坐标系
        can.save()
    
    
        run();
    
    
    
        function run() {
            setInterval(function() {
                clearCanvas();
                draw();
            }, 10);
        }
    
        // 绘图
        function draw() {
            let time = new Date();
            let hour = time.getHours();
            let min = time.getMinutes();
            let sec = time.getSeconds();
            let minSec = time.getMilliseconds();
    
            drawPannl();
            drawHour(hour, min, sec);
            drawMin(min, sec);
            drawSec(sec, minSec);
            drawPoint();
        }
    
        // 最简单的方法:由于canvas每当高度或宽度被重设时,画布内容就会被清空
        function clearCanvas() {
            dom.height = dom.height;
            can.translate(dom.width / 2, dom.height / 2);
            can.save()
        }
    
        // 画表盘
        function drawPannl() {
            can.beginPath();
    
            can.restore()
            can.save()
    
            can.lineWidth = 10;
            can.strokeStyle = 'skyblue';
            can.arc(0, 0, 400, 0, 2 * Math.PI);
            can.stroke();
    
            for (let i = 0; i < 12; i++) {
                can.beginPath();
                can.lineWidth = 16;
                can.strokeStyle = 'greenyellow';
    
                can.rotate(2 * Math.PI / 12)
    
                can.moveTo(0, -395);
                can.lineTo(0, -340);
                can.stroke();
            }
    
            for (let i = 0; i < 60; i++) {
                can.beginPath();
                can.lineWidth = 10;
                can.strokeStyle = '#fff';
    
                can.rotate(2 * Math.PI / 60)
    
                can.moveTo(0, -395);
                can.lineTo(0, -370);
                can.stroke();
            }
        }
    
        // 画时针
        function drawHour(h, m, s) {
            can.beginPath();
    
            can.restore()
            can.save()
    
            can.lineWidth = 24;
            can.strokeStyle = 'palevioletred';
            can.lineCap = 'round'
            can.rotate(2 * Math.PI / (12 * 60 * 60) * (h * 60 * 60 + m * 60 + s))
            can.moveTo(0, 0);
            can.lineTo(0, -200);
            can.stroke();
        }
    
        // 画分针
        function drawMin(m, s) {
            can.beginPath();
    
            can.restore()
            can.save()
    
            can.lineWidth = 14;
            can.strokeStyle = '#09f';
            can.lineCap = 'round'
            can.rotate(2 * Math.PI / (60 * 60) * (m * 60 + s))
            can.moveTo(0, 0);
            can.lineTo(0, -260);
            can.stroke();
        }
    
        // 画秒针
        function drawSec(s, ms) {
            can.beginPath();
    
            can.restore()
            can.save()
    
            can.lineWidth = 8;
            can.strokeStyle = '#f00';
            can.lineCap = 'round'
            can.rotate(2 * Math.PI / (60 * 1000) * (s * 1000 + ms));
            can.moveTo(0, 50);
            can.lineTo(0, -320);
            can.stroke();
        }
    
    
        // 画中心点
        function drawPoint() {
            can.beginPath();
    
            can.restore()
            can.save()
    
            can.lineWidth = 10;
            can.fillStyle = 'red';
            can.arc(0, 0, 12, 0, 2 * Math.PI);
            can.fill();
        }
    </script>
    
    </html>
    

    圆弧时钟(案例)

    <!DOCTYPE html>
    <html>
    
    <head>
        <meta charset="utf-8">
        <title>clock</title>
        <style type="text/css">
            #can {
                 1000px;
                height: 600px;
                background: linear-gradient(45deg, rgb(94, 53, 6), black);
            }
        </style>
    </head>
    
    <body>
        <canvas id="can" width="2000" height="1200"></canvas>
    </body>
    
    <script type="text/javascript">
        let dom = document.getElementById('can');
    
        let can = dom.getContext('2d');
    
        // 把画布的圆心移动到画布的中心
        can.translate(dom.width / 2, dom.height / 2);
        // 保存当前的画布坐标系
        can.save();
    
        // 圆形指针起始角度
        let startDeg = 2 * Math.PI / 360 * 270;
    
    
        run();
        // draw();
    
    
        function run() {
            setInterval(function() {
                clearCanvas();
                draw();
            }, 20);
        }
    
        // 绘图
        function draw() {
            let time = new Date();
            // let hour = time.getHours();
            let hour = time.getHours() > 10 ? time.getHours() - 12 : time.getHours();
            let min = time.getMinutes();
            let sec = time.getSeconds();
            let minSec = time.getMilliseconds();
    
            drawPannl();
            drawTime(hour, min, sec, minSec);
            drawHour(hour, min, sec);
            drawMin(min, sec);
            drawSec(sec, minSec);
            drawPoint();
        }
    
        // 最简单的方法:由于canvas每当高度或宽度被重设时,画布内容就会被清空
        function clearCanvas() {
            dom.height = dom.height;
            can.translate(dom.width / 2, dom.height / 2);
            can.save()
        }
    
        // 画表盘
        function drawPannl() {
    
            can.restore()
            can.save()
    
            // 设置时表盘
            can.beginPath();
            can.lineWidth = 50;
            can.strokeStyle = 'rgba(255,23,87,0.2)';
            can.arc(0, 0, 400, 0, 2 * Math.PI);
            can.stroke();
            // 设置分表盘
            can.beginPath();
            can.strokeStyle = 'rgba(169,242,15,0.2)';
            can.arc(0, 0, 345, 0, 2 * Math.PI);
            can.stroke();
            // 设置秒表盘
            can.beginPath();
            can.strokeStyle = 'rgba(21,202,230,0.2)';
            can.arc(0, 0, 290, 0, 2 * Math.PI);
            can.stroke();
    
    
            // 小时刻度
            // for (let i = 0; i < 12; i++) {
            //     can.beginPath();
            //     can.lineWidth = 16;
            //     can.strokeStyle = 'rgba(0,0,0,0.2)';
    
            //     can.rotate(2 * Math.PI / 12)
    
            //     can.moveTo(0, -375);
            //     can.lineTo(0, -425);
            //     can.stroke();
            // }
    
            // 分针刻度
            // for (let i = 0; i < 60; i++) {
            //     can.beginPath();
            //     can.lineWidth = 10;
            //     can.strokeStyle = '#fff';
    
            //     can.rotate(2 * Math.PI / 60)
    
            //     can.moveTo(0, -395);
            //     can.lineTo(0, -370);
            //     can.stroke();
            // }
        }
    
        // 画时针
        function drawHour(h, m, s) {
    
            let rotateDeg = 2 * Math.PI / (12 * 60 * 60) * (h * 60 * 60 + m * 60 + s);
    
            can.beginPath();
            can.restore()
            can.save()
    
            // 时针圆弧
            can.lineWidth = 50;
            can.strokeStyle = 'rgb(255,23,87)';
            can.lineCap = 'round';
            can.shadowColor = "rgb(255,23,87)"; // 设置阴影颜色
            can.shadowBlur = 20; // 设置阴影范围
            can.arc(0, 0, 400, startDeg, startDeg + rotateDeg);
            can.stroke();
    
            // 时针指针
            can.beginPath();
            can.lineWidth = 24;
            can.strokeStyle = 'rgb(255,23,87)';
            can.lineCap = 'round'
            can.rotate(rotateDeg)
            can.moveTo(0, 0);
            can.lineTo(0, -100);
            can.stroke();
    
    
    
        }
    
        // 画分针
        function drawMin(m, s) {
    
            let rotateDeg = 2 * Math.PI / (60 * 60) * (m * 60 + s);
    
            can.beginPath();
            can.restore()
            can.save()
    
            // 分针圆弧
            can.lineWidth = 50;
            can.strokeStyle = 'rgb(169,242,15)';
            can.lineCap = 'round'
            can.shadowColor = "rgb(169,242,15)";
            can.shadowBlur = 20;
            can.arc(0, 0, 345, startDeg, startDeg + rotateDeg);
            can.stroke();
    
            // 分针指针
            can.beginPath();
            can.lineWidth = 14;
            can.strokeStyle = 'rgb(169,242,15)';
            can.lineCap = 'round'
            can.rotate(rotateDeg)
            can.moveTo(0, 0);
            can.lineTo(0, -160);
            can.stroke();
        }
    
        // 画秒针
        function drawSec(s, ms) {
    
            let rotateDeg = 2 * Math.PI / (60 * 1000) * (s * 1000 + ms);
    
            can.beginPath();
            can.restore()
            can.save()
    
            can.lineWidth = 50;
            can.strokeStyle = 'rgb(21,202,230)';
            can.lineCap = 'round'
            can.arc(0, 0, 290, startDeg, startDeg + rotateDeg);
            can.stroke();
    
            can.beginPath();
            can.lineWidth = 8;
            can.strokeStyle = 'rgb(21,202,230)';
            can.lineCap = 'round'
            can.shadowColor = "rgb(21,202,230)";
            can.shadowBlur = 20;
            can.rotate(rotateDeg);
            can.moveTo(0, 50);
            can.lineTo(0, -220);
            can.stroke();
        }
    
    
        // 画中心点
        function drawPoint() {
            can.beginPath();
            can.restore()
            can.save()
    
            can.lineWidth = 10;
            can.fillStyle = 'red';
            can.arc(0, 0, 12, 0, 2 * Math.PI);
            can.fill();
        }
    
        // 显示数字时钟
        function drawTime(h, m, s, ms) {
            can.font = '60px Calibri';
            can.fillStyle = '#0f0'
            can.shadowColor = "#fff";
            can.shadowBlur = 20;
            can.fillText(`${h}:${m}:${s}.${ms}`, -140, -100);
        }
    </script>
    
    </html>
    

    (啾咪 ^.<)

  • 相关阅读:
    Java之时间处理(当前年的上一年、上一季度、当月、当季)
    Nginx代理之大文件下载失败问题
    PageHelper之排序
    MySQL之集群配置
    Java之判断字符串是否为数字(包含浮点型数据)
    /bin/mysqld: error while loading shared libraries: libaio.so.1: cannot open shared object file:
    Error Code: 1153
    413 Request Entity Too Large
    MyBatis分页插件失效问题之解决
    HikariConfig 连接池属性详解
  • 原文地址:https://www.cnblogs.com/lvonve/p/11937705.html
Copyright © 2011-2022 走看看