Canvas

作者: 苦苦修行 | 来源:发表于2018-08-20 18:06 被阅读0次

参考文献:学习HTML5 Canvas这一篇文章就够了

依次解除注释看效果

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>canvas practice</title>
</head>
<style>
    canvas {
        border: 1px solid black;
    }
</style>
<body>
<canvas id="canvas" width="300" height="300">
    您的浏览器太老了,不支持canvas,请升级您的浏览器!
</canvas>
<p>
    1、lineTo、arc、arcTo、bezierCurveTo、quadraticCurveTo等方法是绘制路径(此时还不可见),stroke方法是将路径画出来(应用了样式,此时可见了)
</p>
<p>
    2、stroke方法用来描边、fill方法用来填充
</p>
<p>
    3、贝塞尔曲线关键点:两个点连线上的点匀速运动;以相同的时间从起点到终点
</p>
</body>
<script
        src="https://code.jquery.com/jquery-3.3.1.min.js"
        integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
        crossorigin="anonymous"></script>


<script>
    // get canvas dom object
    let canvas = $('#canvas')[0];
    // get canvas 2D context
    let ctx = canvas.getContext('2d');
    // check if browser support canvas
    if (ctx) {
        console.info('support');

        /*ctx.fillStyle = 'rgb(200,0,0)';
        ctx.fillRect(10,10,55,50);

        ctx.fillStyle = 'rgba(0,0,200,0.5)';
        ctx.fillRect(30,30,55,50);*/

        /*ctx.fillRect(10,10,100,50);
        ctx.strokeRect(10,70,100,50);
        ctx.clearRect(15,15,50,25);*/

        /*ctx.beginPath();//使用路径指令
        ctx.moveTo(0,50);//设置起点
        ctx.lineTo(300,50);//绘制路径,使用直线绘制
        ctx.closePath();//闭合路径
        ctx.stroke();//使用样式将路径画出来,这里因为没有指定,使用默认样式*/

        /*ctx.beginPath();
        ctx.moveTo(50,50);
        ctx.lineTo(200,50);
        ctx.lineTo(200,200);
        //ctx.closePath();
        ctx.stroke();
        ctx.fillStyle = 'yellow';
        ctx.fill();//fill具有自动闭合的功能,但不能应用描边的样式*/

        /*ctx.beginPath();
        ctx.arc(50,50,40,0, Math.PI/2,true);
        ctx.closePath();
        ctx.stroke();
        ctx.fillStyle = 'yellow';
        ctx.fill();*/

        /*ctx.beginPath();
        ctx.moveTo(50,50);
        ctx.arcTo(200,50,200,200,100);
        ctx.stroke();*/

        /*ctx.beginPath();
        ctx.moveTo(10,200);
        let cp1x = 40, cp1y = 100;
        let x = 200, y = 200;
        ctx.quadraticCurveTo(cp1x,cp1y,x,y);
        ctx.stroke();*/

        /*ctx.beginPath();
        ctx.moveTo(40, 200);
        let cp1x = 20, cp1y = 100;
        let cp2x = 100, cp2y = 120;
        let x = 200, y = 200;
        ctx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y);
        ctx.stroke();*/

        /*for (let i = 0; i < 6; i++) {
            for (let j = 0; j < 6; j++) {
                ctx.fillStyle = `rgb(${Math.floor(255 - 42.5 * i)},${Math.floor(255 - 42.5 * j)},0`;
                ctx.fillRect(j * 50, i * 50, 50, 50);
            }
        }*/

        /*function randomInt(from, to) {
            return parseInt(Math.random() * (to - from + 1) + from);
        }
        for (let i = 0; i < 6; i++) {
            for (let j = 0; j < 6; j++) {
                ctx.strokeStyle = `rgb(${randomInt(0, 255)},${randomInt(0, 255)},${randomInt(0, 255)})`;
                ctx.strokeRect(j * 50, i * 50, 40, 40);
            }
        }*/

        /*ctx.beginPath();
        ctx.moveTo(10,10);
        ctx.lineTo(100,10);
        ctx.lineWidth = 10;
        ctx.stroke();

        ctx.beginPath();
        ctx.moveTo(110,10);
        ctx.lineTo(160,10);
        ctx.lineWidth = 20;
        ctx.stroke();*/

        /*let lineCaps = ['button', 'round', 'square'];
        for (let i = 0; i < 3; i++) {
            ctx.beginPath();
            ctx.moveTo(20 + 30 * i, 30);
            ctx.lineTo(20 + 30 * i, 100);
            ctx.lineWidth = 20;
            ctx.lineCap = lineCaps[i];
            ctx.stroke();
        }
        ctx.beginPath();
        ctx.moveTo(0, 30);
        ctx.lineTo(300, 30);
        ctx.moveTo(0, 100);
        ctx.lineTo(300, 100);
        ctx.strokeStyle = 'red';
        ctx.lineWidth = 1;
        ctx.stroke();*/

        /*let lineJoin = ['round', 'bevel', 'miter'];
        ctx.lineWidth = 20;
        for (let i = 0; i < 3; i++) {
            ctx.lineJoin = lineJoin[i];
            ctx.beginPath();//试一下,如果将这行代码放在for循环之前,会发生什么事情
            ctx.moveTo(50, 50 + i * 50);
            ctx.lineTo(100, 100 + i * 50);
            ctx.lineTo(150, 50 + i * 50);
            ctx.lineTo(200, 100 + i * 50);
            ctx.lineTo(250, 50 + i * 50);
            ctx.stroke();
        }*/

        /*ctx.setLineDash([20, 5]);
        ctx.lineDashOffset = 0;
        ctx.strokeRect(50, 50, 210, 210);
        console.log(ctx.getLineDash());*/

        /*ctx.font = '30px sans-serif';
        ctx.direction = 'ltr';//need to enable chrome feature
        ctx.strokeStyle = 'rgba(188,165,34,0.5)';
        ctx.fillText('何事秋风悲画扇',10,100);
        ctx.strokeText('那人却在灯火阑珊处',10,200);*/

        /*let img = new Image();
        img.src = 'https://ss1.baidu.com/6ONXsjip0QIZ8tyhnq/it/u=2398393444,3602364069&fm=173&app=25&f=JPEG?w=640&h=390&s=2CC46B840A73649A8A819118030080D0';
        img.onload = function () {
            const naturalWidth = img.naturalWidth;
            const naturalHeight = img.naturalHeight;//modern browser
            console.log(img.height);//old browser
            if (naturalWidth > naturalHeight) {
                ctx.drawImage(img, 0, 0, 300, naturalHeight * 300 / naturalWidth);
            } else {
                ctx.drawImage(img, 0, 0, 300 * naturalWidth / naturalHeight, 300);
            }

            //drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight)
            ctx.drawImage(img, 260, 70, 100, 100, 10, 200, 100, 100);//sx, sy指的是以图片原始大小为基础进行的定位
        };*/

        /*ctx.fillRect(0,0,150,150);
        ctx.save();
        ctx.fillStyle = 'red';
        ctx.fillRect(15,15,120,120);
        ctx.save();
        ctx.fillStyle = '#fff';
        ctx.fillRect(30, 30, 90, 90);
        ctx.restore();
        ctx.fillRect(45, 45, 60, 60);//should be red
        ctx.restore();
        ctx.fillRect(60, 60, 30, 30);//should be black(default)*/

        /*ctx.save();//就像push方法,将当前状态压入栈中
        ctx.translate(100, 100);
        ctx.strokeRect(0, 0, 100, 100);
        ctx.restore();//就像pop方法,将栈顶状态弹出来
        ctx.translate(220, 220);//想想如果不执行restore方法,执行完这行代码后会发生什么情况
        ctx.fillRect(0, 0, 50, 50);*/

        /*ctx.fillStyle = "red";
        ctx.save();
        ctx.translate(100, 100);
        ctx.rotate(Math.PI / 180 * 45);
        ctx.fillStyle = "blue";
        ctx.fillRect(0, 0, 100, 100);
        ctx.restore();
        ctx.fillRect(0, 0, 50, 50);*/

        /*ctx.fillRect(0, 0, 100, 100);
        ctx.scale(0.5,0.5);
        ctx.fillStyle = 'gray';
        ctx.fillRect(200, 200, 100, 100);//注意x、y点应该是200,实际的定位点经过缩小到0.5倍后,就是看到的(100,100)的位置
        ctx.restore();*/

        /*//随机展示
        let globalCompositeOperation = ['source-over', 'source-in', 'source-out',
            'source-atop', 'destination-over', 'destination-in',
            'destination-out', 'destination-atop', 'lighter',
            'darken', 'lighten', 'xor', 'copy'];
        ctx.fillStyle = "blue";
        ctx.fillRect(0, 0, 200, 200);
        let i = Math.floor(Math.random() * 13);//向下取整
        let selected = globalCompositeOperation[i];
        console.log('random globalCompositeOperation is:', selected);
        ctx.globalCompositeOperation = selected; //全局合成操作
        ctx.fillStyle = "red";
        ctx.fillRect(100, 100, 200, 200);

        ctx.beginPath();
        ctx.arc(20,20, 100, 0, Math.PI * 2);
        ctx.clip();//试着注释掉这行代码看看效果
        ctx.fillStyle = "pink";
        ctx.fillRect(20, 20, 100,100);*/
    } else {
        console.error('sorry');
    }
</script>
</html>

转载simulation clock实现

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>simulation clock</title>
    <style>
        body {
            padding: 0;
            margin: 0;
            background-color: rgba(0, 0, 0, 0.1)
        }

        canvas {
            display: block;
            margin: 200px auto;
            background: black;
        }
    </style>
</head>
<body>
<canvas id="simulation-clock" width="300" height="300"></canvas>
<script>
    init();

    function init() {
        let canvas = document.querySelector("#simulation-clock");
        let ctx = canvas.getContext("2d");
        draw(ctx);
    }

    function draw(ctx) {
        requestAnimationFrame(function step() {
            drawDial(ctx); //绘制表盘
            drawAllHands(ctx); //绘制时分秒针
            requestAnimationFrame(step);
        });
    }

    /*绘制时分秒针*/
    function drawAllHands(ctx) {
        let time = new Date();

        let s = time.getSeconds();
        let m = time.getMinutes();
        let h = time.getHours();

        let pi = Math.PI;
        let secondAngle = pi / 180 * 6 * s;  //计算出来s针的弧度
        let minuteAngle = pi / 180 * 6 * m + secondAngle / 60;  //计算出来分针的弧度
        let hourAngle = pi / 180 * 30 * h + minuteAngle / 12;  //计算出来时针的弧度

        drawHand(hourAngle, 60, 6, "red", ctx);  //绘制时针
        drawHand(minuteAngle, 106, 4, "green", ctx);  //绘制分针
        drawHand(secondAngle, 129, 2, "blue", ctx);  //绘制秒针
    }

    /*绘制时针、或分针、或秒针
     * 参数1:要绘制的针的角度
     * 参数2:要绘制的针的长度
     * 参数3:要绘制的针的宽度
     * 参数4:要绘制的针的颜色
     * 参数4:ctx
     * */
    function drawHand(angle, len, width, color, ctx) {
        ctx.save();
        ctx.translate(150, 150); //把坐标轴的远点平移到原来的中心
        ctx.rotate(-Math.PI / 2 + angle);  //旋转坐标轴。 x轴就是针的角度
        ctx.beginPath();
        ctx.moveTo(-4, 0);
        ctx.lineTo(len, 0);  // 沿着x轴绘制针
        ctx.lineWidth = width;
        ctx.strokeStyle = color;
        ctx.lineCap = "round";
        ctx.stroke();
        ctx.closePath();
        ctx.restore();
    }

    /*绘制表盘*/
    function drawDial(ctx) {
        let pi = Math.PI;

        ctx.clearRect(0, 0, 300, 300); //清除所有内容
        ctx.save();

        ctx.translate(150, 150); //一定坐标原点到原来的中心
        ctx.beginPath();
        ctx.arc(0, 0, 148, 0, 2 * pi); //绘制圆周
        ctx.stroke();
        ctx.closePath();

        for (let i = 0; i < 60; i++) {//绘制刻度。
            ctx.save();
            ctx.rotate(-pi / 2 + i * pi / 30);  //旋转坐标轴。坐标轴x的正方形从 向上开始算起
            ctx.beginPath();
            ctx.moveTo(110, 0);
            ctx.lineTo(140, 0);
            ctx.lineWidth = i % 5 ? 2 : 4;
            ctx.strokeStyle = i % 5 ? "blue" : "red";
            ctx.stroke();
            ctx.closePath();
            ctx.restore();
        }
        ctx.restore();
    }
</script>
</body>
</html>

相关文章

网友评论

      本文标题:Canvas

      本文链接:https://www.haomeiwen.com/subject/bunliftx.html