canvas(三) 颜色和样式

使用样式和颜色


色彩 colors

如果想要给图形上色,有两个重要的属性可以做到:fillStylestrokeStyle

fillStyle = color
设置图形的填充颜色。

strokeStyle = color
设置图形轮廓的颜色。

color可以是表示css颜色值的字符串,渐变对象或者图案对象。默认情况下,线条和填充颜色都是黑色的(#000000)。

下面的例子表示的都是同一种例子:

//这些fillStyle的值均为‘橙色’
ctx.fillStyle = 'orange'
ctx.fillStyle = '#ffa500'
ctx.fillStyle = 'rgb(255,165,0)'
ctx.fillStyle = 'rbga(155,165,0,1)'

fillStyle 示例

function draw(){
    var ctx = document.getElementById('canvas').getContext('2d');
    for (var i=0;i<6;i++){
        for (var j=0;j<6;j++){
            ctx.fillStyle = 'rgb(' + Math.floor(255-42.5*i) + ',' + 
                       Math.floor(255-42.5*j) + ',0)';
            ctx.fillRect(j*25,i*25,25,25);
        }
    }
}
fillStyle示例
fillStyle示例

利用两层for循环来绘制方格列阵,每个方格不同的颜色。通过每次循环都设置不同的fillStyle 的值。

strokeStyle 示例

同fillStyle的示例相似,通过循环来变换 strokeStyle 的值。

function draw(){
    var ctx = document.getElementById('canvas').getContext('2d');
    for (var i=0;i<6;i++){
        for (var j=0;j<6;j++){
            ctx.strokeStyle = 'rgb(' + Math.floor(255-42.5*i) + ',' + 
                       Math.floor(255-42.5*j) + ',0)';
            ctx.beginPath();
            ctx.arc(12.5+j*25,12.5+i*25,10,0,Math.PI*2,true)
            ctx.stroke();
        }
    }
}
此处输入图片的描述
此处输入图片的描述

透明度 Transparency

除了可以绘制实色图形,还可以用canvas来绘制半透明的图形。通过设置 globalAlpha 属性或者使用一个半透明颜色作为轮廓或者填充色。

globalAlpha = transparencyValue
这个属性影响到canvas里所有的图形透明度,有效范围是0.0(完全透明)到1.0(完全不透明),默认是1.0。

globalApha 属性需要在绘制全局拥有透明度相同的图形时,如果需要改变单个图形的透明度,设置 strokeStylefillStyle 的属性为 rgba 类型。

ctx.fillStyle = "rgba(255,0,0,0.5)"
ctx.strokeStyle = "rgba(255,0,0,0.5)"

线型 Line style

可以通过一系列属性来设置线的样式。

lineWidth = value
设置线条的宽度。默认值为1.0。

lineCap = type
设置线条末端样式。butt round square 默认是 butt

lineJoin = type
设定线条与线条间结合处的样式。 round bevelmiter 默认是miter

miterLimit = value
限制当两条线相交时交接处最大的长度,所谓交接处长度是指线条交接处内角顶点到另外角顶点的长度。

getLineDash()
返回一个包含当前虚线样式,长度为非负数的数组。

setLineDash(segments)
设置当前虚线样式。

lineDashOffset = value
设置虚线样式的起始偏移量。

lineWidth 属性的例子

这个属性设置当前绘线的粗细,属性值必须为正数。默认值是1.0。

function draw() {
    let canvas = document.getElementById('tutorial')
    if (canvas.getContext) {
        let ctx = canvas.getContext('2d');
        
        for(var i = 0;i<10;i++){
            ctx.lineWidth = 1+i  //递增增加lineWidth
            ctx.beginPath()
            ctx.moveTo(5+i*14,5)
            ctx.lineTo(5+i*14,140)
            ctx.stroke()
        }
    }
}
lineWidth
lineWidth

lineCap 属性的例子

属性lineCap 的值决定了线段端点显示的样子。可以为下面的三种样式butt round square 默认是butt

function draw() {
let canvas = document.getElementById('tutorial')
    if (canvas.getContext) {
        let ctx = canvas.getContext('2d');
        var lineCap = ['butt', 'round', 'square'];
        // 创建路径
        ctx.strokeStyle = '#09f';
        ctx.beginPath();
        ctx.moveTo(10, 10);
        ctx.lineTo(140, 10);
        ctx.moveTo(10, 140);
        ctx.lineTo(140, 140);
        ctx.stroke();

        // 画线条
        ctx.strokeStyle = 'black';
        for (let i = 0; i < lineCap.length; i++) {
            ctx.lineWidth = 15;
            ctx.lineCap = lineCap[i]

            ctx.beginPath()
            ctx.moveTo(25 + i * 50, 10)
            ctx.lineTo(25 + i * 50, 140)
            ctx.stroke()
        }
    }
}
lineCap
lineCap

最左边的线用了默认的butt。中间的是 round效果,端点处加了半径为一半线宽的半圆,右边的是square的效果,端点处加上了等宽且高度为一半线宽的方块。

lineJoin 属性的例子

lineJoin的属性值决定了图形中两线段连接处所显示的样子,可以为以下三种样式: round bevelmiter 默认是 miter

function draw() {
    let canvas = document.getElementById('tutorial')
    if (canvas.getContext) {
        let ctx = canvas.getContext('2d');
        var lineJoin = ['round', 'bevel', 'miter'];
        
        ctx.lineWidth = 10;
        for (var i = 0; i < lineJoin.length; i++) {
            ctx.lineJoin = lineJoin[i];
            ctx.beginPath();
            ctx.moveTo(5, 5 + i * 40);
            ctx.lineTo(35, 45 + i * 40);
            ctx.lineTo(75, 5 + i * 40);
            ctx.lineTo(115, 45 + i * 40);
            ctx.lineTo(155, 5 + i * 40);
            ctx.stroke();
        }
    }
}
lineJoin
lineJoin

用三条折线来做例子,分别设置不同的lineJoin值。最上面一条是 round 的效果,边角处被磨圆了,圆的半径等于线宽。中间为bevel效果,下层为miter效果。当值为miter效果时,线段会在连接处外侧延伸直至交于一点,延伸效果受到 miterLimit 属性的制约。

miterLimit 属性的演示例子

当设置 lineJoin 的属性为 miter 的效果时,线段的外侧边缘会延伸交汇于一点上。线段夹角越小焦点的距离越大。

miterLimit 属性就是用来设定外延交点与连接点的最大距离,如果交点距离大于这个值,连接效果就会变为 bevel

使用虚线

setLineDash([a,b]) 方法和 lineDashOffset 属性来制定虚线样式。 setLineDash 方法接受一个数组,来指定线段与间隙的交替,lineDashOffset 属性设置起始偏移量。

function draw() {
    let canvas = document.getElementById('tutorial')
    if (canvas.getContext) {
        let ctx = canvas.getContext('2d');

        ctx.setLineDash([5,15]) //设置交替量为5,15
        ctx.lineDashOffset = 2
        ctx.beginPath()
        ctx.moveTo(0,50)
        ctx.lineTo(400,50)

        ctx.stroke()
    }
}
QQ图片20171103085448.png

渐变 Gradients

像一般的绘图软件一样,可以使用线性或者径向的渐变来填充或者描边。

使用下面的方法新建一个 canvasGradient 对象,并且赋值给图形的 fillStyle 或者 strokeStyle 属性。

createLinearGradient(x1,y1,x2,y2)
createLinearGradient 方法接受4个参数,表示渐变的起点(x1,y1) 与终点 (x2,y2)。

createRadialGradient(x1,y1,r1,x2,y2,r2)
createRadialGradient(x1,y1,r1,x2,y2,r2) 方法接受6个参数,前三个定义一个以(x1,y1)为圆心,半径为r1的圆,后三个参数定义另一个以(x2,y2)为圆心,半径为r2的圆。

let lineGradient = ctx.createLinearGradient(0,0,150,150)
let radialGradient = ctx.createLinearGradient(75,75,0,75,75,100)

在创建完 canvasGradient 对象之后就可以使用 addColorStop 添加颜色了。

canvasGradient.addColorStop(position,color)
addColorStop 方法接受2个参数,position 参数必须是一个0.0 到 1.0 之间数值,表示渐变中颜色所在的相对位置。例如,0.5 表示颜色会出现在正中间。 color 参数必须是一个有效的css颜色值。

可以添加任意多个色标,下面是最简单的线性黑白渐变的例子。

let linearGradient = ctx.createLineGradient(0,0,150,150)
linearGradient.addColorStop(0.0,'white')
linearGradient.addColorStop(1,'black')

createLinearGradient 的例子

在例子中设置了两种不同的渐变。设置渐变的步骤是 创建canvasGradient 对象 --> 使用addcolorStop 设置渐变色标 --> 将 canvasGradient 赋值给 fillStyle 或者 strokeStyle --> 使用 fillRect 或者 strokeRect 绘制图形

function draw() {
    let canvas = document.getElementById('tutorial')
    if (canvas.getContext) {
        let ctx = canvas.getContext('2d');

        // Create gradients
        var lingrad = ctx.createLinearGradient(0, 0, 0, 150);
        lingrad.addColorStop(0, '#00ABEB');
        lingrad.addColorStop(0.5, '#fff');
        lingrad.addColorStop(0.5, '#26C000');
        lingrad.addColorStop(1, '#fff');

        var lingrad2 = ctx.createLinearGradient(0, 50, 0, 95);
        lingrad2.addColorStop(0.5, '#000');
        lingrad2.addColorStop(1, 'rgba(0,0,0,0)');

        // assign gradients to fill and stroke styles
        ctx.fillStyle = lingrad;
        ctx.strokeStyle = lingrad2;

        // draw shapes
        ctx.fillRect(10, 10, 130, 130);
        ctx.strokeRect(50, 50, 50, 50);

    }
}
此处输入图片的描述
此处输入图片的描述

createRadialGrdient 的例子

function draw() {
  var ctx = document.getElementById('canvas').getContext('2d');

  // 创建渐变
  var radgrad = ctx.createRadialGradient(45,45,10,52,50,30);
  radgrad.addColorStop(0, '#A7D30C');
  radgrad.addColorStop(0.9, '#019F62');
  radgrad.addColorStop(1, 'rgba(1,159,98,0)');
  
  var radgrad2 = ctx.createRadialGradient(105,105,20,112,120,50);
  radgrad2.addColorStop(0, '#FF5F98');
  radgrad2.addColorStop(0.75, '#FF0188');
  radgrad2.addColorStop(1, 'rgba(255,1,136,0)');

  var radgrad3 = ctx.createRadialGradient(95,15,15,102,20,40);
  radgrad3.addColorStop(0, '#00C9FF');
  radgrad3.addColorStop(0.8, '#00B5E2');
  radgrad3.addColorStop(1, 'rgba(0,201,255,0)');

  var radgrad4 = ctx.createRadialGradient(0,150,50,0,140,90);
  radgrad4.addColorStop(0, '#F4F201');
  radgrad4.addColorStop(0.8, '#E4C700');
  radgrad4.addColorStop(1, 'rgba(228,199,0,0)');
  
  // 画图形
  ctx.fillStyle = radgrad4;
  ctx.fillRect(0,0,150,150);
  ctx.fillStyle = radgrad3;
  ctx.fillRect(0,0,150,150);
  ctx.fillStyle = radgrad2;
  ctx.fillRect(0,0,150,150);
  ctx.fillStyle = radgrad;
  ctx.fillRect(0,0,150,150);
}
此处输入图片的描述
此处输入图片的描述

图案样式 Patterns

createPattern(image,type)
该方法接受两个参数,image 可以是一个 image 对象的引用,或者另一个canvas对象。 type 必须为下列的参数值之一: repeat repeat-x repeat-y no-repeat

图案的应用跟渐变很类似的,创建出一个pattern之后,赋值给 fillStyle 或者 strokeStyle 属性即可。

function draw() {
    let canvas = document.getElementById('tutorial')
    if (canvas.getContext) {
        let ctx = canvas.getContext('2d');

        //创建image对象 用作图案
        var img = new Image();
        img.src = 'https://mdn.mozillademos.org/files/222/Canvas_createpattern.png'
        //使用onload 确保图片已经被加载
        img.onload = function(){
            var ptrn = ctx.createPattern(img,'repeat')
            ctx.fillStyle = ptrn
            ctx.fillRect(0,0,150,150)
        }
    }
}
此处输入图片的描述
此处输入图片的描述

阴影 Shadows

shadowOffsetX = float shadowOffsetY = float
shadowOffsetXshadowOffsetY 用来设定阴影在X 和 Y 轴的延伸距离,它们是不受变换矩阵所影响的,负值表示阴影会向上或者向左延伸,正值则表示会往下或者右延伸,它们都默认为 0。

shadowBlur = float
shadowBlur 用于设定阴影的模糊程度,其数值并不跟像素数量挂钩,也不受变换矩阵的影响,默认为 0 。

shadowColor = color
shadowColor 使用标准的css 颜色值,设定阴影的颜色

文字阴影的例子

function draw() {
    let canvas = document.getElementById('tutorial')
    if (canvas.getContext) {
        let ctx = canvas.getContext('2d');
        //设置阴影
        ctx.shadowOffsetX = 2
        ctx.shadowOffsetY = 2
        ctx.shadowBlur = 5
        ctx.shadowColor = "rgba(0,0,0,0.5)"

        //设置文字
        ctx.font = "20px Times New Roman"      
        ctx.fillStyle = 'black'
        ctx.fillText("Sample String", 5, 30);

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

推荐阅读更多精彩内容

  • 一:canvas简介 1.1什么是canvas? ①:canvas是HTML5提供的一种新标签 ②:HTML5 ...
    GreenHand1阅读 4,661评论 2 32
  • 熟悉html5的程序员们肯定都知道 元素,该元素是用来在页面中规定一块区域,然后由js在该区域内绘制图形。canv...
    米几V阅读 2,136评论 1 5
  • 一、简介 HTML5 中的定义:“它是依赖分辨率的位图画布,你可以在 canvas 上面绘制任何图形,甚至加载照片...
    destiny0904阅读 10,515评论 1 4
  • 一、canvas简介 1.1 什么是canvas?(了解) 是HTML5提供的一种新标签 Canvas是一个矩形区...
    Looog阅读 3,935评论 3 40
  • 小时候妈妈说,男人不要轻易给人承诺,说到就要办到。 长大后,也没有和人有过地老天荒的海誓山盟,没有合适的人,有了,...
    大叔早安阅读 167评论 0 0