Canvas简单学习

一、基础

canvas标签,设置画布宽高及浏览器不支持canvas时提示信息。

<canvas id="drawing" width="1000" height="600">your browser not hold cnavas.</canvas>
    <script>
        var drawing = document.querySelector("#drawing");
        drawing.style.border = "1px solid #000";

        if (drawing.getContext){
            var context = drawing.getContext("2d");

            context.fillStyle = "orange";  // 填充样式
            context.strokeStyle = "red";  // 描边样式
            // 矩形
            context.fillRect(10, 10, 80, 80);
            context.strokeRect(100, 10, 80, 80);
            context.clearRect(30, 30, 20, 20);

            // 路径
            context.beginPath();
            // 圆弧
            context.arc(60, 150, 50, 0, 2*Math.PI, false); // Ox, Oy, radius, startA, endA, dire
            // 弧线
            context.arcTo(170, 150, 210, 180, 150); // Ox, Oy, Nx, Ny, radius
            // 直线
            context.lineTo(260, 230);  // Nx, Ny
            // 矩形线
            context.rect(10, 300, 50, 50);

            // 闭合路劲
            context.closePath();

            context.stroke();  // 描边
            context.fill();  // 填充

            // 文本
            context.font = "bold 16px Arial";
            context.textAlign = "start";
            context.textBaseline = "top";
            context.fillText("text", 300, 10);
        }
    </script>

二、划分区域

类似于绘制坐标图

    <script>
        var drawing = document.querySelector("#drawing");

        if (drawing.getContext){
            var context = drawing.getContext("2d");

            context.strokeStyle = "#000";
            context.lineWidth = 1;
            context.beginPath();
            context.font = "14px";
            context.textBaseline = "middle";
            drawLine(context, 0);
            context.textAlign = "center";
            context.textBaseline = "top";
            drawLine(context, 1);

            context.stroke();
        }
        function drawLine(context, mode) {
            // Horizontal
            if (mode == 0){
                for(var i=0;i<6;i++){
                    context.moveTo(0, 100*(i+1));
                    context.lineTo(1000, 100*(i+1));
                    context.fillText(100*(i+1)+"px", 0, 100*(i+1));
                }
            }else if(mode == 1){
                for(var i=0;i<9;i++){
                    context.moveTo(100*(i+1), 0);
                    context.lineTo(100*(i+1), 700);
                    context.fillText(100*(i+1)+"px", 100*(i+1), 0);
                }
            }
        }
    </script>

效果如下:

三、图像绘制

图像的绘制,阴影、渐变的使用

    <script>
        var drawing = document.getElementById("drawing");
        var image = document.getElementsByTagName("img")[0];

        if(drawing.getContext){
            var context = drawing.getContext("2d");

            context.drawImage(image, 10, 10, 200, 150);  // image, posX, posY, contextWit, contextHei
            // image, imageX, imageY, imageWid, imageHei, posX, posY, contextWit, contextHei
            context.drawImage(image, 0, 0, 1920, 1080, 10, 170, 400, 300);

            // 阴影
            context.shadowColor = "#000";
            context.shadowOffsetX = 0;
            context.shadowOffsetY = 0;
            context.shadowBlur = 50;

            context.fillStyle = "orange";
            context.fillRect(400, 10, 100, 100);

            // 渐变
            // startX, startY, endX, endY
            var gradient = context.createLinearGradient(500, 150, 600, 250);
            gradient.addColorStop(0, "#fff");
            gradient.addColorStop(1, "#000");
            context.fillStyle = gradient;
            context.fillRect(500, 150, 100, 100);

            // startOX, startOY, startRadius, endOX, endOY, endRadius
            gradient = context.createRadialGradient(700, 350, 0, 700, 350, 100);
            gradient.addColorStop(0, "#fff");
            gradient.addColorStop(1, "#000");
            context.fillStyle = gradient;
            context.beginPath();
            context.arc(700, 350, 100, 0, 2*Math.PI);
            context.fill();
        }
    </script>

效果如下:

四、case

1.动态实时时钟

<script>
    var drawing = document.getElementById("drawing");

    if(drawing.getContext){
        var context = drawing.getContext("2d");

        context.strokeStyle = "#000";
        context.font = "bold 18px Arial";
        context.textAlign = "center";
        context.textBaseline = "middle";
        context.translate(270, 270);  // 移动原点
        showClock(context);
        setInterval(function () {
            context.clearRect(-270, -270, 1000, 700);
            showClock(context);
        }, 1000)
    }
    function showClock(context) {
        context.beginPath();
        context.arc(0, 0, 258, 0, 2*Math.PI); // 外圆半径258
        context.moveTo(250, 0);
        context.arc(0, 0, 250, 0, 2*Math.PI);  // 内圆半径250
        drawMoment(context);
        computePointer(context, 0);
        computePointer(context, 1);
        computePointer(context, 2);

        context.stroke();
    }
    function drawMoment(context) {
        var posX, posY, markEndX, markEndY, posDeg;
        for(var i=0;i<12;i++){
            posDeg = i*360/12;
            posX = Math.sin(posDeg*Math.PI/180)*230;  // 时刻文字距圆心距离230
            posY = Math.cos(posDeg*Math.PI/180)*-230;
            if(i === 0){
                context.fillText("12", posX, posY);
            }else{
                context.fillText(i.toString(), posX, posY);
            }
        }
        for(var j=0;j<60;j++){
            posDeg = j*360/60;
            posX = Math.sin(posDeg*Math.PI/180)*250;
            posY = Math.cos(posDeg*Math.PI/180)*-250;
            markEndX = Math.cos((posDeg+270)*Math.PI/180)*(250-4);  // 普通时刻标记线长4
            markEndY = Math.sin((posDeg+270)*Math.PI/180)*(250-4);
            if(parseInt(j/5) === j/5){
                markEndX = Math.cos((posDeg+270)*Math.PI/180)*(250-9);  // 整点时刻标记线长9
                markEndY = Math.sin((posDeg+270)*Math.PI/180)*(250-9);
            }
            context.moveTo(posX, posY);
            context.lineTo(markEndX, markEndY);
        }
    }
    function computePointer(context, mode) {
        var myDate = new Date();
        var hourPointerLen = 150,  // 时针长
            minutePointerLen = 180,  // 分针长
            secondPointerLen = 220;  // 秒针长
        // 以3点方向为0的方位角,下同
        var secondDeg = myDate.getSeconds()*360/60 + 270,
            minuteDeg = myDate.getMinutes()*360/60 + (secondDeg-270)/60 + 270,
            hourDeg = myDate.getHours()*360/12 + (minuteDeg-270)/12 + 270;

        if(mode === 0){
            // 时针
            drawPointer(context, hourDeg, hourPointerLen);
        }else if(mode === 1){
            // 分针
            drawPointer(context, minuteDeg, minutePointerLen);
        }else if(mode === 2){
            // 秒针
            drawPointer(context, secondDeg, secondPointerLen);
        }
    }
    function drawPointer(context, dge, len) {
        var posX = Math.cos(dge*Math.PI/180)*len;
        var posY = Math.sin(dge*Math.PI/180)*len;
        var mark1X = posX + Math.cos((dge-135)*Math.PI/180)*10; // 以3点方向为0的方位角,下同
        var mark1Y = posY + Math.sin((dge-135)*Math.PI/180)*10; // 指针箭头部分长10
        var mark2X = posX + Math.cos((dge-225)*Math.PI/180)*10;
        var mark2Y = posY + Math.sin((dge-225)*Math.PI/180)*10;

        context.moveTo(0, 0);
        context.lineTo(posX, posY);
        context.lineTo(mark1X, mark1Y);
        context.moveTo(posX, posY);
        context.lineTo(mark2X, mark2Y);
    }
</script>

效果图如下:

展示链接: https://tanf1995.github.io/js-css3-specialEffets/Canvas%E5%8A%A8%E6%80%81%E6%97%B6%E9%92%9F/index.html

2.图像灰阶处理

    <script>
        var drawing = document.getElementById("drawing");
        var pic = document.getElementsByTagName("img")[0];

        if (drawing.getContext){
            var context = drawing.getContext("2d");

            context.drawImage(pic, 10, 10, 400, 300);

            var imageData = context.getImageData(10, 10, 400, 300);
            console.log(imageData.width + "---" + imageData.height);
            var data = imageData.data;

            // data为数组,依次为各像素点红、绿、蓝、透明度值
            for(var i=0, len=data.length;i< len;i += 4){
                var red = data[i],
                    green = data[i+1],
                    blue = data[i+2],
                    alpha = data[i+3];

                aveValue = Math.floor((red + green + blue)/3);

                data[i] = data[i+1] = data[i+2] = aveValue;
            }
            imageData.data = data;
            context.putImageData(imageData, 10, 10);
        }
    </script>

效果如下:

原理:通过getImageDate()函数获取到图像的数据,返回一个包含三个元素的数组,分别为图像宽、高及图像源数据列表。源数据列表的元素依次为图像每个像素的红、绿、蓝原色及透明度,正是每个元素的三原色以及透明度共同构成了彩色的图像。然后将三原色求平均值,并使每个像素的三原色都为该平均值,而透明度不变,最后呈现出的图像就是灰色的(三原色相等为灰色,不同值构成了图像)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值