canvas

關(guān)鍵字:canvas 繪制 矩形 文字 圓形 曲線 圖片 畫(huà)布 變形 陰影


簡(jiǎn)介

IE8以下不支持
HTML5新標(biāo)簽 使用JS API
canvas不適用CSS設(shè)置樣式,使用自身的width和height屬性設(shè)置

作用

  • 繪制線
  • 繪制三角形
  • 繪制矩形
  • 繪制文字
  • 繪制圓形
  • 繪制圖片
  • 繪制視頻
  • 繪制圖片陰影
<canvas id="canvas" width="500" height="500">
    您的瀏覽器不支持canvas露戒,請(qǐng)升級(jí)至最新版
</canvas>

常用方法

獲取元素

大多數(shù)時(shí)候都在操作ctx對(duì)象

var canvas=document.getElementById("canvas");

獲取上下文對(duì)象(畫(huà)筆)

var ctx=canvas.getContext("2d");

暫時(shí)不涉及3d

繪制線

  • 1腿准、開(kāi)始繪制
  • 2容燕、繪制起點(diǎn)
  • 3操软、繪制后續(xù)的點(diǎn)
  • 4详瑞、繪制結(jié)束
    • closePath()也叫關(guān)閉路徑遗嗽,會(huì)把終點(diǎn)和起點(diǎn)連接起來(lái)進(jìn)行繪制
    • 當(dāng)需要終點(diǎn)和起點(diǎn)連接粘我,才使用closePath()
  • 5、畫(huà)(填)
    • 設(shè)置畫(huà)線顏色
    • 設(shè)置畫(huà)線的寬度
    • 畫(huà)線
    • 設(shè)置填充顏色
    • 填充
    • 繪制的線和填充的內(nèi)容會(huì)發(fā)生覆蓋的情況痹换,沒(méi)有優(yōu)先級(jí)征字,由代碼順序決定(后面設(shè)置的會(huì)覆蓋前面設(shè)置的)
//1都弹、開(kāi)始繪制
ctx.beginPath();
//2、繪制起點(diǎn)
ctx.moveTo(250,250);
//3匙姜、繪制后續(xù)的點(diǎn)
ctx.lineTo(500,0);
ctx.lineTo(450,450);
//4缔杉、繪制結(jié)束
//closePath()也叫關(guān)閉路徑,會(huì)把終點(diǎn)和起點(diǎn)連接起來(lái)進(jìn)行繪制
//當(dāng)需要終點(diǎn)和起點(diǎn)連接搁料,才使用closePath()
ctx.closePath();
//5或详、畫(huà)(填)
//設(shè)置畫(huà)線顏色
ctx.strokeStyle="red";
//設(shè)置畫(huà)線的寬度
ctx.lineWidth=5;
//畫(huà)線
ctx.stroke();
//設(shè)置填充顏色
ctx.fillStyle="blue";
//填充
ctx.fill();
//繪制的線和填充的內(nèi)容會(huì)發(fā)生覆蓋的情況,沒(méi)有優(yōu)先級(jí)郭计,由代碼順序決定(后面設(shè)置的會(huì)覆蓋前面設(shè)置的)

繪制矩形

按照矩形畫(huà)線ctx.strokeRect(x,y,w,h);
按照矩形填充ctx.fillRect(x,y,w,h);

//按照矩形畫(huà)線
ctx.strokeRect(0,0,100,100);
//按照矩形填充
ctx.fillRect(0,100,100,100);

繪制文字

  • 參數(shù)4:最大寬度霸琴,可寫(xiě)可不寫(xiě)

描邊文字ctx.strokeText(text,x,y,maxwidth?);
填充文字ctx.fillText(text,x,y,maxwidth?);

ctx.font="50px 黑體";
ctx.strokeText("hello world",100,100);
ctx.fillText("hello world",100,100);

繪制圓形

ctx.arc(x,y,r,startAngle,endAngle,direction)

  • 參數(shù)1:圓心的x
  • 參數(shù)2:圓心的y
  • 參數(shù)3:圓的半徑
  • 參數(shù)4:起點(diǎn)的位置昭伸,根據(jù)右側(cè)和設(shè)置的弧度制找到起點(diǎn)
  • 參數(shù)5:終點(diǎn)的位置梧乘,根據(jù)右側(cè)和設(shè)置的弧度制找到終點(diǎn)
  • 參數(shù)6:繪制的方向,true表示逆時(shí)針庐杨,false表示順時(shí)針
ctx.arc(250, 250, 200, Math.PI, Math.PI / 2, true);
ctx.stroke();

繪制曲線

  • 使用moveTo設(shè)置起點(diǎn)
  • 使用quadraticCurveTo()放置基準(zhǔn)點(diǎn)和終點(diǎn)

二次貝塞爾曲線

  • 參數(shù)1:基準(zhǔn)點(diǎn)的x
  • 參數(shù)2:基準(zhǔn)點(diǎn)的y
  • 參數(shù)3:終點(diǎn)的x
  • 參數(shù)4:終點(diǎn)的y
ctx.moveTo(0, 0)
ctx.quadraticCurveTo(250, 500, 500, 0);
ctx.stroke();

ctx.moveTo(0, 0);
ctx.quadraticCurveTo(500, 250, 0, 500);
ctx.stroke();

ctx.moveTo(0, 500);
ctx.quadraticCurveTo(250, 0, 500, 500);
ctx.stroke();

ctx.moveTo(500,0);
ctx.quadraticCurveTo(0, 250, 500, 500);
ctx.stroke();

三次貝塞爾曲線的特點(diǎn)是有兩個(gè)基準(zhǔn)點(diǎn)

  • 參數(shù)1:基準(zhǔn)點(diǎn)1的x
  • 參數(shù)2:基準(zhǔn)點(diǎn)1的y
  • 參數(shù)3:基準(zhǔn)點(diǎn)2的x
  • 參數(shù)4:基準(zhǔn)點(diǎn)2的y
  • 參數(shù)5:終點(diǎn)的x
  • 參數(shù)6:終點(diǎn)的y
ctx.moveTo(0, 0);
ctx.bezierCurveTo(500, 0, 0, 500, 500, 500);
ctx.stroke();

ctx.beginPath();
ctx.moveTo(0, 0);
ctx.bezierCurveTo(0, 500, 500, 0, 500, 500);
ctx.stroke();

ctx.beginPath();
ctx.moveTo(500, 0);
ctx.bezierCurveTo(0, 0, 500, 500, 0, 500);
ctx.stroke();

ctx.beginPath();
ctx.moveTo(500, 0);
ctx.bezierCurveTo(500, 500, 0, 0, 0, 500);
ctx.stroke();

繪制圖片

  • 如果想把圖像畫(huà)到canvas中选调,需要先創(chuàng)建image對(duì)象
var img = new Image();
img.src = './imgs/img.png';
img.onload = function () {
    // 必須等圖片加載完成之后,才可以進(jìn)行繪制
    ctx.drawImage(img, 100, 100);
    // ctx.drawImage(img, 100, 100, 200, 200);
    // ctx.drawImage(img, 100, 100, 260, 260, 100, 96, 260, 260);
    
    // 清除畫(huà)布
    ctx.clearRect(250, 250, 200, 200);
    // 四個(gè)參數(shù): x, y, w, h
    // 用戶(hù)清除畫(huà)布中已有的內(nèi)容
};

變形

注意:改變不了坐標(biāo)系
不會(huì)影響已經(jīng)繪制的內(nèi)容

  • 位移ctx.translate(x,y);
  • 縮放ctx.scale(scaleX,scaleY)
  • 旋轉(zhuǎn)灵份、弧度ctx.rotate();

代碼練習(xí)

ctx.translate(100, 100);
ctx.scale(2, 2);
ctx.rotate(Math.PI / 8);

ctx.fillRect(100, 100, 300, 100);

ctx.rotate(Math.PI / 2);
ctx.translate(200, 100);

ctx.fillStyle = 'red';
ctx.fillRect(0, 0, 300, 100);

代碼示例

// 繪制表盤(pán)
ctx.translate(250, 250);
for (var i = 0; i < 12; i++) {
    ctx.rotate(Math.PI / 6);
    ctx.beginPath();
    ctx.moveTo(0, -200);
    ctx.lineTo(0, -150);
    ctx.closePath();
    ctx.lineWidth = 10;
    ctx.stroke();
//因?yàn)楸肀P(pán)上所有的刻度都是圍繞中心展開(kāi)的仁堪,所以,先把坐標(biāo)系原點(diǎn) 平移 到canvas中心的位置填渠,然后在使用 負(fù)的y值 進(jìn)行繪制弦聂,每次繪制前,進(jìn)行30度的旋轉(zhuǎn)即可氛什,持續(xù)12次莺葫。 第一個(gè)繪制的并非是12刻度,而是刻度1
}

判斷是否點(diǎn)中

  • var res=ctx.isPointInPath(x,y);
    • 判斷是否點(diǎn)了某個(gè)區(qū)域
    • 注意點(diǎn):如果進(jìn)行了描邊枪眉,點(diǎn)擊內(nèi)部也會(huì)觸發(fā)
  • var res=ctx.isPointInStroke(x,y);
    • 判斷是否點(diǎn)中了邊框

常用屬性

顏色捺檬、線

  • 設(shè)置顏色ctx.strokeStyle = 'red';
  • 設(shè)置線的寬度ctx.lineWidth = 50;
  • 設(shè)置線的頭部和尾部進(jìn)行圓角處理ctx.lineCap = 'round';
  • 設(shè)置線的交互處進(jìn)行圓角處理ctx.lineJoin = 'round';
ctx.strokeStyle = 'red';
ctx.lineWidth = 50;
ctx.lineCap = 'round';
ctx.lineJoin = 'round';
ctx.stroke();

文字

  • 設(shè)置文字字體ctx.font = '50px 黑體';

注意:?jiǎn)为?dú)設(shè)置字體大小不起作用,需要同時(shí)設(shè)置字體

  • 設(shè)置水平對(duì)齊方式ctx.textAlign = 'left';
    • textAlign的參數(shù)start|left/center/end|right
  • 設(shè)置垂直對(duì)齊方式ctx.textBaseline = 'middle';
    • textBaseline的參數(shù)top/middle/bottom
ctx.font = '50px 黑體';
ctx.textAlign = 'left';
ctx.textBaseline = 'middle';
ctx.fillText('l j k m n p q', 100, 100);
ctx.strokeRect(100, 100, 300, 100);

陰影

  • 設(shè)置陰影顏色ctx.shadowColor = 'blue';
  • 設(shè)置陰影X軸偏移量ctx.shadowOffsetX = 10;
  • 設(shè)置陰影Y軸偏移量ctx.shadowOffsetY = 10;
  • 設(shè)置陰影模糊程度ctx.shadowBlur = 10;

代碼示例

ctx.shadowColor = 'blue';
ctx.shadowOffsetX = 10;
ctx.shadowOffsetY = 10;
ctx.shadowBlur = 10;
ctx.fillRect(250, 250, 200, 200);

動(dòng)畫(huà)

動(dòng)畫(huà)的原理:擦出-繪制-擦出-繪制-擦出-繪制-擦出-繪制

  • 使用setInterval();切換選項(xiàng)卡的時(shí)候
  • 使用setTimeout();實(shí)現(xiàn)setInterval();
  • requestAnimationFrame();幀動(dòng)畫(huà)

學(xué)習(xí)應(yīng)用——躁動(dòng)的小球

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>躁動(dòng)的小球</title>
        <style type="text/css">
            *{
                margin: 0;
                padding: 0;
            }
            html,body{
                overflow: hidden;
            }
        </style>
    </head>
    <body>
        <canvas id="canvas" width="300" height="300">
            <p>您的瀏覽器不支持canvas贸铜,請(qǐng)<a href="#">點(diǎn)擊</a>下載最新版瀏覽器</p>
        </canvas>
    </body>
    <script type="text/javascript">
        var canvas=document.getElementById("canvas");
        var ctx=canvas.getContext("2d");
        canvas.width=window.innerWidth;
        canvas.height=window.innerHeight;
        
        var canvasWidth=canvas.width;
        var canvasHeight=canvas.height;
        
        
        function random(min,max){
            return parseInt(Math.random()*(max-min+1)+min);
        }
        function randomColor(){
            var r=random(0,255);
            var g=random(0,255);
            var b=random(0,255);
            var a=Math.random(0,1)+0.3;
            return "rgba("+r+","+g+","+b+","+a+")";
        }
        
        var balls=[];
        for (var i=0;i<500;i++) {
            var ball={};
            ball.r=random(10,30);
            ball.x=random(ball.r,canvasWidth-ball.r);
            ball.y=random(ball.r,canvasHeight-ball.r);
            ball.color=randomColor();
            ball.speedX=random(1,5);
            ball.speedY=random(1,5);
            
            balls.push(ball);
        }
        
        setInterval(function(){
            ctx.clearRect(0,0,canvasWidth,canvasHeight);
            
            for (var i=0;i<balls.length;i++) {
                var ball=balls[i];
                
                ball.x+=ball.speedX;
                ball.y+=ball.speedY;
                
                if (ball.x>=canvasWidth-ball.r||ball.x<=ball.r) {
                    ball.speedX*=-1;
                }
                if (ball.y>=canvasHeight-ball.r||ball.y<=ball.r) {
                    ball.speedY*=-1;
                }
                
                ctx.beginPath();
                ctx.arc(ball.x,ball.y,ball.r,0,Math.PI*2,false);
                ctx.closePath();
                ctx.fillStyle=ball.color;
                ctx.fill();
                
            }
            
        },20)
    </script>
</html>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末堡纬,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子萨脑,更是在濱河造成了極大的恐慌隐轩,老刑警劉巖饺饭,帶你破解...
    沈念sama閱讀 216,470評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件渤早,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡瘫俊,警方通過(guò)查閱死者的電腦和手機(jī)鹊杖,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)悴灵,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人骂蓖,你說(shuō)我怎么就攤上這事积瞒。” “怎么了登下?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,577評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵茫孔,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我被芳,道長(zhǎng)缰贝,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,176評(píng)論 1 292
  • 正文 為了忘掉前任畔濒,我火速辦了婚禮剩晴,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘侵状。我一直安慰自己赞弥,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,189評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布趣兄。 她就那樣靜靜地躺著绽左,像睡著了一般。 火紅的嫁衣襯著肌膚如雪艇潭。 梳的紋絲不亂的頭發(fā)上妇菱,一...
    開(kāi)封第一講書(shū)人閱讀 51,155評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音暴区,去河邊找鬼闯团。 笑死,一個(gè)胖子當(dāng)著我的面吹牛仙粱,可吹牛的內(nèi)容都是我干的房交。 我是一名探鬼主播,決...
    沈念sama閱讀 40,041評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼伐割,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼候味!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起隔心,我...
    開(kāi)封第一講書(shū)人閱讀 38,903評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤白群,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后硬霍,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體帜慢,經(jīng)...
    沈念sama閱讀 45,319評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,539評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了粱玲。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片躬柬。...
    茶點(diǎn)故事閱讀 39,703評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖抽减,靈堂內(nèi)的尸體忽然破棺而出允青,到底是詐尸還是另有隱情,我是刑警寧澤卵沉,帶...
    沈念sama閱讀 35,417評(píng)論 5 343
  • 正文 年R本政府宣布颠锉,位于F島的核電站,受9級(jí)特大地震影響史汗,放射性物質(zhì)發(fā)生泄漏木柬。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,013評(píng)論 3 325
  • 文/蒙蒙 一淹办、第九天 我趴在偏房一處隱蔽的房頂上張望眉枕。 院中可真熱鬧,春花似錦怜森、人聲如沸速挑。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,664評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)姥宝。三九已至,卻和暖如春恐疲,著一層夾襖步出監(jiān)牢的瞬間腊满,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,818評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工培己, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留碳蛋,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,711評(píng)論 2 368
  • 正文 我出身青樓省咨,卻偏偏與公主長(zhǎng)得像肃弟,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子零蓉,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,601評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容

  • 一:canvas簡(jiǎn)介 1.1什么是canvas笤受? ①:canvas是HTML5提供的一種新標(biāo)簽 ②:HTML5 ...
    GreenHand1閱讀 4,679評(píng)論 2 32
  • 一、canvas簡(jiǎn)介 1.1 什么是canvas敌蜂?(了解) 是HTML5提供的一種新標(biāo)簽 Canvas是一個(gè)矩形區(qū)...
    Looog閱讀 3,941評(píng)論 3 40
  • 簡(jiǎn)介 canvas 來(lái)源 html5新屬性 使用JS API 兼容問(wèn)題 IE8以下不支持canvas 注意 不要...
    馮小胖兒閱讀 468評(píng)論 0 0
  • 神奇且強(qiáng)大的canvas 一.Canvas的基本介紹 1.什么是Canvas 定義:是HTML5提供的一種新標(biāo)簽,...
    Ainy塵世繁花終凋落閱讀 10,746評(píng)論 1 18
  • 我有一個(gè)朋友箩兽,我覺(jué)得他生活其實(shí)不錯(cuò),至少在我們這個(gè)朋友圈里家里條件好章喉,結(jié)婚又有了一個(gè)小公舉汗贫∩碜可是最近他總說(shuō)想一...
    壞女孩的眼淚閱讀 492評(píng)論 0 0