HTML5 -- Canvas

利用 HTML5 中的 Canvas,我们可以做很多很棒的事情,下面来看看我做的一个 Demo

HTML5 -- Canvas_第1张图片
mydemo.png

下面就针对这个例子介绍一下 Canvas 的基础使用。


HTML & CSS

当然 Canvas 的绘制需要借助 JavaScript, 首先让我们利用 HTMLCSS 将结构层和表现层搭建好,然后我们才可以大展身手。

你可以利用自己高超的 CSS 水平将页面写的十分炫酷,当然我只是简单的利用 CSS 对页面进行了布局,没有写其它用来表现的特性。



    
        
        
    
    
        

其实大部分内容都是关于书写表单控件的,这些代码千篇一律,十分好懂,不过唯一值得注意的是,我在输入控件中加入了 maxlength, 对输入的长度进行了控制,如果输入的字符串太多,绘制文字的时候会出现文字溢出。

上述代码中最珍贵的一行是定义 canvas 元素的那一行,将画布定义为 680px 宽,320px 高。

下面利用 CSS 对页面进行稍微的修改。

*,
*::before,
*::after {
    -moz-box-sizing: border-box;
         box-sizing: border-box;
    margin: 0;
    padding: 0;
}

article {
    width: 680px;
    height: 320px;
    margin: 32px auto;

    text-align: center;
}

canvas {
    border: 1px solid #ccc;
}

form section {
    margin-bottom: 16px;
}

这里,为画布设置了一个边框,是为了更清楚的看到画布的位置。


Canvas 绘图

为了绘制图形,我们首先要得到画布元素,并要求得到它的 2d 绘制上下文。像下面这样。

var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d");

有了这个 context, 我们就可以肆意的画图了,首先,让我们来画个矩形吧,需要哪些条件呢?事实上,我们只需要指定 x,y 坐标(矩形左上角的坐标)并且设置宽高就可以画出这个图形。

function drawSquare(canvas, context) {
    var width = Math.floor(Math.random() * 64);

    var x = Math.floor(Math.random() * canvas.width);
    var y = Math.floor(Math.random() * canvas.height);

    context.fillStyle = "lightblue";
    context.fillRect(x, y, width, width);
}

上面我们使用了随机值,这样我们就可以绘制出不同宽高分布在不同位置的矩形了。利用上面的代码,我们就可以看到下面这样的结果啦。

HTML5 -- Canvas_第2张图片
square.png

可以看到,有的矩形已经超出边界了,为什么呢?自己好好想想总会相处答案的吧!

既然已经知道怎么绘制矩形了,那么该怎么绘制圆形呢?我已经迫不及待的去画个圆了,因为我感觉圆比矩形好看,这也就是为什么我们在很多 app 中看到的是圆形头像。

不过,事情进展的不是很顺利,因为我们已经没有类似 fillCircle() 这样的函数可用了。所以我们不得不动笔去画一个,实际上利用 Canvas 你可以画出可以用笔画出的任何效果。在现实生活中,如果你想画画,那么你需要拿起一支笔,但是在画布上,你只需要调用 contextbeginPath() 方法就可以了,这相当于告诉画布:我要开始画些东西了,你准备好吧!

如果你想在指定的一个点开始你的笔迹,那么你可以使用 moveTo(x, y) 方法,如果你想从画笔的当前位置画线,可以使用 lineTo(x, y)方法。

好了,下面就让我们开始画圆吧!实际上,还有一个 arc() 方法,可以让我们去画圆,不过在这之前,我们需要调用 beginPath() 方法。

function drawCircle(canvas, context) {
    var radius = Math.floor(Math.random() * 48);

    var x = Math.floor(Math.random() * canvas.width);
    var y = Math.floor(Math.random() * canvas.height);

    context.beginPath();
    context.arc(x, y, radius, 0, Math.PI * 2, true);
    context.fillStyle = "lightblue";
    context.fill();
}

值得一提的是,arc() 方法中第四和第五个参数使用的都是弧度值,不过我们一般喜欢使用角度,比如 360 度,而不是 2 PI,所以我们可以写一个转换函数,然后你就可以尽情的使用熟悉的角度值了。

function degreesToRadians(degrees) {
    return (degrees * Math.PI) / 180;
}

下面,你就可以画出下面这样的效果。

HTML5 -- Canvas_第3张图片
circle.png

图形已经绘制完毕了,我们就去看看如何绘制文字,首先我们的获取输入控件中输入的文字,然后我们需要使用 contextmeasureText() 测量文字的宽度,因为我们想让文字居中。

function drawText(canvas, context) {
    var selectObj = document.getElementById("foregroundColor");
    var index = selectObj.selectedIndex;
    var fgColor = selectObj[index].value;
    var fontSize = "24";

    context.fillStyle = fgColor;
    context.font = "bold " + fontSize + "px sans-serif";
    context.textAlign = "left";

    var message = document.getElementById("message").value;
    var messageWidth = context.measureText(message).width;
    var x = Math.floor(canvas.width / 2 - messageWidth / 2);
    var y = Math.floor(canvas.height / 2 - fontSize / 2);
    context.fillText(message, x, y);
}

可以使用 context.font 设置文字相关的信息,第一个参数是 font style, 可以设置为 bold 或者 italic,第二个参数是文字的大小,第三个参数是 font family,这里我指定为 sans-serif

你可能还有疑问的是,context.textAlign 是什么玩意?这个就是设置 fillText() 中 x 坐标指定的是文本哪个部位的坐标,如果你设置为 center,那么这个 x 就是文本中间的 x 坐标。当然我们这里设置为 left 就是文本最左边的 x 坐标。

那么问题来了,我们为什么还要使用 measureText() 这么费劲的测试文本的宽度使文本居中呢?的确如此,我们可以使用 textAlign 轻易的实现文本居中,下面是对上述函数的改写。

function drawText(canvas, context) {
    var selectObj = document.getElementById("foregroundColor");
    var index = selectObj.selectedIndex;
    var fgColor = selectObj[index].value;
    var fontSize = "24";

    context.fillStyle = fgColor;
    context.font = "bold " + fontSize + "px sans-serif";
    context.textAlign = "center"; // change

    var x = Math.floor(canvas.width / 2); // change
    var y = Math.floor(canvas.height / 2 - fontSize / 2);

    var message = document.getElementById("message").value;
    context.fillText(message, x, y);
}

文字也绘制完毕了,下面就绘制图形右下角的笑脸图片,当然这是个图片,不是一笔一笔画出来的。

function drawImage(canvas, context) {
    var smileImage = new Image();
    smileImage.src = "smile.png";

    smileImage.onload = function() {
        context.drawImage(smileImage, 632, 272, 24, 24);
    }
}

drawImage() 的第二个参数是图形的左上角的 x 坐标,第三个参数是左上角的 y 坐标,第四个参数是图形的宽度,第五个参数是图形的高度。

这里为什么还是用一个 onload 呢?因为图片总是需要加载的,如果图片还没有加载完毕,就开始去绘制图片,肯定会绘制失败,所以我们利用一个回调,当图片加载完毕,再去绘制图片。

最后再来介绍一个目前浏览器支持不是很好的属性,我们可以将这个 Canvas 转化为一个图片,怎么样?听上去是不是很心动,其实写起来很容易。

function makeImage() {
    var canvas = document.getElementById("myCanvas");
    canvas.onclick = function() {
        window.location = canvas.toDataURL("image/png");
    }
}

这个时候,如果你的浏览器支持的话,只要你点击一些画布,那么就会有一个图片版本弹出来,供你保存到本地。

我在我的电脑上做了测试,只有 Firefox 支持这个功能,我喜欢的 Google Chrome, Opera, Yandex 在这方面的支持还不尽如人意。


如果你想要项目的源码,你可以到 我的 Github 下载源码。

Ending...

你可能感兴趣的:(HTML5 -- Canvas)