HTML5-Canvas初探(1)

canvas其实没有那么玄乎,它不外乎是一个H5的标签,跟其它HTML标签如出一辙:

canvas 元素用于在网页上绘制图形。

那么什么是 Canvas?

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

  • canvas本身没有任何的绘图能力,所有的绘图工作都是通过js来实现的。通常我们在js通过getElementById来获取要操作的canvas(这意味着咱得给canvas设个id):

注意最好在一开始的时候就给canvas设置好其宽高(若不设定宽高,浏览器会默认设置canvas大小为宽300、高100像素),而且不能使用css来设置(会被拉伸),建议直接写于canvas标签内部:

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

也可以在js脚本中设置:

为什么不能用css来设置呢?

这是因为 canvas 元素有元素本身大小与元素绘图表面大小两套尺寸。 设置 width 和 height 时,实际上是同时修改了该元素本身大小和元素绘图表面大小; 而设置 css,只会改变元素本身大小,并不会改变元素绘图表面大小。

关于canvas大小需要知道的一点是,后续咱们对canvas所做的全部绘图操作,超出此大小范围的部分是不可见的。顾名思义,可以把canvas看成一块画布,其大小是咱设定好的宽高,那么无论你怎么画,画布外的地方自然是画不到的。

对于有些浏览器是不支持canvas功能的,我们可以直接在canvas标签中写一些替换内容,在浏览器不支持canvas时显示:


接着在聊如何在canvas上绘图前,咱得先说说.getContext(“2d”)这东西。 .getContext() 是canvas的绘图对象/方法,要让canvas执行绘图工作必须先获取canvas的.getContext()对象来执行。

.getContext()只接受一个参数,该参数用于获取canvas的绘图环境,例如.getContext(“2d”)表示该canvas的绘图环境为2D平面(可以绘制文本、直线、弧线、矩形、圆形等)。当前H5只支持2D环境,在不久的将来会开放3D绘图功能。(故咱可将“getContext”翻译为“获取绘图环境”)

接下来:主要是对canvas线段绘制功能的介绍 理论不多说,我们先来个小例子,从最简单的绘制直线开始:

效果如下:

在这里我们使用了3个getContext(“2d”)对象的绘图方法:

  • .moveTo(x坐标 , y坐标) 可以理解为定位画笔在画布上的位置(注意所有绘图方法所定义的坐标是相对canvas而言的而不是浏览器窗口,对canvas来说,最左上角的点的坐标是(0,0))
  • .lineTo(x坐标 , y坐标) 顾名思义,就是画一条直线到某个点,很好理解。需要知道的是此方法仅仅做路径运动,而不存在任何视觉上的绘图效果(上色、描边)
  • .stroke() 描边方法,有玩过AfterEffect的朋友会很清楚,不给运动路径加stroke特效的画是不存在描边效果的,canvas也一样,想要运动路径轨迹能有视觉效果,需要使用相应的上色/描边方法

自此我们很轻松地绘制了一条黑色的直线,但如果我们想要绘制一条红色的或者其它颜色的线段,该怎么做呢?

答案很简单,使用ctx.strokeStyle来设定描边的颜色即可。我们画三条红色的线段吧:

注释都说的很清楚了,故不再赘述实现原理,其效果如下:

注意在开始绘制路径的时候,一定要加上moveTo(x,y),否则第一个lineTo()的运动轨迹将不计入绘图中(浏览器会认为没获取到该运动轨迹的起始点,故忽略此线段)。


另外有一个问题,如果上方我们会出来的两条线段(嗯,一条折线,一条直线),我们希望第一条折线是蓝色的,第二条直线是红色的,应当怎么做?

你会很自然地做如下处理:

但运行脚本会发现,折线除了被描了一遍蓝色,也被描了一遍红色:

这是因为canvas在第二次给路径上色时,是把之前的所有路径轨迹合在一起来上色的,除非咱们让canvas知道那折线和直线应该是独立开来的俩路径。

我们可以使用.beginPath()来解决:

有的朋友一开始会搞不清楚beginPath()的用途,觉得有moveTo()就可以了,其实beginPath()可以做到上述的隔离路径绘制效果的作用,防止之前的效果被污染。


接着唠嗑.strokeStyle的赋值方式,咱们上方是直接用了 ctx.strokeStyle=”red” 来定义描边颜色为红色,不过ctx.strokeStyle可获值的形式有三种:

ctx.strokeStyle=color|gradient|pattern;  //即支持 “颜色/渐变/图案笔刷” 的赋值
  1. 先看看color赋值方式,和我们常规的css赋值是一样的,支持css3颜色值标准,如下例:

2 . 再看下渐变gradient,这个稍有复杂:

效果如下:

这里我们提到了一个概念叫“渐变线”,没有玩过设计的朋友需要了解下渐变的知识点,我们可以把LinearGradient(线性渐变,另有放射状/圆形渐变RadialGradient)范围看成一个矩形(你可以通过Illustator、Photoshop等专业设计软件来辅助你理解这点):

我们一开始定义线性渐变对象的代码 var grd = ctx.createLinearGradient(0,0,170,0) 不外乎就是设定了线性渐变线起始点为(0,0),结束点为(170,0)。

紧接着我们通过 addColorStop( 渐变线位置<0~1>, 颜色 ) 来设定了渐变色值,分别在渐变线0、0.5、1的位置设置了黑色、红色、黄色,其渐变效果如下:

通过 ctx.strokeStyle = grd 将渐变赋值给描边方法,最终描边得到了我们想要的渐变效果。

3 . 最后看看pattern描边方式,strokeStyle之所以不叫strokeColor是因为它除了支持颜色描边还支持图案描边(搞设计的朋友或许称作笔触描边会更有feel)。

线性渐变描边需要先createLinerGradient(xstart,ystart,xend,yend),那么设置图案描边自然也要先新建一个canvasPattern对象:

其中参数 image 代表图案对象,一般通过 document.createElement(‘img’) 或者 new Image() ,再定义其src值来创建该对象。 而repetitionStyle参数很好理解,即图案重复形式,其可选值有”repeat” 、”repeat-x”、”repeat-y” 和”no-repeat” (和css的background-repeat可选值一样,不赘述)。

我们这样写

效果如下:

注意这里我还加了个 ctx.lineWidth = 8 来设定线段的粗度。

自此我们学习了strokeStyle的三个赋值方式,也学习了上述的通过 ctx.lineWidth = lineWeight 的形式来给线段设定粗度。


咱们再学习两个很简单的线段属性 lineCap 和 lineJoin。

⑴ lineCap是设定线段端点的形状(线帽),其值可以是

butt 默认,即线条端点为平直的边缘 round 线条端点为圆角线帽 square 为线条端点添加正方形线帽

效果如下:

光看此图可能看不太出“butt”和”square”的区别,但懂得使用AI绘制矢量的同学们应该比较了解:

⑵ lineJoin则是设定折线的交接处的外角类型,其值可为:

miter 默认,折线交接处为尖角 round 折线交接处为圆角 bevel 折线交接处为斜角

效果如下

需要了解的是,miter还受到了属性miterLimit的影响(点此查看详细),但个人觉得它跟bevel实现的效果是一致的,故在此不做介绍。 这次就到这里了,下次再见了啦!

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏偏前端工程师的驿站

CSS魔法堂:你真的懂text-align吗?

前言 也许提及text-align你会想起水平居中,但除了这个你对它还有多少了解呢?本篇打算和大家一起来跟text-align来一次负距离的交往,你准备好了吗?...

23070
来自专栏练小习的专栏

带你轻松打开svg滤镜的大门

上次和大家一起,用最简单直白,轻松粗暴的方式学习了一遍SVG动画,这次我们再一起来搞点不一样的东西,SVG滤镜的实现。 SVG滤镜绝对称得上是他最强大的功能之一...

22180
来自专栏cnblogs

Css3新特性总结之边框与背景(二)

一、条纹背景 利用background为linear-gradient函数实现,linear-gradient取值如下: <angle>:角度,渐变的方向 t...

20690
来自专栏葡萄城控件技术团队

Spread for Windows Forms快速入门(9)---使用公式

Spread的公式计算引擎支持300多种内置函数,并支持通过内置函数和运算符来自定义公式。支持的函数包括日期、时间函数、工程计算函数、财务计算函数、逻辑函数、数...

23250
来自专栏Coco的专栏

谈谈一些有趣的CSS题目(三)-- 层叠顺序与堆栈上下文知多少

16750
来自专栏听雨堂

从MapX到MapXtreme2004[11]-坐标概论

        坐标的问题是Mapxtreme中最郁闷的问题,前几天在这上面耗了很多时间,没有搞定,今天又是不得不钻研,还好,小有心得。         1、...

22370
来自专栏HTML5学堂

原生JS | 导航底部横线跟随鼠标缓动

HTML5学堂(码匠):在上周当中,我们用jQuery实现了 - 在导航底部存在一条横线,跟随着鼠标缓动到相应导航项 - 的特效,今天我们来讲讲原生JS的实现方...

70880
来自专栏编程之旅

iOS开发——Core Graphics绘图

我们在搭建UI界面时,有很多时候,我们会用到iOS自带的绘图功能来完成一些界面的效果,很常用也很方便。今天我们在这里就一起讨论一下iOS的绘图功能。

26620
来自专栏前端桃园

深入理解z-index

在页面编写的过程中,经常需要处理元素的重叠。重叠的顺序不当则容易造成元素被错误地遮盖等现象。一般地,有很多人认为只需要指定元素的z-index即可调整重叠的顺序...

12920
来自专栏欧阳大哥的轮子

路径布局-基于数学函数的视图布局方法

路径布局MyPathLayout是MyLayout布局体系中的第7种布局体系,在这种布局体系中您只需要提供一个坐标轴、一个曲线函数、以及视图之间的距离这三个要素...

8020

扫码关注云+社区

领取腾讯云代金券