Html5 Canvas绘图实例

简介: Html5 Canvas绘图实例

前些年的时候,突然对Canvas感兴趣,利用空闲时间做一些Canvas小例子进行练习,仅供学习分享使用。如有不足之处,还请指正。

什么是 Canvas?

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

创建 Canvas 元素及JavaScript对象

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

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

JavaScript 使用 id 来寻找 canvas 元素:

var c=document.getElementById("myCanvas");

然后,创建 context 对象:

var cxt=c.getContext("2d");

注意:getContext("2d") 对象是内建的 HTML5 对象,拥有多种绘制路径、矩形、圆形、字符以及添加图像的方法。

实例一、灯笼绘制

以下是一个灯笼,并作了简要的说明。

具体绘制思路在页面上有说明,不再赘述,代码如下:

<script type="text/javascript">
        //绘制椭圆
        function ParamEllipse(context, x, y, a, b) {
            //max是等于1除以长轴值a和b中的较大者
            //i每次循环增加1/max,表示度数的增加
            //这样可以使得每次循环所绘制的路径(弧线)接近1像素
            var step = (a > b) ? 1 / a : 1 / b;
            context.fillStyle = "#ff0000";
            context.beginPath();
            context.moveTo(x + a, y); //从椭圆的左端点开始绘制
            for (var i = 0; i < 2 * Math.PI; i += step) {
                //参数方程为x = a * cos(i), y = b * sin(i),
                //参数为i,表示度数(弧度)
                context.lineTo(x + a * Math.cos(i), y + b * Math.sin(i));
            }
            context.closePath();
            context.stroke();
            context.fill();
            context.closePath();
        };
        //绘制矩形
        function FillRect(context, x, y, w, h, flag) {
            var grd = context.createLinearGradient(x+w/2, y, x + w/2, y + h);
            if (flag) {
                grd.addColorStop(0, "yellow");
                grd.addColorStop(1, "red");
            } else {
                grd.addColorStop(0, "red");
                grd.addColorStop(1, "yellow");
            }
            context.fillStyle = grd;
            context.fillRect(x, y, w, h);
        }
        //绘制线条
        function SetLine(ctx, x, y, x1, y1) {
            ctx.beginPath();
            ctx.strokeStyle = "yellow";
            ctx.moveTo(x,y);
            ctx.lineTo(x1,y1);
            ctx.stroke();
            ctx.closePath();
        }
        window.onload = function () {
            var c = document.getElementById("myCanvas");
            var ctx = c.getContext("2d");
            var startX = 150; //中心坐标x
            var startY = 300; //中心坐标y
            var pWidth = 120; //椭圆长轴
            var pHeigth = 80; //椭圆形短轴
            var fWidth = 120; //矩形宽
            var fheight = 40; //矩形高
            //绘制椭圆
            ParamEllipse(ctx, startX, startY, pWidth, pHeigth);
            //在椭圆上方和下方绘制长方形,且有一半的高度和椭圆重叠
            FillRect(ctx, startX - fWidth / 2, startY - pHeigth - (fheight / 2), fWidth, fheight, true);
            FillRect(ctx, startX - fWidth / 2, startY + pHeigth - (fheight / 2), fWidth, fheight, false);
            //在矩形下方绘制线条,8个单位一条线,长度为40,均匀分布在矩形下方
            var lLen = fheight; //画线的范围始终在矩形之下
            var lInterval = 8; //线与线之间的间隔
            for (var i = 0; i < (fWidth / 8) + 1; i++) {
                SetLine(ctx, startX - fWidth / 2 + i * lInterval, startY + pHeigth + fheight / 2, startX - fWidth / 2 + i * lInterval, startY + pHeigth + fheight / 2 + lLen);
            }
            //对三部分进行拆解
            //1. 上矩形
            var right = 380;
            FillRect(ctx, startX - fWidth / 2 + right, startY - pHeigth - (fheight / 2) - 150, fWidth, fheight, true);
            //2. 中椭圆
            ParamEllipse(ctx, startX + right, startY - 50, pWidth, pHeigth);
            //3. 下矩形
            FillRect(ctx, startX - fWidth / 2 + right, startY + pHeigth - (fheight / 2) + 50, fWidth, fheight, false);
            //4. 下线
            for (var i = 0; i < (fWidth / 8) + 1; i++) {
                SetLine(ctx, startX - fWidth / 2 + i * lInterval + right, startY + pHeigth + fheight / 2 + 100, startX - fWidth / 2 + i * lInterval + right, startY + pHeigth + fheight / 2 + lLen + 100);
            }
            //画线,将其连接起来
            var lsX = startX + pWidth + 20;
            var lsY = startY;
            var leX = startX + pWidth + 20 + 100;
            var leY = startY;
            SetLine(ctx, lsX, startY - 30, leX - 30, leY - 150);
            SetLine(ctx, lsX, startY - 15, leX, leY - 50);
            SetLine(ctx, lsX, startY + 15, leX, leY + 100);
            SetLine(ctx, lsX, startY + 30, leX - 30, leY + 150);
            //左上标写上说明
            ctx.font = "35px Arial";
            var t = "灯笼组成--2016-11-13";
            ctx.fillText(t, 50, 50);
        }
    </script>

实例二、绘制时钟

绘制一个走动的时钟,具体如下图所示:

具体思路在上图已有说明,代码如下:

<script type="text/javascript">
        //绘制圆形的弧度,ctx 为绘制环境,x,y为绘制中心,r为绘制半径,st为起始弧度,end为结束弧度
        function circle(ctx, x, y, r, st, end, w) {
            ctx.lineWidth = w;
            ctx.beginPath();
            ctx.moveTo(x, y);
            ctx.arc(x, y, r, st, end, true);
            ctx.stroke();
        }
        //画一个白色的圆,用以覆盖
        function circle0(ctx, x, y, r, st, end) {
            ctx.fillStyle = "#ffffff";
            ctx.beginPath();
            ctx.arc(x, y, r, st, end, true);
            ctx.fill();
        }
        function circle1(ctx, x, y, r, st, end, w) {
            ctx.strokeStyle = "gray";
            ctx.lineWidth = w;
            ctx.beginPath();
            ctx.arc(x, y, r, st, end, true);
            ctx.stroke();
        }
        //绘制时钟用的线
        function line(ctx, x1, y1, x2, y2, w) {
            if (w == 1) {
                ctx.strokeStyle = "red";
            } else if (w == 2) {
                ctx.strokeStyle = "blue";
            } else {
                ctx.strokeStyle = "black";
            }
            ctx.lineWidth = w;
            ctx.beginPath();
            ctx.moveTo(x1, y1);
            ctx.lineTo(x2, y2);
            ctx.stroke();
        }
        function drawClock() {
            var c = document.getElementById("myCanvas");
            var ctx = c.getContext("2d");
            ctx.clearRect(0, 0, c.width, c.height);
            //绘制一个钟表
            var cX = 300;
            var cY = 200;
            var radius = 100;
            //绘制分与秒的刻度
            for (var i = 0; i < 60; i++) {
                circle(ctx, cX, cY, radius, i * 6 * Math.PI / 180, (i + 1) * 6 * Math.PI / 180, 1);
            }
            circle0(ctx, cX, cY, radius * 9 / 10, 0, 2 * Math.PI, true);
            //绘制时刻度
            for (var i = 0; i < 12; i++) {
                circle(ctx, cX, cY, radius, i * 30 * Math.PI / 180, (i + 1) * 30 * Math.PI / 180, 2);
            }
            circle0(ctx, cX, cY, radius * 8 / 10, 0, 2 * Math.PI, true);
            //外围再画一圈
            circle1(ctx, cX, cY, radius * 11 / 10, 0, 2 * Math.PI, 1);
            ctx.save();
            ctx.fillStyle = "black";
            ctx.font = "10px Arial";
            //在钟表的周围画上数字
            for (var i = 0; i < 12; i++) {
                var fX = cX + Math.cos((i + 1) * 5 * 6 * Math.PI / 180 - Math.PI / 2) * radius * 7.5 / 10;
                var fY = cY + Math.sin((i + 1) * 5 * 6 * Math.PI / 180 - Math.PI / 2) * radius * 7.5 / 10;
                ctx.fillText((i + 1), fX, fY);
            }
            var date = new Date();
            var second = date.getSeconds();
            var minute = date.getMinutes();
            var hour = date.getHours();
            hour = hour % 12; //采用12小时制
            var secondX = cX + Math.cos(second * 6 * Math.PI / 180 - Math.PI / 2) * radius * 9 / 10;
            var secondY = cY + Math.sin(second * 6 * Math.PI / 180 - Math.PI / 2) * radius * 9 / 10;
            var minuteX = cX + Math.cos(minute * 6 * Math.PI / 180 - Math.PI / 2) * radius * 8 / 10;
            var minuteY = cY + Math.sin(minute * 6 * Math.PI / 180 - Math.PI / 2) * radius * 8 / 10;
            //小时为了准确起见,应该要加上分的弧度
            var hourX = cX + Math.cos(hour * 30 * Math.PI / 180 + (minute * 6 * Math.PI / 180) / 12 - Math.PI / 2) * radius * 6.5 / 10;
            var hourY = cY + Math.sin(hour * 30 * Math.PI / 180 + (minute * 6 * Math.PI / 180) / 12 - Math.PI / 2) * radius * 6.5 / 10;
            //画秒针,红色
            line(ctx, cX, cY, secondX, secondY, 1);
            //画分针,蓝色
            line(ctx, cX, cY, minuteX, minuteY, 2);
            //画时针,黑色
            line(ctx, cX, cY, hourX, hourY, 3);
            ctx.fillStyle = "black";
            ctx.font = "15px Arial";
            ctx.fillText("CurrentTime is : " + date.toLocaleString(), 150, 450);
            ctx.save();
        }
        window.onload = function () {
            //循环,1s一次,且要在加载完才可以开始,否则会出现找不到对象的异常
            setInterval(drawClock, 1000);
        }
    </script>

实例三、绘制太极图

采用Html5+JavaScript在Canvas中绘制旋转的太极图,如下图所示:

具体思路和绘制逻辑,在上图中已有说明,代码如下:

<script type="text/javascript">
       //只画边框线,无填充
        function bigCircle(ctx,x, y, r, st, end, w,oc) {
            ctx.lineWidth = w;
            ctx.beginPath();
            ctx.arc(x, y, r, st, end, oc);
            ctx.closePath();
            ctx.stroke();
        }
        //有填充,画小圆,x,y表示大圆的圆心,r表示大圆的半径,w表示线宽,oc表示方向,l表示上下,d表示度数
        function smallCircle(ctx, x, y, r, st, end, w, oc, l,d) {
            var Angle = d * Math.PI / 180; //偏移角用弧度表示
            ctx.lineWidth = w;
            ctx.beginPath();
            if (l) {
                ctx.fillStyle = "black";
                ctx.arc(x + (r / 2) * Math.sin(Angle), y - (r / 2) * Math.cos(Angle), r/10, st, end, oc);
            } else {
                ctx.fillStyle = "red";
                ctx.arc(x - (r / 2) * Math.sin(Angle), y + (r / 2) * Math.cos(Angle), r/10, st, end, oc);
            }
            ctx.closePath();
            ctx.stroke();
            ctx.fill();
        }
        //此函数是画带S形曲线的圆,l表示左右,true表示左,顺时针,false表示右,逆时针
        //d表示度数
        function halfCircle(ctx, x, y, r, w, l,d) {
            ctx.lineWidth = w;
            if (l) {
                ctx.fillStyle = "black";
            } else {
                ctx.fillStyle = "red";
            }
            ctx.beginPath();
            var Angle = d * Math.PI / 180;//偏移角用弧度表示
            ctx.arc(x + (r / 2) * Math.sin(Angle), y - (r / 2) * Math.cos(Angle), r / 2, Math.PI / 2 + Angle, Math.PI * 3 / 2 + Angle, true);
            ctx.arc(x - (r / 2) * Math.sin(Angle), y + (r / 2) * Math.cos(Angle), r / 2, Math.PI*3 / 2 + Angle, Math.PI / 2 + Angle, true);
            ctx.arc(x, y, r, Math.PI / 2 + Angle, Math.PI * 3 / 2 + Angle, l); //顺时针,逆时针通过参数判断
            ctx.closePath();
            ctx.stroke();
            ctx.fill();
        }
        var num = 0;//表示旋转的度数
        function drawTaichi() {
            var c = document.getElementById("myCanvas");
            var ctx = c.getContext("2d");
            var cX = 200;
            var cY = 200;
            var radius = 150;
            ctx.clearRect(0,0,c.width,c.height);
            //绘制s线 左
            halfCircle(ctx, cX, cY, radius, 1, true, num);
            //右
            halfCircle(ctx, cX, cY, radius, 1, false, num);
            //绘制小圆,上
            smallCircle(ctx, cX, cY, radius, 0, Math.PI * 2, 1, true, true, num);
            //绘制小圆,下
            smallCircle(ctx, cX, cY, radius, 0, Math.PI * 2, 1, true, false, num);
            //绘制外圆
            bigCircle(ctx, cX, cY, radius, 0, Math.PI * 2, 2, true);
            ctx.save();
            num++;
            num = num % 360;//只有360°,所以大于360,就重新开始
        }
        window.onload = function () {
            setInterval(drawTaichi, 200);
        }
    </script>

实例四、绘制五星红旗

Html5+JavaScript 在Canvas上绘制五星红旗,具体思路如下图所示:

绘制思路在上图中已有说明,具体代码如下:

<script type="text/javascript">
        //绘制五角星,其中一点垂直向上,相隔的点相连,即可绘制。
        function drawStar(ctx,starCenterX,starCenterY,starRadius) {
            var aX = starCenterX;
            var aY = starCenterY - starRadius;
            var bX = starCenterX - Math.cos(18 * Math.PI / 180) * starRadius;
            var bY = starCenterY - Math.sin(18 * Math.PI / 180) * starRadius;
            var cX = starCenterX - Math.cos(54 * Math.PI / 180) * starRadius;
            var cY = starCenterY + Math.sin(54 * Math.PI / 180) * starRadius;
            var dX = starCenterX + Math.cos(54 * Math.PI / 180) * starRadius;
            var dY = starCenterY + Math.sin(54 * Math.PI / 180) * starRadius;
            var eX = starCenterX + Math.cos(18 * Math.PI / 180) * starRadius;
            var eY = starCenterY - Math.sin(18 * Math.PI / 180) * starRadius;
            ctx.beginPath();
            ctx.fillStyle = "yellow";
            ctx.moveTo(aX, aY);
            ctx.lineTo(cX, cY);
            ctx.lineTo(eX, eY);
            ctx.lineTo(bX, bY);
            ctx.lineTo(dX, dY);
            ctx.lineTo(aX, aY);
            ctx.fill();
            ctx.closePath();
        }
        window.onload = function () {
            var c = document.getElementById("myCanvas");
            var ctx = c.getContext("2d");
            ctx.clearRect(0, 0, c.width, c.height);
            var width = 300*1.5;
            var height = 200*1.5;
            var sX = 50; //其实坐标
            var sY = 50; //其实坐标
            var step = 10*1.5;
            //绘制矩形
            ctx.beginPath();
            ctx.lineWidth = 1;
            ctx.fillStyle = "red";
            ctx.fillRect(sX, sY, width, height);
            ctx.closePath();
            //绘制大五角星
            var bigStarCenterX = sX + 5 * step;
            var bigStarCenterY = sY + 5 * step;
            var bigStarRadius = (height * 3 / 10) / 2; //外接圆直径为旗高3/10,半径要再除以2
            drawStar(ctx, bigStarCenterX, bigStarCenterY, bigStarRadius);
            //绘制小五角星
            var smallStarRadius = (height * 1 / 10) / 2; //外接圆直径为旗高1/10,半径要再除以2
            var smallStarCenterX_1 = sX + 10 * step;
            var smallStarCenterY_1 = sY + 2 * step;
            drawStar(ctx, smallStarCenterX_1, smallStarCenterY_1, smallStarRadius);
            var smallStarCenterX_2 = sX + 12 * step;
            var smallStarCenterY_2 = sY + 4 * step;
            drawStar(ctx, smallStarCenterX_2, smallStarCenterY_2, smallStarRadius);
            var smallStarCenterX_3 = sX + 12 * step;
            var smallStarCenterY_3 = sY + 7 * step;
            drawStar(ctx, smallStarCenterX_3, smallStarCenterY_3, smallStarRadius);
            var smallStarCenterX_4 = sX + 10 * step;
            var smallStarCenterY_4 = sY + 9 * step;
            drawStar(ctx, smallStarCenterX_4, smallStarCenterY_4, smallStarRadius);
        };
    </script>

备注

赤壁【作者】杜牧【朝代】唐

折戟沉沙铁未销,自将磨洗认前朝。东风不与周郎便,铜雀春深锁二乔。

相关文章
|
2月前
|
前端开发 JavaScript API
2024 新年HTML5+Canvas制作3D烟花特效(附源码)
2024 新年HTML5+Canvas制作3D烟花特效(附源码)
54 0
|
6月前
|
移动开发 前端开发 JavaScript
【HTML】HTML基础知识详解【2万字+代码实例+显示效果】(下)
【HTML】HTML基础知识详解【2万字+代码实例+显示效果】(下)
【HTML】HTML基础知识详解【2万字+代码实例+显示效果】(下)
|
7月前
|
移动开发 前端开发 Shell
《HTML5 Canvas核心技术 图形、动画与游戏开发》 读书笔记
《HTML5 Canvas核心技术 图形、动画与游戏开发》 读书笔记
|
2月前
|
存储 移动开发 前端开发
HTML新特性【HTML5内联SVG、SVG_矩形、SVG 与 Canvas两者间的区别 、HTML5_MathML 】(三)-全面详解(学习总结---从入门到深化)
HTML新特性【HTML5内联SVG、SVG_矩形、SVG 与 Canvas两者间的区别 、HTML5_MathML 】(三)-全面详解(学习总结---从入门到深化)
48 0
|
1月前
|
前端开发 JavaScript 容器
编程笔记 html5&css&js 032 HTML Canvas
编程笔记 html5&css&js 032 HTML Canvas
|
3月前
|
移动开发 前端开发 JavaScript
html5 Canvas 绘制基本图形 从直线图形到使用路径 - 直线、矩形、路径、多边形、复杂组合图形
html5 Canvas 绘制基本图形 从直线图形到使用路径 - 直线、矩形、路径、多边形、复杂组合图形
127 0
html5 Canvas 绘制基本图形 从直线图形到使用路径 - 直线、矩形、路径、多边形、复杂组合图形
|
3月前
|
存储 移动开发 前端开发
HTML新特性【HTML5内联SVG、SVG_矩形、SVG 与 Canvas两者间的区别 、HTML5_MathML 】(三)-全面详解(学习总结---从入门到深化)(下)
HTML新特性【HTML5内联SVG、SVG_矩形、SVG 与 Canvas两者间的区别 、HTML5_MathML 】(三)-全面详解(学习总结---从入门到深化)
29 0
|
3月前
|
XML 移动开发 前端开发
HTML新特性【HTML5内联SVG、SVG_矩形、SVG 与 Canvas两者间的区别 、HTML5_MathML 】(三)-全面详解(学习总结---从入门到深化)(上)
HTML新特性【HTML5内联SVG、SVG_矩形、SVG 与 Canvas两者间的区别 、HTML5_MathML 】(三)-全面详解(学习总结---从入门到深化)
29 0
|
4月前
html中img图片进行等比例缩放的实例代码
HTML中,要修改img元素定义的图片的大小,且是等比例缩放,不改变宽和高的比值,那么可以采用只设置img元素属性中width和height中的任何一个,不要同时设置两个即可实现img图片的等比例缩放效果。下面将通过两个实例来分别实现这两种方法。
85 1
|
4月前
|
移动开发 前端开发 HTML5
【Web端智能聊天客服】之HTML、CSS、Bootstrap的讲解及实例(超详细必看 附源码)
【Web端智能聊天客服】之HTML、CSS、Bootstrap的讲解及实例(超详细必看 附源码)
56 0