CANVAS

Canvas

canvas 最早由Apple引入WebKit,用于Mac OS X 的 Dashboard,后来又在Safari和Google Chrome被实现。
基于 Gecko 1.8的浏览器,比如 Firefox 1.5, 同样支持这个元素。
<canvas> 元素是WhatWG Web applications 1.0规范的一部分,也包含于HTML 5中。

参考

什么是Canvas?

HTML5 的 canvas 元素使用 JavaScript 在网页上绘制图像。
画布是一个矩形区域,您可以控制其每一像素。
canvas 拥有多种绘制路径、矩形、圆形、字符以及添加图像的方法。

创建Canvas元素

向 HTML5 页面添加 canvas 元素。 规定元素的 id、宽度和高度:

<canvas id="myCanvas" width="200" height="100"></canvas>

Canvas坐标系

location.jpg

通过JavaScript来绘制

    /*获取元素*/
    var myCanvas = document.querySelector('#myCanvas');
    /*获取绘图工具*/
    var context = myCanvas.getContext('2d');
    /*设置绘图的起始位置*/
    context.moveTo(100,100);
    /*绘制路径*/
    context.lineTo(200,200);
    /*描边*/
    context.stroke();

Canvas的基本使用

图形绘制

需要理解些概念:

  • 路径的概念

  • 路径的绘制

    • 描边 stroke()
    • 填充 fill()
      path.jpg
  • 开启新的路径 beginPath()

  • 闭合路径

    • 手动闭合
    • 程序闭合 closePath()
  • 填充规则(非零环绕)

    zero.jpg

设置样式

  • 画笔
    • lineWidth 线宽,默认1px
    • lineCap 线末端类型:(butt默认)、round、square
    • lineJoin 相交线的拐点 miter(默认)、round、bevel
    • strokeStyle 线的颜色
    • fillStyle 填充颜色
    • setLineDash() 设置虚线
    • getLineDash() 获取虚线宽度集合
    • lineDashOffset 设置虚线偏移量(负值向右偏移)

折线图

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        canvas {
            border: 1px solid #ccc;
        }
    </style>
</head>
<body>
<canvas width="600" height="400"></canvas>
<script>
    /*1.构造函数*/
    var LineChart = function (ctx) {
        /*获取绘图工具*/
        this.ctx = ctx || document.querySelector('canvas').getContext('2d');
        /*画布的大小*/
        this.canvasWidth = this.ctx.canvas.width;
        this.canvasHeight = this.ctx.canvas.height;
        /*网格的大小*/
        this.gridSize = 10;
        /*坐标系的间距*/
        this.space = 20;
        /*坐标原点*/
        this.x0 = this.space;
        this.y0 = this.canvasHeight - this.space;
        /*箭头的大小*/
        this.arrowSize = 10;
        /*绘制点*/
        this.dottedSize = 6;
        /*点的坐标 和数据有关系  数据可视化*/
    }
    /*2.行为方法*/
    LineChart.prototype.init = function (data) {
        this.drawGrid();
        this.drawAxis();
        this.drawDotted(data);
    };
    /*绘制网格*/
    LineChart.prototype.drawGrid = function () {
        /*x方向的线*/
        var xLineTotal = Math.floor(this.canvasHeight / this.gridSize);
        this.ctx.strokeStyle = '#eee';
        for (var i = 0; i <= xLineTotal; i++) {
            this.ctx.beginPath();
            this.ctx.moveTo(0, i * this.gridSize - 0.5);
            this.ctx.lineTo(this.canvasWidth, i * this.gridSize - 0.5);
            this.ctx.stroke();
        }
        /*y方向的线*/
        var yLineTotal = Math.floor(this.canvasWidth / this.gridSize);
        for (var i = 0; i <= yLineTotal; i++) {
            this.ctx.beginPath();
            this.ctx.moveTo(i * this.gridSize - 0.5, 0);
            this.ctx.lineTo(i * this.gridSize - 0.5, this.canvasHeight);
            this.ctx.stroke();
        }
    };
    /*绘制坐标系*/
    LineChart.prototype.drawAxis = function () {
        /*X轴*/
        this.ctx.beginPath();
        this.ctx.strokeStyle = '#000';
        this.ctx.moveTo(this.x0, this.y0);
        this.ctx.lineTo(this.canvasWidth - this.space, this.y0);
        this.ctx.lineTo(this.canvasWidth - this.space - this.arrowSize, this.y0 + this.arrowSize / 2);
        this.ctx.lineTo(this.canvasWidth - this.space - this.arrowSize, this.y0 - this.arrowSize / 2);
        this.ctx.lineTo(this.canvasWidth - this.space, this.y0);
        this.ctx.stroke();
        this.ctx.fill();
        /*Y轴*/
        this.ctx.beginPath();
        this.ctx.strokeStyle = '#000';
        this.ctx.moveTo(this.x0, this.y0);
        this.ctx.lineTo(this.space, this.space);
        this.ctx.lineTo(this.space + this.arrowSize / 2, this.space + this.arrowSize);
        this.ctx.lineTo(this.space - this.arrowSize / 2, this.space + this.arrowSize);
        this.ctx.lineTo(this.space, this.space);
        this.ctx.stroke();
        this.ctx.fill();
    };
    /*绘制所有点*/
    LineChart.prototype.drawDotted = function (data) {
        /*1.数据的坐标 需要转换 canvas坐标*/
        /*2.再进行点的绘制*/
        /*3.把线连起来*/
        var that = this;
        /*记录当前坐标*/
        var prevCanvasX = 0;
        var prevCanvasY = 0;
        data.forEach(function (item, i) {
            /* x = 原点的坐标 + 数据的坐标 */
            /* y = 原点的坐标 - 数据的坐标 */
            var canvasX = that.x0 + item.x;
            var canvasY = that.y0 - item.y;
            /*绘制点*/
            that.ctx.beginPath();
            that.ctx.moveTo(canvasX - that.dottedSize / 2, canvasY - that.dottedSize / 2);
            that.ctx.lineTo(canvasX + that.dottedSize / 2, canvasY - that.dottedSize / 2);
            that.ctx.lineTo(canvasX + that.dottedSize / 2, canvasY + that.dottedSize / 2);
            that.ctx.lineTo(canvasX - that.dottedSize / 2, canvasY + that.dottedSize / 2);
            that.ctx.fillStyle = 'red';
            that.ctx.closePath();
            that.ctx.fill();
            /*点的连线*/
            /*当时第一个点的时候 起点是 x0 y0*/
            /*当时不是第一个点的时候 起点是 上一个点*/
            that.ctx.strokeStyle = 'red';
            if(i == 0){
                that.ctx.beginPath();
                that.ctx.moveTo(that.x0,that.y0);
                that.ctx.lineTo(canvasX,canvasY);
                that.ctx.stroke();
            }else{
                /*上一个点*/
                that.ctx.beginPath();
                that.ctx.moveTo(prevCanvasX,prevCanvasY);
                that.ctx.lineTo(canvasX,canvasY);
                that.ctx.stroke();
            }
            /*记录当前的坐标,下一次要用*/
            prevCanvasX = canvasX;
            prevCanvasY = canvasY;
        });
    };
    /*3.初始化*/
    var data = [
        {
            x: 100,
            y: 120
        },
        {
            x: 200,
            y: 160
        },
        {
            x: 300,
            y: 240
        },
        {
            x: 400,
            y: 120
        },
        {
            x: 500,
            y: 80
        }
    ];
    var lineChart = new LineChart();
    lineChart.init(data);
</script>
</body>
</html>
  • 文本
    • ctx.font = '微软雅黑' 设置字体
    • strokeText()
      • text 要绘制的文本
      • x,y 文本绘制的坐标(文本左下角)
      • maxWidth 设置文本最大宽度,可选参数
    • fillText(text,x,y,maxWidth)
      • text 要绘制的文本
      • x,y 文本绘制的坐标(文本左下角)
      • maxWidth 设置文本最大宽度,可选参数
    • ctx.textAlign文本水平对齐方式,相对绘制坐标来说的
      • left
      • center
      • right
      • start 默认
      • end
      • direction属性css(rtl ltr) start和end于此相关
        • 如果是ltr,start和left表现一致
        • 如果是rtl,start和right表现一致
    • ctx.textBaseline 设置基线(垂直对齐方式 )
      • top 文本的基线处于文本的正上方,并且有一段距离
      • middle 文本的基线处于文本的正中间
      • bottom 文本的基线处于文本的证下方,并且有一段距离
      • hanging 文本的基线处于文本的正上方,并且和文本粘合
      • alphabetic 默认值,基线处于文本的下方,并且穿过文字
      • ideographic 和bottom相似,但是不一样
    • measureText() 获取文本宽度obj.width

文本绘制

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>word</title>

    <style>
        canvas {
            border: 1px solid #ccc;
        }
    </style>
</head>
<body>
    <canvas width="600" height="400"></canvas>

    <script>
        // 获取canvas上下文
        var canvas = document.querySelector('canvas');
        var ctx = canvas.getContext('2d');

        // 获取canvas画布宽高
        var canvasWidth = ctx.canvas.width;
        var canvasHeight = ctx.canvas.height;

        // 绘制基准线
        ctx.moveTo(canvasWidth / 2, 0);
        ctx.lineTo(canvasWidth / 2, canvasHeight);
        ctx.moveTo(0, canvasHeight / 2);
        ctx.lineTo(canvasWidth, canvasHeight / 2);
        ctx.strokeStyle = '#ccc';
        ctx.stroke();

        // 绘制文字
        ctx.beginPath();
        ctx.strokeStyle = '#000';
        var str = '获取canvas上下文';
        ctx.font = '24px 微软雅黑';
        // 文本水平对齐方式
        // ctx.textAlign = 'left';
        // ctx.textAlign = 'right';
        ctx.textAlign = 'center';
        // 文本垂直对齐方式
        // ctx.textBaseline = 'top';
        // ctx.textBaseline = 'bottom';
        // ctx.textBaseline = 'hanging';
        ctx.textBaseline = 'middle';


        ctx.strokeText(str, canvasWidth / 2, canvasHeight / 2);
    </script>
</body>
</html>

Canvas图形绘制

矩形绘制

  • rect(x,y,w,h) 没有独立路径
  • strokeRect(x,y,w,h) 有独立路径,不影响别的绘制
  • fillRect(x,y,w,h) 有独立路径,不影响别的绘制
  • clearRect(x,y,w,h) 擦除矩形区域

绘制一个线性渐变矩形

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>rect</title>
    <style>
        canvas {
            border: 1px solid #ccc;
            margin: 200px 650px;
        }
    </style>
</head>
<body>
    <canvas width="600" height="400"></canvas>

    <script>
        // 获取canvas对象
        var canvas = document.querySelector('canvas');
        // 获取canvas上下文
        var ctx = canvas.getContext('2d');

        // 绘制矩形
        // 设置填充样式
        ctx.fillStyle = 'red';
        ctx.fillRect(100, 50, 400, 100);

        // 绘制渐变矩形
        // 创建一个线性渐变方案linearGradient
        var linearGradient = ctx.createLinearGradient(0, 0, 600, 0);
        linearGradient.addColorStop(0, 'green');
        linearGradient.addColorStop(0.5, 'blue');
        linearGradient.addColorStop(1, 'red');
        ctx.fillStyle = linearGradient;
        ctx.fillRect(100, 200, 400, 100)
    </script>
</body>
</html>

圆弧绘制

  • 弧度概念
  • arc()
    • x 圆心横坐标
    • y 圆心纵坐标
    • r 半径
    • startAngle 开始角度
    • endAngle 结束角度
    • anticlockwise 是否逆时针方向绘制(默认false表示顺时针;true表示逆时针)

绘制随机颜色等分圆

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>quxian</title>

    <style>
        canvas {
            border: 1px solid #ccc;
        }
    </style>
</head>
<body>
    <canvas width="600" height="400"></canvas>

    <script>
        var canvas = document.querySelector('canvas');
        var ctx = canvas.getContext('2d');
        
        // 获取canvas画布宽和高
        var canvasWidth = ctx.canvas.width;
        var canvasHeight = ctx.canvas.height;

        // 定义绘制原点位置
        var x0 = canvasWidth / 2;
        var y0 = canvasHeight / 2;
        
        // 等分次数
        var divideNum = 6;
        // 等分弧度
        var divideAngle = 2 * Math.PI / divideNum;

        // 定时启动
        setInterval(function() {
            ctx.clearRect(0, 0, 600, 400);
            for (var i = 0; i < divideNum; i++) {
                var startAngle = i * divideAngle;
                var endAngle = startAngle + divideAngle;
                ctx.beginPath();
                ctx.moveTo(x0, y0);
                ctx.arc(x0, y0, 150, startAngle, endAngle);
                ctx.fillStyle = getRandomColor();
                ctx.fill();
            }
        }, 100);

        // 获取随机颜色
        function getRandomColor() {
            var c1 = Math.floor(Math.random() * 256);
            var c2 = Math.floor(Math.random() * 256);
            var c3 = Math.floor(Math.random() * 256);
            return 'rgb(' +c1+ ',' +c2+ ',' +c3+ ')';
        }
    </script>
</body>
</html>

绘制饼状图

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        canvas {
            border: 1px solid #ccc;
            display: block;
            margin: 100px auto;
        }
    </style>
</head>
<body>
<canvas width="600" height="400"></canvas>
<script>
    /*var myCanvas = document.querySelector('canvas');
    var ctx = myCanvas.getContext('2d');*/

    /*1.绘制饼状态图*/
    /*1.1 根据数据绘制一个饼图*/
    /*1.2 绘制标题 从扇形的弧中心伸出一条线在画一条横线在横线的上面写上文字标题*/
    /*1.3 在画布的左上角 绘制说明 一个和扇形一样颜色的矩形 旁边就是文字说明*/

    var PieChart = function (ctx) {
        /*绘制工具*/
        this.ctx = ctx || document.querySelector('canvas').getContext('2d');
        /*绘制饼图的中心*/
        this.w = this.ctx.canvas.width;
        this.h = this.ctx.canvas.height;
        /*圆心*/
        this.x0 = this.w / 2 + 60;
        this.y0 = this.h / 2;
        /*半径*/
        this.radius = 150;
        /*伸出去的线的长度*/
        this.outLine = 20;
        /*说明的矩形大小*/
        this.rectW = 30;
        this.rectH = 16;
        this.space = 20;
    }
    PieChart.prototype.init = function (data) {
        /*1.准备数据*/
        this.drawPie(data);
    };
    PieChart.prototype.drawPie = function (data) {
        var that = this;
        /*1.转化弧度*/
        var angleList = this.transformAngle(data);
        /*2.绘制饼图*/
        var startAngle = 0;
        angleList.forEach(function (item, i) {
            /*当前的结束弧度要等于下一次的起始弧度*/
            var endAngle = startAngle + item.angle;
            that.ctx.beginPath();
            that.ctx.moveTo(that.x0, that.y0);
            that.ctx.arc(that.x0, that.y0, that.radius, startAngle, endAngle);
            var color = that.ctx.fillStyle = that.getRandomColor();
            that.ctx.fill();
            /*下一次要使用当前的这一次的结束角度*/
            /*绘制标题*/
            that.drawTitle(startAngle, item.angle, color , item.title);
            /*绘制说明*/
            that.drawDesc(i,item.title);
            startAngle = endAngle;
        });
    };
    PieChart.prototype.drawTitle = function (startAngle, angle ,color , title) {
        /*1.确定伸出去的线 通过圆心点 通过伸出去的点  确定这个线*/
        /*2.确定伸出去的点 需要确定伸出去的线的长度*/
        /*3.固定伸出去的线的长度*/
        /*4.计算这个点的坐标*/
        /*5.需要根据角度和斜边的长度*/
        /*5.1 使用弧度  当前扇形的起始弧度 + 对应的弧度的一半 */
        /*5.2 半径+伸出去的长度 */
        /*5.3 outX = x0 + cos(angle) * ( r + outLine)*/
        /*5.3 outY = y0 + sin(angle) * ( r + outLine)*/
        /*斜边*/
        var edge = this.radius + this.outLine;
        /*x轴方向的直角边*/
        var edgeX = Math.cos(startAngle + angle / 2) * edge;
        /*y轴方向的直角边*/
        var edgeY = Math.sin(startAngle + angle / 2) * edge;
        /*计算出去的点坐标*/
        var outX = this.x0 + edgeX;
        var outY = this.y0 + edgeY;
        this.ctx.beginPath();
        this.ctx.moveTo(this.x0, this.y0);
        this.ctx.lineTo(outX, outY);
        this.ctx.strokeStyle = color;
        /*画文字和下划线*/
        /*线的方向怎么判断 伸出去的点在X0的左边 线的方向就是左边*/
        /*线的方向怎么判断 伸出去的点在X0的右边 线的方向就是右边*/
        /*结束的点坐标  和文字大小*/
        this.ctx.font = '14px Microsoft YaHei';
        var textWidth = this.ctx.measureText(title).width ;
        if(outX > this.x0){
            /*右*/
            this.ctx.lineTo(outX + textWidth,outY);
            this.ctx.textAlign = 'left';
        }else{
            /*左*/
            this.ctx.lineTo(outX - textWidth,outY);
            this.ctx.textAlign = 'right';
        }
        this.ctx.stroke();
        this.ctx.textBaseline = 'bottom';
        this.ctx.fillText(title,outX,outY);

    };
    PieChart.prototype.drawDesc = function (index,title) {
        /*绘制说明*/
        /*矩形的大小*/
        /*距离上和左边的间距*/
        /*矩形之间的间距*/
        this.ctx.fillRect(this.space,this.space + index * (this.rectH + 10),this.rectW,this.rectH);
        /*绘制文字*/
        this.ctx.beginPath();
        this.ctx.textAlign = 'left';
        this.ctx.textBaseline = 'top';
        this.ctx.font = '12px Microsoft YaHei';
        this.ctx.fillText(title,this.space + this.rectW + 10 , this.space + index * (this.rectH + 10));
    };
    PieChart.prototype.transformAngle = function (data) {
        /*返回的数据内容包含弧度的*/
        var total = 0;
        data.forEach(function (item, i) {
            total += item.num;
        });
        /*计算弧度 并且追加到当前的对象内容*/
        data.forEach(function (item, i) {
            var angle = item.num / total * Math.PI * 2;
            item.angle = angle;
        });
        return data;
    };
    PieChart.prototype.getRandomColor = function () {
        var r = Math.floor(Math.random() * 256);
        var g = Math.floor(Math.random() * 256);
        var b = Math.floor(Math.random() * 256);
        return 'rgb(' + r + ',' + g + ',' + b + ')';
    };

    var data = [
        {
            title: '15-20岁',
            num: 6
        },
        {
            title: '20-25岁',
            num: 30
        },
        {
            title: '25-30岁',
            num: 10
        },
        {
            title: '30以上',
            num: 8
        }
    ];

    var pieChart = new PieChart();
    pieChart.init(data);

</script>
</body>
</html>

绘制图片

  • drawImage()
    • 三个参数drawImage(img,x,y)
      • img 图片对象、canvas对象、video对象
      • x,y 图片绘制的左上角
    • 五个参数drawImage(img,x,y,w,h)
      • img 图片对象、canvas对象、video对象
      • x,y 图片绘制的左上角
      • w,h 图片绘制尺寸设置(图片缩放,不是截取)
    • 九个参数drawImage(img,x,y,w,h,x1,y1,w1,h1)
      • img 图片对象、canvas对象、video对象
      • x,y,w,h 图片中的一个矩形区域
      • x1,y1,w1,h1 画布中的一个矩形区域

绘制图片

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>quxian</title>

    <style>
        canvas {
            border: 1px solid #ccc;
        }
    </style>
</head>
<body>
    <canvas width="600" height="400"></canvas>

    <script>
        // 获取canvas上下文
        var canvas = document.querySelector('canvas');
        var ctx = canvas.getContext('2d');

        // 获取canvas画布宽高
        var canvasWidth = ctx.canvas.width;
        var canvasHeight = ctx.canvas.height;

        /*1.加载图片到内存即可*/
        /*var img = document.createElement('img');
        img.src = 'image/01.jpg';*/

        /*2.创建图片对象*/
        var image = new Image();
        /*绑定加载完成事件*/
        image.onload = function () {
            /*3参数*/
            /*图片对象*/
            /*绘制在画布上的坐标 x y*/
            //ctx.drawImage(image,100,100);


            /*5个参数*/
            /*图片对象*/
            /*绘制在画布上的坐标 x y*/
            /*是图片的大小  不是裁剪  是缩放*/
            //ctx.drawImage(image,100,100,100,100);


            /*9个参数*/
            /*图片对象*/
            /*图片上定位的坐标  x y */
            /*在图片上截取多大的区域  w h*/
            /*绘制在画布上的坐标 x y*/
            /*是图片的大小  不是裁剪  是缩放*/
            ctx.drawImage(image,0,0,200,200,100,100,200,200);
        }
        /*设置图片路径*/
        image.src = './images/001.jpg';
    </script>
</body>
</html>

坐标变换

  • 平移 移动画布的原点
    • translate(x,y) 参数表示移动目标点的坐标
  • 缩放
    • scale(x,y) 参数表示宽高的缩放比例
  • 旋转
    • rotate(angle) 参数表示旋转角度
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,427评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,551评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,747评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,939评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,955评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,737评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,448评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,352评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,834评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,992评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,133评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,815评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,477评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,022评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,147评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,398评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,077评论 2 355

推荐阅读更多精彩内容

  • 一、canvas简介 1.1 什么是canvas?(了解) 是HTML5提供的一种新标签 Canvas是一个矩形区...
    J_L_L阅读 1,517评论 0 4
  • 什么是canvas? HTML5的canvas元素使用javascript在网页上绘制图像。 画布是一个矩形区域,...
    Tu_Feng阅读 1,381评论 0 1
  • Canvas canvas 最早由Apple引入WebKit,用于Mac OS X 的 Dashboard,后来又...
    zhangjingbibibi阅读 1,410评论 0 0
  • 神奇且强大的canvas 一.Canvas的基本介绍 1.什么是Canvas 定义:是HTML5提供的一种新标签,...
    Ainy尘世繁花终凋落阅读 10,784评论 1 18
  • 一、初识canvas canvas画布默认宽高是 300 * 150 px canvas宽高要使用canvas标签...
    福尔摩鸡阅读 441评论 0 0