浅析HTML5的Canvas——案例绘制

1. Canvas绘制五环

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

    //2.绘制奥运五环
    //第一个五环
    //遍历
    //颜色数组
    var colorArr = ['red','green','yellow','blue','black'];
    for(var i = 0;i<5;i++){
        ctx.beginPath();
        ctx.arc(100 *(i+1),150,80,0,2 * Math.PI);
        ctx.strokeStyle = colorArr[i];
        ctx.lineWidth = 5;
        ctx.stroke();
    };
    //绘制第二个五环
    var colorArr = ['red','green','yellow','blue','black'];
    for(var i = 0;i<5;i++){//0,1,2
        ctx.beginPath();
        if(i<3){
            ctx.arc(100 *(i+1),350,80,0,2 * Math.PI);
        }else{//3,4
            ctx.arc(100 *(i-2) + 40,350 + 80,80,0,2 * Math.PI);
        }
        ctx.strokeStyle = colorArr[i];
        ctx.lineWidth = 5;
        ctx.stroke();
    };
</script>
canvas绘制五环渲染效果

2.Canvas绘制饼状图以及绘制文字

<script>
    var canvas = document.getElementById('canvas');
    var ctx = canvas.getContext('2d');

    //2.绘制饼状图
    //常量
    var canW = canvas.width * 0.5;//圆心
    var canH = canvas.height * 0.5;//圆心
    var radius = 150;
    //数据
    var dataArr = [
        {name:'北京',color:'yellow',value:'0.3'},
        {name:'上海',color:'red',value:'0.2'},
        {name:'广州',color:'green',value:'0.1'},
        {name:'深圳',color:'blue',value:'0.15'},
        {name:'杭州',color:'purple',value:'0.25'}
    ];
    //3.遍历并绘制扇形
    var beginAngle = -90 * Math.PI/180;
    for(var i= 0;i<dataArr.length;i++){
        //3.1获取每一个扇形的角度
        var temAngle = dataArr[i].value *360 *Math.PI/180;
        //3.2获取终点
        var endAngle = beginAngle + temAngle;
        //开启新路径
        ctx.beginPath();
        ctx.moveTo(canW,canH);
        ctx.arc(canW,canH,radius,beginAngle,endAngle);
        ctx.fillStyle = dataArr[i].color;
        ctx.fill();

        //3.3绘制文字
        //获取每一个文字的角度
        var textAngle = beginAngle + temAngle * 0.5;
        //文字坐标
        var textX = canW + (radius+30)* Math.cos(textAngle);
        var textY = canH + (radius+30)* Math.sin(textAngle);
        //获取文字内容
        var text = dataArr[i].name + dataArr[i].value *100 + '%';
        //设置文字字号
        ctx.font = "20px '微弱雅黑'";
        ctx.strokeStyle = dataArr[i].color;
        //设置左边文字的对齐方式
        if(textAngle>90 * Math.PI/180 && textAngle<270 *Math.PI/180){
            ctx.textAlign = 'end';
        }
        ctx.strokeText(text,textX,textY);
        //更新起点,让当前的终点角度成为下一个图形的起点的角度
        beginAngle = endAngle;
    }
</script>
Canvas绘制饼状图以及文字渲染效果

3. Canvas绘制一堆不断变大变小的随机移动的气泡

  • html文件
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>气泡变化</title>
</head>
<body>
<canvas id="canvas" width="1200px" height="800px">
</canvas>
</body>
<script src="main.js">

</script>
</html>
  • js文件
<script >
    //获取context
    var canvas=document.querySelector('canvas'),
    context=canvas.getContext('2d');
    // 这个数组用于保存画布上出现的所有球
    var balls = [];
    // 用于表示球的所有细节的Ball函数
    // x、y分别是气泡初始化的位置
    //radius是气泡的半径-随机
    //strokeColor 绘制颜色 -随机
    //填充颜色-随机
    //flag半径变大还是变小
    //flagx x增大还是减小
    //flagy y增加还是减少
    // 构建一个气泡对象
    function Ball(x, y) {
        this.x = x;
        this.y = y;
        this.radius = Math.round(Math.random()*10)*10;
        this.strokeColor = 'rgba('+Math.round(Math.random()*10)*25+','+Math.round(Math.random()*10)*25+','+Math.round(Math.random()*10)*25+',0)';
        this.fillColor = 'rgba('+Math.round(Math.random()*10)*25+','+Math.round(Math.random()*10)*25+','+Math.round(Math.random()*10)*25+','+Math.round(Math.random()*10)/10+')';
        this.flag=1;
        this.flagx=1;
        this.flagy=1;
    }
    // 向数组添加小球
    function addBall() {
        // 小球半径
        var radius = Math.round(Math.random()*10)*10;
        var x=0,y=0;

        if (x<200||x>1000){
            x=Math.round(Math.random()*10)*100;
        }
        if (y<200||x>600){
            y=Math.round(Math.random()*10)*60;
        }
        // 创建新的ball对象
        var ball = new Ball(x,y);
        // 将其保存在balls数组中
        balls.push(ball);
    }
    //绘制图像并且在20ms后再次绘制
      function drawFrame() {
        // 清除画布
        context.clearRect(0, 0, canvas.width, canvas.height);
        context.beginPath();
        // 循环所有的球,并重新定义他们的位置和大小

        for(var i=0; i<balls.length; i++) {
            if (balls[i].flagx==1){
                balls[i].x++;
                if (balls[i].x>=800){
                    balls[i].flagx=0;
                }
            }else if(balls[i].flagx==0){
                balls[i].x--;
                if (balls[i].x<=0){
                    balls[i].flagx=1;
                }
            }
            if (balls[i].flagy==1){
                balls[i].y++;
                if (balls[i].y>=600){
                    balls[i].flagy=0;
                }
            }else if(balls[i].flagy==0){
                balls[i].y--;
                if (balls[i].y<=0){
                    balls[i].flagy=1;
                }
            }
            if (balls[i].flag==1){
                balls[i].radius++;

                balls[i].y++;
                if (balls[i].radius>=100){
                    balls[i].flag=0;
                }
            }else if (balls[i].flag==0){
                balls[i].radius--;
                balls[i].x--;
                balls[i].y--;
                if (balls[i].radius<=0){
                    balls[i].flag=1;
                }
            }
            var ball = balls[i];
            context.beginPath();
            context.fillStyle = balls[i].fillColor;
            context.strokeStyle=balls[i].strokeColor;
            // 绘制球
            context.arc(balls[i].x, balls[i].y, balls[i].radius, 0, Math.PI*2);
            context.lineWidth = 0;
            context.fill();
            context.stroke();
        }
        // 20毫秒后绘制下一帧
        setTimeout(drawFrame, 20);
    }
    //调用并且初始化小球
      for(var i=0;i<50;i++){
          addBall();
      }
      drawFrame();
</script>
效果渲染示例

4.Canvas绘制简单的时钟

  • html文件
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Clock</title>
    <style>
        body {
            background: #dddddd;
        }

        #canvas {
            position: absolute;
            left: 0px;
            top: 0px;
            margin: 20px;
            background: #ffffff;
            border: thin solid #aaaaaa;
        }
    </style>
</head>
<body>
    <canvas id='canvas' width='400' height='400'>
      Canvas not supported
    </canvas>

    <script src='example.js'></script>
</body>
</html>
  • js文件
const canvas = document.getElementById('canvas'),
    context = canvas.getContext('2d'),
    FONT_HEIGHT = 15,
    MARGIN = 35,
    HAND_TRUNCATION = canvas.width / 25,
    HOUR_HAND_TRUNCATION = canvas.width / 10,
    NUMERAL_SPACING = 20,
    RADIUS = canvas.width / 2 - MARGIN,
    HAND_RADIUS = RADIUS + NUMERAL_SPACING;
// Functions.....................................................
function drawCircle() {
    context.beginPath();
    context.arc(canvas.width / 2, canvas.height / 2,
        RADIUS, 0, Math.PI * 2, true);
    context.stroke();
}
function drawNumerals() {
    let numerals = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
        angle = 0,
        numeralWidth = 0;
    numerals.forEach(function(numeral) {
        angle = Math.PI / 6 * (numeral - 3);
        numeralWidth = context.measureText(numeral).width;
        context.fillText(numeral,
            canvas.width / 2 + Math.cos(angle) * (HAND_RADIUS) -
            numeralWidth / 2,
            canvas.height / 2 + Math.sin(angle) * (HAND_RADIUS) +
            FONT_HEIGHT / 3);
    });
}
function drawCenter() {
    context.beginPath();
    context.arc(canvas.width / 2, canvas.height / 2, 5, 0, Math.PI * 2, true);
    context.fill();
}
function drawHand(loc, isHour) {
    let angle = (Math.PI * 2) * (loc / 60) - Math.PI / 2,
        handRadius = isHour ? 
                     RADIUS - HAND_TRUNCATION - HOUR_HAND_TRUNCATION :
                     RADIUS - HAND_TRUNCATION;
    context.moveTo(canvas.width / 2, canvas.height / 2);
    context.lineTo(canvas.width / 2 + Math.cos(angle) * handRadius,
        canvas.height / 2 + Math.sin(angle) * handRadius);
    context.stroke();
}
function drawHands() {
    let date = new Date,
        hour = date.getHours();
    hour = hour > 12 ? hour - 12 : hour;
    drawHand(hour * 5 + (date.getMinutes() / 60) * 5, true, 0.5);
    drawHand(date.getMinutes(), false, 0.5);
    drawHand(date.getSeconds(), false, 0.2);
}
function drawClock() {
    context.clearRect(0, 0, canvas.width, canvas.height);
    drawCircle();
    drawCenter();
    drawHands();
    drawNumerals();
}
// Initialization................................................
context.font = FONT_HEIGHT + 'px Arial';
loop = setInterval(drawClock, 1000);
canvas时钟渲染图

Canvas的基本介绍先介绍到这里;如果对您有所帮助的话,请点赞并关注哦,我会不定时的更新一下自己学习的经验以及见解,和大家进行交流。

您赞就是是我最大的动力!!!

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

推荐阅读更多精彩内容