js canvas圖形 基本畫布功能(二)

基本介紹

創(chuàng)建<canvas>元素的時(shí)候至少要設(shè)置width height屬性康谆。這樣才能告訴瀏覽器在多大的地方進(jìn)行繪制陪每。在繪制之前首先要取到繪制的上下文态辛,使用getContext()方法可以獲取到繪制的上下文潜叛。為了確保瀏覽器對(duì)canvas的支持絮爷,最好先判斷一下瀏覽器是否支持canvas.

2D 繪制上下文

2D繪制圖形的方法包括矩形咬腕,弧形欢峰,路勁。2D上下文的坐標(biāo)原點(diǎn)在(0,0)即canvas的左上角涨共。所以的坐標(biāo)都是基于這一點(diǎn)進(jìn)行計(jì)算的纽帖。默認(rèn)情況下x的最大值是width y最大值為height

填充和描邊

2D上下文的基本繪制操作:填充和描邊即fillStyle和strokeStyle
fillSyle:代表填充的顏色,類似于backgroundColor
strokeStyle:代表邊框的顏色

繪制矩形

矩形是唯一一個(gè)可以直接在2D在上下文中繪制的圖形举反。與矩形繪制相關(guān)的方法有fillRect() strokeRect() clearRect(),這些方法都接受4個(gè)參數(shù):矩形的X參數(shù)懊直,矩形y參數(shù),矩形的寬度照筑,矩形的高度吹截。單位都是像素點(diǎn)。strokeRect創(chuàng)建的矩形有輪廓凝危,clearRect()清楚某一個(gè)區(qū)域例如

    function rect() {
            let drawing = document.querySelector("canvas")
            if (drawing.getContext) {
                console.log("11111111")
                let context = drawing.getContext("2d")
                context.lineWidth = 5
                // context.fillStyle ="red"
                context.strokeStyle = "red"
                context.fillStyle = "orange"
                context.fillRect(10, 10, 50, 50)

                context.fillStyle = "rgba(0,0,255,0.5)"
                context.fillRect(30, 30, 50, 50)
                context.clearRect(40, 40, 10, 10)

            }
        }
image.png

繪制路徑

2D繪制上下文支持很多在畫布繪制路勁的方法波俄。通過(guò)繪制路徑和繪制復(fù)雜的形狀和圖形,繪制路徑之前必須先調(diào)用beginPath方法表示開始繪制路勁蛾默,然后在調(diào)用一下方法
arc(x,y,radius,startAngle,endAngle,counterclockwise),已坐標(biāo)(x,y)為圓心懦铺,已radius為半徑繪制一條弧線,開始角度為startAngle支鸡,結(jié)束角度為endAngle冬念,counterclockwise表示順時(shí)針還是逆時(shí)針。默認(rèn)為順時(shí)針
lineTo(x,y) 繪制一條從上一點(diǎn)到(x,y)的直線
moveTo(x,y) 不繪制線牧挣,只是把光標(biāo)繪制點(diǎn)移動(dòng)到(x,y)點(diǎn)
以上三個(gè)方法實(shí)例如下

    function path() {
            console.log("2222222")
            let drawing = document.querySelector("canvas")
            if (drawing.getContext) {
                let context = drawing.getContext("2d")
                context.fillStyle = "orange"
                context.beginPath()
                context.arc(200,200,99,0,2*Math.PI,false)
                context.moveTo(294,200)
                context.arc(200,200,94,0,2*Math.PI,false)
                
                let fz = 100
                context.font = fz +"px Arial"
                while(context.measureText("hello wolrd").width >140) {
                    fz--
                context.font = fz +"px Arial"
                }
                context.fillText("hello wolrd",10,10)
                context.fillText("Font size is" +fz +"px",10,50)
                context.translate(200,200)
                context.rotate(2)
                context.moveTo(0,0)
                context.lineTo(0,-50)
                context.moveTo(0,0)
                context.lineTo(50,0)
                context.stroke()
            }
        }
image.png

arcTo(x1,y1,x2,y2,ranius):以給定的半徑急前,經(jīng)由(x1,y1)繪制一條從上一點(diǎn)到(x2,y2)的弧線

function basicPathDraw(){
            let drawing = document.querySelector("canvas")
            if (drawing.getContext) {
                var ctx=drawing.getContext("2d");
                ctx.beginPath();
                ctx.moveTo(20,20);           // 創(chuàng)建開始點(diǎn)
                ctx.lineTo(100,20);          // 創(chuàng)建水平線
                ctx.arcTo(150,20,150,70,50); // 創(chuàng)建弧
                ctx.lineTo(150,120);         // 創(chuàng)建垂直線
                ctx.stroke(); 
            }
        }
image.png
bezierCurveTo

bezierCurveTo(clx,cly,c2x,c2y,x,y)以(clx,cly)和(c2x,c2y)為控制點(diǎn),繪制一條從上一點(diǎn)到(x,y)的弧線(三次曲線)

function bezierCurveTo(){
            let drawing = document.querySelector("canvas")
            if (drawing.getContext) {
                var ctx=drawing.getContext("2d");
                ctx.beginPath();
                ctx.moveTo(20,20);
                ctx.bezierCurveTo(20,100,200,100,200,20);
                ctx.stroke();
            }
        }
image.png
quadraticCurveTo

quadraticCurveTo(cx瀑构,cy,x,y)以(cx,cy)為控制點(diǎn)裆针,繪制一條上一點(diǎn)到(x,y)的弧線(二次曲線)


image.png

路徑是2D上下文的主要繪制機(jī)制。通過(guò)isPointInPath(x,y)方法來(lái)判斷(x寺晌,y)是否在當(dāng)前路勁上面

繪制文本

文本和圖形的混合是最常見(jiàn)的繪制需求世吨。文本的繪制通過(guò)上下文中的fillText 和strokeText。這兩個(gè)方法都接受4參數(shù)呻征。第一個(gè)是要繪制的字符串耘婚,x坐標(biāo),y坐標(biāo)和可選的最大像素寬度陆赋。而且這兩個(gè)方法最終繪制的結(jié)果取決于上下文中的以下三個(gè)屬性
font:Css語(yǔ)法指定字體的樣式 "blod 14px"
textAlign:文本的對(duì)齊方式 "start" "end"
textBaseLine:指定文本的基線

context.fillText("Font size is" +fz +"px",10,50)

對(duì)于復(fù)雜文本的繪制是一件很難得事情沐祷,比如在特定文字繪制到指定區(qū)域嚷闭。因此2D上下文提供了用戶輔助確定文本大小的measureText()方法,該方法接受一個(gè)參數(shù)戈轿,返回一個(gè)TextMetrics對(duì)象凌受,返回對(duì)象只有一個(gè)屬性width。用法如下

let fz = 100
                context.font = fz +"px Arial"
                while(context.measureText("hello wolrd").width >140) {
                    fz--
                context.font = fz +"px Arial"
                }
                context.fillText("hello wolrd",10,10)
                context.fillText("Font size is" +fz +"px",10,50)

變換

上下文變換可以操作繪制在畫布的圖像思杯。以下方法用于改變繪制上下文圖像的變換矩陣
rotate(ange):圍繞原點(diǎn)把圖像旋轉(zhuǎn)angle弧度
scale(scaleX,scaleY) :x上乘上scaleX胜蛉,y上乘上scaleY
translate(x,y):把原點(diǎn)移動(dòng)到(x,y)。執(zhí)行這個(gè)操作之后原點(diǎn)變成了(x,y)
可以使用save()方法保存context上下文設(shè)置色乾,restroe()方法恢復(fù)之前的上下文設(shè)置

陰影

2D上下文可以根據(jù)以下屬性自動(dòng)改變相關(guān)或者路徑上面的陰影
shadowColor:CSS屬性值誊册,表示要繪制的陰影顏色
shadowOffsetX/Y:陰影相對(duì)x/y坐標(biāo)上面的偏移
shadowBlur:陰影的模糊程度

var ctx=drawing.getContext("2d");
                ctx.shadowOffsetX = 5
                ctx.shadowOffsetY = 5
                ctx.shadowBlur = 4
                ctx.shadowColor = "rgba(0,0,0,0.5)"
                ctx.fillStyle = "#ff0000"
                ctx.fillRect(30,30,50,50)

漸變

漸變通過(guò)CanvasGradient的實(shí)例表示。要?jiǎng)?chuàng)建一個(gè)新的線性漸變暖璧,可以調(diào)用上下文的createLinearGradient()方法案怯,該方法需要4個(gè)參數(shù),開始x坐標(biāo)澎办,開始y坐標(biāo)嘲碱,終點(diǎn)x坐標(biāo),終點(diǎn)y坐標(biāo)局蚀。調(diào)用之后會(huì)創(chuàng)建一個(gè)實(shí)例對(duì)象麦锯。有了實(shí)例對(duì)象之后,使用addColorStop()方法為漸變指定色標(biāo)琅绅。這個(gè)方法接受兩個(gè)參數(shù)扶欣,第一個(gè)參數(shù)為色標(biāo),取值為0~1,0代表第一種顏色千扶,1代表最后一種顏色料祠。
還有一種漸變使用createRadiaGradient方法創(chuàng)建。這種漸變也叫放射性漸變澎羞。這個(gè)方法接受三個(gè)參數(shù)髓绽,前三個(gè)參數(shù)賽表一個(gè)圓的圓心x,y,半徑妆绞,后三個(gè)參數(shù)代表后一個(gè)圓 圓心x,y和半徑

function radialGradient(){
            let drawing = document.querySelector("canvas")
            
        if (drawing.getContext) {
            var ctx=drawing.getContext("2d");
            let gradient = ctx.createRadialGradient(80,80,10,80,80,30)
            gradient.addColorStop(0,"white")
            gradient.addColorStop(1,"black")
            ctx.fillStyle = "#ff0000"
            ctx.fillRect(10,10,50,50)
            ctx.fillStyle =gradient
            ctx.fillRect(30,30,100,100)
        }   
        }
image.png

數(shù)據(jù)圖像

2D上下文可以通過(guò)getImageData()方法獲取到原始圖像的數(shù)據(jù)
實(shí)例如下

function imgData(){
            // let img = 
            // console.log(img)
            let drawing = document.querySelector("canvas")
                
            if (drawing.getContext) {
                var ctx=drawing.getContext("2d");
                let image = document.images[0],imageData,data,i,len,average,red,green,blue,alpha
                ctx.drawImage(image,0,0)
                imageData = ctx.getImageData(0,0,image.width,image.height)
                data = imageData.data
                for ( i = 0; i < data.length; i+=4) {
                    red = data[i]
                    green = data[i+1]
                    blue = data[i+2]
                    alpha = data[i+3]
                    average = Math.floor((red+green+blue)/3)
                    data[i] = average
                    data[i+1]= average
                    data[i+2] =average
                }
                imageData.data = data
                ctx.putImageData(imageData,0,0)
            }
        }
image.png

圖形的合成

兩個(gè)圖像重疊可以使用globalCompositeOperation方法對(duì)兩個(gè)圖形進(jìn)行重疊

function gloab(){
            let drawing = document.querySelector("canvas")
                
            if (drawing.getContext) {
                let ctx=drawing.getContext("2d");
                ctx.fillStyle = "#ff0000"
                ctx.fillRect(10,10,50,50)
                ctx.globalAlpha = 0.5
                // ctx.globalCompositeOperation = "source-in" //只繪制重疊部分(其他部分透明)
                // ctx.globalCompositeOperation = "source-out" //只繪制新圖形不重疊部分(其他部分透明
                // ctx.globalCompositeOperation = "source-atop" //舊圖不受影響梧宫,新圖只繪制重疊部分
                // ctx.globalCompositeOperation = "destination-over" //新圖在舊圖s面,透明度根據(jù)舊圖決定
                // ctx.globalCompositeOperation = "destination-in" //新圖在舊圖下面摆碉,只顯示重疊部分,其他部分隱藏
                // ctx.globalCompositeOperation = "destination-out" //新圖和舊圖重疊部分完全透明
                // ctx.globalCompositeOperation = "destination-atop" //新圖在舊圖下面脓豪,舊圖不重疊的地方透明
                // ctx.globalCompositeOperation = "lighter" //新圖形與原有圖形重疊部分像素相加巷帝,變得更加亮
                ctx.globalCompositeOperation = "copy" //新圖形講被擦除
                ctx.fillStyle = "#00ff00"
                ctx.fillRect(10,40,50,50)
                ctx.globalAlpha = 0.5
                
            }
        }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市扫夜,隨后出現(xiàn)的幾起案子楞泼,更是在濱河造成了極大的恐慌驰徊,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,635評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件堕阔,死亡現(xiàn)場(chǎng)離奇詭異棍厂,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)超陆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門牺弹,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人时呀,你說(shuō)我怎么就攤上這事张漂∮希” “怎么了略板?”我有些...
    開封第一講書人閱讀 168,083評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)让簿。 經(jīng)常有香客問(wèn)我趴梢,道長(zhǎng)漠畜,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,640評(píng)論 1 296
  • 正文 為了忘掉前任坞靶,我火速辦了婚禮憔狞,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘滩愁。我一直安慰自己躯喇,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,640評(píng)論 6 397
  • 文/花漫 我一把揭開白布硝枉。 她就那樣靜靜地躺著廉丽,像睡著了一般。 火紅的嫁衣襯著肌膚如雪妻味。 梳的紋絲不亂的頭發(fā)上正压,一...
    開封第一講書人閱讀 52,262評(píng)論 1 308
  • 那天,我揣著相機(jī)與錄音责球,去河邊找鬼焦履。 笑死,一個(gè)胖子當(dāng)著我的面吹牛雏逾,可吹牛的內(nèi)容都是我干的嘉裤。 我是一名探鬼主播,決...
    沈念sama閱讀 40,833評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼栖博,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼屑宠!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起仇让,我...
    開封第一講書人閱讀 39,736評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤典奉,失蹤者是張志新(化名)和其女友劉穎躺翻,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體卫玖,經(jīng)...
    沈念sama閱讀 46,280評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡公你,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,369評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了假瞬。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片陕靠。...
    茶點(diǎn)故事閱讀 40,503評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖笨触,靈堂內(nèi)的尸體忽然破棺而出懦傍,到底是詐尸還是另有隱情,我是刑警寧澤芦劣,帶...
    沈念sama閱讀 36,185評(píng)論 5 350
  • 正文 年R本政府宣布粗俱,位于F島的核電站,受9級(jí)特大地震影響虚吟,放射性物質(zhì)發(fā)生泄漏寸认。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,870評(píng)論 3 333
  • 文/蒙蒙 一串慰、第九天 我趴在偏房一處隱蔽的房頂上張望偏塞。 院中可真熱鬧,春花似錦邦鲫、人聲如沸灸叼。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)古今。三九已至,卻和暖如春滔以,著一層夾襖步出監(jiān)牢的瞬間捉腥,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工你画, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留抵碟,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,909評(píng)論 3 376
  • 正文 我出身青樓坏匪,卻偏偏與公主長(zhǎng)得像拟逮,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子适滓,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,512評(píng)論 2 359

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