整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          html5 的 Canvas介紹

          SVG是構建XML樹的方式來達到繪制圖形的,canvas是通過調用相關的方法來繪制圖形的。

          區別:SVG繪制圖形,通過移除或者更改DOM方式來而使用canvas需要把圖片從新擦除。

          繪制的API在繪制上下文中定義。而不在畫布中定義。

          需要獲得上下文對象的時候,需要調用畫布的getContext方法,獲得繪畫的上下文。

          畫布元素和上下文,屬于兩個不同的對象,其中畫布元素為canvas畫布,而上下文對象為繪制需要的上下文。

          關于3D圖形,即,webGL 為封裝了基本的OPENGL,當調用webGL的時候,其瀏覽器會調用OpenGL相關的API

          繪制圓

          <!DOCTYPE html>
          <html lang="zh_CN" xmlns="http://www.w3.org/1999/html">
          <head>
           <meta charset="UTF-8">
           <title>Title</title>
          </head>
          <body>
          <div>第一個園</br>
           <canvas id="square" width="10" height="100">
           </canvas>
          </div>
          <div>
           第二個園
           <canvas id="circle" width="10" height="10">
           </canvas>
          </div>
          <script src="./js/index.js" charset="UTF-8"></script>
          </body>
          </html>
          // 獲取畫布元素
          let canvas = document.getElementById("square");
          // 獲取繪制2D元素上下文
          let context = canvas.getContext("2d");
          // 設置填充顏色為紅色
          context.fillStyle = "#f00";
          // 填充一個正方形
          context.fillRect(10,0,10,10);
          

          繪制線段,填充多邊形

          // 獲取畫布元素

          let canvas = document.getElementById("square");

          // 獲取繪制2D元素上下文

          let context = canvas.getContext("2d");

          // 開始一條路徑

          context.beginPath();

          // 從100,100 開始定義一條新的子路徑

          context.moveTo(100,100);

          // 從100 100 到 200 200 繪制一條線段

          context.lineTo(200,200);

          // 從200 200 到 100 200 繪制一條線段

          context.lineTo(100,200);

          // 從100 200 到 100 100 繪制一條路徑

          context.lineTo(100,100);

          // 繪制邊

          context.stroke();

          // 進行填充

          context.fill();

          繪制多邊形

          以五邊形為例子,

          var canvas = document.getElementById("square");
          var context = canvas.getContext("2d");
          // 繪制一個以100,100為中心,半徑為20的柜子N變形,每個定點均勻分布在圓角上,第一個定點放置在最上下
          // 偏轉角度為0
          // 開始定義一條子路徑
          context.moveTo(100 + 20 * Math.sin(0), 100 - 20 * Math.cos(0));
          // 計算兩個頂點之間夾角
          // 其中2π為一個園,除以邊數,得到需要旋轉的角度
          var delta = 2 * Math.PI/5;
          console.log(delta);
          // 循環剩余每個頂點
          var angle = 0;
          for(var i = 1; i < 5; i++){
           // 角度累加
           angle += delta;
           // 通過旋轉繪制下一個頂點,不斷的旋轉繪制
           context.lineTo(100 + 20 * Math.sin(angle), 100 - 20*Math.cos(angle));
          }
          // 最后一個頂點和起點進行連接
          context.closePath();
          // 從新開始一條新路徑
          context.stroke();
          context.fill();
          

          同理,畫圓

          var canvas = document.getElementById("square");
          var context = canvas.getContext("2d");
          // 繪制一個以100,100為中心,半徑為20的柜子N變形,每個定點均勻分布在圓角上,第一個定點放置在最上下
          // 偏轉角度為0
          // 開始定義一條子路徑
          context.moveTo(100 + 20 * Math.sin(0), 100 - 20 * Math.cos(0));
          // 計算兩個頂點之間夾角
          // 其中2π為一個園,除以邊數,得到需要旋轉的角度
          var delta = 2 * Math.PI/500000;
          console.log(delta);
          // 循環剩余每個頂點
          var angle = 0;
          for(var i = 1; i < 500000; i++){
           // 角度累加
           angle += delta;
           // 通過旋轉繪制下一個頂點,不斷的旋轉繪制
           context.lineTo(100 + 20 * Math.sin(angle), 100 - 20*Math.cos(angle));
          }
          // 最后一個頂點和起點進行連接
          context.closePath();
          // 從新開始一條新路徑
          context.stroke();
          context.fill();
          

          非零繞數原則

          要檢測一個點p是否在路徑內部,使用非零繞數原則,即,一條從點p出發沿著任意方向無限延伸,或者一直延伸到路徑所在的區域外某點的射線,現在從0開始初始化一個計數器,對穿過這條射線的路徑進行枚舉,每當一條路徑順時針方向穿過射線的時候,計數器加1,逆時針減1,最后,枚舉完所有路徑以后,如果計時器的值不是0,那么就認為p在路徑內,反過來,計數器的值為0,p在路徑外。

          js根據非零繞數原則確定那個在路徑內,那個在路徑外,用于進行填充。

          圖形屬性

          可以通過設置畫布上下文的fillStyle等屬性,設置圖形的屬性,例如對畫布上下文的fillStyle的屬性進行設置,即,可以設置出填充時的顏色,漸變,圖案等樣式。

          對于canvas來說,每次獲取上下文對象的時候,都會返回同一個上下文對象,即,上下文對象為單例的。

          還可以使用save方法,把當前的狀態,壓入已經保存的棧中,調用restore方法,把狀態進行恢復,即彈棧。

          畫布尺寸坐標

          畫布的默認的坐標系為左上角的坐標原點(0,0),右邊數值大,下數值大,使用浮點數指定坐標,但不會自動轉換為整數,會用反鋸齒的方式,模擬填充部分元素。

          畫布尺寸不能隨意改變,對任意屬性進行操作,都會清空整個畫布。

          坐標系變換

          每一個點的坐標都會映射到css像素上,css像素會映射到一個或多個設備像素。

          畫布中的特定操作,屬性使用默認坐標系。

          畫布還有當前變換矩陣。

          畫布還有當前變換矩陣,當前變換矩陣作為圖形狀態的一部分。矩陣定義了當前畫布的坐標系。

          畫布的操作會把該點映射到當前的坐標系中。

          坐標變換

          當調用c.translate(dx,dy)方法的時候,會進行如下變換

          translate會進行坐標的上下移動

          x' = x + dy;
          y' = y + dy;
          

          縮放

          如要進行縮放,進行的是如下的變換

          x' = sx * x;
          y' = sy * y;
          

          進行旋轉操作,進行的是如下變換

          x' = x * cos(a) - y * sin(a);
          y' = y * cos(a) - x * sin(a);
          

          如果要先變換再伸縮,進行如下變換

          需要先把現有坐標系映射成為坐標系中的點x’, y’ 然后再變換到x‘’ , y‘’

          x'' = sx*x + dx;
          y'' = sy*y + dy;
          

          如果變換順序相反進行如下變換

          x'' = sx*(x + dx);
          y'' = sy*(y + dy);
          

          這種變換稱為仿射變換,并且仿射變換會修改點的距離和線段間的夾角。對于平行線來說,仿射變換也會保持平行。仿射變換用6個參數描述成為如下表述

          x' = ax + cy + e;
          y' = bx + dy + f;
          

          通過傳入參數實現仿射變換

          對于坐標變換來說,除非進行刷新,否則,已經繪制的圖形,不會進行消失,所有的變換,都不能對已經繪制的圖形進行更改。栗子如下

          var canvas = document.getElementById("square");
          var context = canvas.getContext("2d");
          // 通過坐標變換實現科赫雪花
          // 開始一條路徑
          context.beginPath();
          // 開始繪制子路徑
          context.moveTo(100,100);
          // 繼續繪制
          context.lineTo(200,200);
          // 繼續繪制
          context.lineTo(200,200);
          // 進行繪制邊
          context.stroke();
          context.translate(200,200);
          // 開始一條路徑
          context.beginPath();
          // 開始繪制子路徑
          context.moveTo(100,100);
          // 繼續繪制
          context.lineTo(200,200);
          // 繼續繪制
          context.lineTo(200,200);
          // 進行繪制邊
          context.stroke();
          

          已經繪制的圖形不會進行改變,改變的是已經繪制的圖形

          科赫雪花

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

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

          // 通過坐標變換實現科赫雪花

          // 當前狀態入棧

          function leg(n) {

          // 保存狀態

          context.save();

          // 遞歸畫

          if(n == 0){

          context.lineTo(50, 0);

          }else{

          // 定義為v字型

          context.scale(1/2,1/2);

          // 遞歸第一條

          context.rotate(60 * (Math.PI / 180));

          leg(n - 1);

          context.rotate(-120 * (Math.PI / 180));

          leg(n - 1);

          }

          // 坐標恢復變換

          context.restore();

          // 恢復下一個坐標為0,0

          context.translate(50, 0);

          }

          context.save();

          context.moveTo(50, 50);

          // 繪制第一條

          leg(1);

          context.stroke();

          繪制填充曲線

          繪制一些常見的圖形

          var canvas = document.getElementById("square");
          var context = canvas.getContext("2d");
          // 工具函數,角度轉弧度
          function rads(x) {
           return Math.PI * x / 180;
          }
          // 繪制園
          context.beginPath();
          context.arc(100,100,40, 0, rads(360), false);
          context.stroke();
          context.fill();
          

          同理繪制貝塞爾曲線也是同理。

          顏色,透明度,漸變,圖案

          繪制一個漸變

          需要使用createLinearGradient獲取一個進行漸變的上下文,對這個上下文進行處理。然后其顏色設置為這個漸變的上下文,即,fillStyle屬性。

          線段繪制

          封頂

          對于線段,有三種封頂方式,即,butt,square,round

          在繪制圖形以后,會參數尖角,圓角,平角,三種。

          lineCap屬性

          文本

          和css類似,基線問題。

          裁剪

          直接調動clip即可,當前路徑也會被裁剪進入,路徑外的統統不會顯示。

          陰影

          設置shadow屬性即可

          圖片

          畫布API支持位圖圖片,同時也支持canvas導出成為圖片。

          // 創建一個img元素
          let img = document.createElement("img");
          // 設置src屬性
          img.src = canvas.toDataURL();
          // 追加到文檔后面
          document.body.appendChild(img);
          

          合成

          一些api不在闡述

          像素操作

          調用getImageDate方法返回ImageDate對象

          使用createImageDate()可以創建像素容器

          進行動態模糊先獲取像素的ImageDate對象,然后再獲取該對象的data屬性,該data為一個數組。為一個維數組。每四個元素代表紅色分量,綠色分量,藍色分量,透明度分量。(Alpha分量)

          其色素直為0-1,即,數組元素中保存的數組為色素值。

          每四個每四個元素遍歷。然后把其色素值的1/ n + 上一個色塊的m/n 然后賦值給新的色塊,代碼如下

          // row為行數
          for(var row = 0; row < height; row++){
           // 獲得每行第二個元素的偏移量,其中width為行的色素塊。
           var i = row * width * 4;
           // 每4個的色素值進行處理
           for(var col = 1; col < width; col++, i+=4){
           // 對紅色分量處理
           data[i] = (data[i] + data[i - 4] * m) / n;
           // 對綠色分量處理
           data[i + 1] = (data[i + 1] + data[i + 1 - 4] * m) / n;
           // 對藍色分量處理
           data[i + 2] = (data[i + 2] + data[i + 2 - 4] * m) / n;
           // 對透明度分量處理
           data[i + 3] = (data[i + 3] + data[i + 3 - 4] * m) / n;
           }
          }
          

          然后把其色素塊進行復制回去即可。

          其中每個像素占據一個字節,一個四個字節。

          命中檢測

          isPointInPath方法用來確定一個點是否落在當前路徑中。

          即命中檢測。

          命中檢測可以和鼠標事件相互轉化

          但是坐標需要進行轉換。

          TML5 的 canvas 元素使用 JavaScript 在網頁上繪制圖像。

          畫布是一個矩形區域,您可以控制其每一像素。

          canvas 擁有多種繪制路徑、矩形、圓形、字符以及添加圖像的方法。

          下面是一個用 HTML5 的 canvas 繪制的 3D 玫瑰花。

          <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

          <html>

          <head>

          <title>3D玫瑰花</title>

          <meta name="Generator" content="EditPlus">

          <meta name="Author" content="">

          <meta name="Keywords" content="">

          <meta name="Description" content="">

          </head>

          <body>

          <div id="demo" style="width:520; height:500px;"><canvas id="c" height="500" width="500"></canvas></div>

          <script>

          var b = document.body;

          var c = document.getElementsByTagName('canvas')[0];

          var a = c.getContext('2d');

          var canvas = document.getElementsByTagName('canvas')[0];

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

          document.body.clientWidth;

          with(m=Math)C=cos,S=sin,P=pow,R=random;

          c.width=c.height=f=500;h=-250;

          function p(a,b,c){

          if(c>60)

          return[S(a*7)*(13+5/(.2+P(b*4,4)))-S(b)*50,b*f+50,625+C(a*7)*(13+5/(.2+P(b*4,4)))+b*400,a*1-b/2,a];

          A=a*2-1;

          B=b*2-1;

          if(A*A+B*B<1){

          if(c>37){

          n=(j=c&1)?6:4;o=.5/(a+.01)+C(b*125)*3-a*300;

          w=b*h;

          return[o*C(n)+w*S(n)+j*610-390,o*S(n)-w*C(n)+550-j*350,1180+C(B+A)*99-j*300,.4-a*.1+P(1-B*B,-h*6)*.15-a*b*.4+C(a+b)/5+P(C((o*(a+1)+(B>0?w:-w))/25),30)*.1*(1-B*B),o/1e3+.7-o*w*3e-6]

          }

          if(c>32){

          c=c*1.16-.15;o=a*45-20;w=b*b*h;z=o*S(c)+w*C(c)+620;

          return[o*C(c)-w*S(c),28+C(B*.5)*99-b*b*b*60-z/2-h,z,(b*b*.3+P((1-(A*A)),7)*.15+.3)*b,b*.7]

          }

          o=A*(2-b)*(80-c*2);

          w=99-C(A)*120-C(b)*(-h-c*4.9)+C(P(1-b,7))*50+c*2;z=o*S(c)+w*C(c)+700;

          return[o*C(c)-w*S(c),B*99-C(P(b, 7))*50-c/3-z/1.35+450,z,(1-b/1.2)*.9+a*.1, P((1-b),20)/4+.05]

          }

          }

          var draw = setInterval('for(i=0;i<1e4;i++)if(s=p(R(),R(),i%46/.74)){z=s[2];x=~~(s[0]*f/z-h);y=~~(s[1]*f/z-h);if(!m[q=y*f+x]|m[q]>z)m[q]=z,a.fillStyle="rgb("+~(s[3]*h)+","+~(s[4]*h)+","+~(s[3]*s[3]*-80)+")",a.fillRect(x,y,1,1)}',0);

          var demo = document.getElementById('demo');

          function redraw(){

          /*

          var d_c = document.createElement("canvas");

          d_c.setAttribute("id","c");

          d_c.setAttribute("width","520");

          d_c.setAttribute("height","500");

          demo.appendChild(d_c);

          */

          draw = setInterval('for(i=0;i<1e4;i++)if(s=p(R(),R(),i%46/.74)){z=s[2];x=~~(s[0]*f/z-h);y=~~(s[1]*f/z-h);if(!m[q=y*f+x]|m[q]>z)m[q]=z,a.fillStyle="rgb("+~(s[3]*h)+","+~(s[4]*h)+","+~(s[3]*s[3]*-80)+")",a.fillRect(x,y,1,1)}',0);

          //alert(d_c);

          }

          function clear_canvas()

          {

          ctx.clearRect(0,0,520,500);

          //canvas.parentNode.removeChild(canvas); //刪除

          }

          function stop_draw(obj){

          clearInterval(obj);

          }

          </script>

          </body>

          </html>

          門可以通過啃書,但書本上的東西很多都已經過時了,在啃書的同時,也要持續關注技術的新動態。這里推幾本不錯的書:

            《JavaScript高級編程》:可以作為入門書籍,但同時也是高級書籍,可以快速吸收基礎,等到提升再回來重新看

          《JavaScript權威指南》:不太適合入門,但是必備,不理解的地方就去查閱一下,很有幫助

            《編寫可維護的JavaScript》和:

            《Node.js開發指南》:不錯的Nodejs入門書籍

            《深入淺出Node.js》:Nodejs進階書籍,必備

            《JavaScript異步編程》:理解JS異步的編程理念

            《JavaScript模式》和《JavaScript設計模式》:JavaScript的代碼模式和設計模式,將開發思維轉變到JavaScript,非常好的書

            《JavaScript框架設計》:在用輪子同時,應當知道輪子是怎么轉起來的,講解很詳細,從源碼級別講解框架的各個部分的實現,配合一個現有框架閱讀,可以學到很多東西

            《Dont make me think》:網頁設計的理念,了解用戶行為,非常不錯

            《CSS禪意花園》:經久不衰的一部著作,同樣傳遞了網頁設計中的理念以及設計中需要注意的問題

            《高性能JavaScript》和《高性能HTML5》:強調性能的書,其中不只是性能優化,還有很多原理層面的東西值得學習

            《HTML5 Canvas核心技術》:我正在讀的一本書,對于canvas的使用,動畫的實現,以及動畫框架的開發都非常有幫助

            《HTTP權威指南》:HTTP協議相關必備,前端開發調試的時候也會經常涉及到其中的知識

            《響應式Web設計》:技術本身不難,重要的是響應式網頁的設計理念,以及移動先行的思想

            《JavaScript語言精粹》:老道的書,也是普及JavaScript的開發思維的一本好書,非常適合入門

          一些不錯的網站

            github:沒啥好說的,多閱讀別人的源碼,多上傳自己的源碼,向世界各地的大牛學習

            codepen:感受前端之美的必選之地,里面有很多酷炫的效果和優秀的插件

            echojs:快速了解js新資訊的網站

            stackoverflow和segmentfault:基本上各種問題都能在上面獲得解答

            google web fundamentals:每篇文章都適合仔細閱讀

            static files:開放的CDN,很好用

            iconfont:阿里的矢量圖標庫,非常不錯,支持CDN而且支持項目

            html5 rocks: 一個不錯的網站,很多瀏覽器的新特性以及前沿的技術,都能在這上面找到文章

            css tricks:如何活用CSS,以及了解CSS新特性,這里可以滿足你

            JavaScript 秘密花園 JavaScript初學必看,非常不錯

            w3cplus:一個前端學習的網站,里面的文章質量都挺不錯的

            node school:一個不錯的node學習網站

            learn git branch:一個git學習網站,交互很棒

            前端亂燉:一個前端文章分享的社區,有很多優秀文章

            正則表達式:一個正則表達式入門教程,非常值得一看

          喜歡的可以收藏,希望能夠對你有所幫助

          切圖網(qietu.com)專業從事web前端開發的公司,專注we前端開發,響應式布局,webapp手機端網頁制作,微信html5頁面制作,bootstrap布局等,關注用戶體驗。


          主站蜘蛛池模板: 麻豆精品人妻一区二区三区蜜桃 | 麻豆va一区二区三区久久浪| 成人区精品一区二区不卡| 一区二区三区在线观看视频| 国产在线观看一区二区三区四区 | 伊人久久一区二区三区无码| 国产主播一区二区| 熟妇人妻系列av无码一区二区| 538国产精品一区二区在线| 国产精品被窝福利一区 | 精品无码一区二区三区电影| 日韩精品无码一区二区三区免费| 亚洲AV无码一区二区三区DV| 制服丝袜一区在线| 无码丰满熟妇一区二区| 国产传媒一区二区三区呀| 日韩一区二区三区在线观看| 中文字幕一区二区三区有限公司| 欧洲精品无码一区二区三区在线播放| 一区二区三区国产| 亚洲精品一区二区三区四区乱码| 国产91精品一区二区麻豆网站 | 国模无码人体一区二区| 无码人妻久久久一区二区三区| 中文字幕日韩丝袜一区| 国模极品一区二区三区| 亚洲国产激情一区二区三区| 日本中文字幕一区二区有码在线| 久久久老熟女一区二区三区| 亚洲综合一区无码精品| 日韩精品一区二区三区中文字幕| 中文字幕日韩一区二区三区不| 亚洲国产一区国产亚洲| 成人在线观看一区| 变态拳头交视频一区二区| 老熟女高潮一区二区三区| 国产伦精品一区二区| 久久高清一区二区三区| 国产成人精品一区二三区熟女| 亚洲国模精品一区| 精品国产一区AV天美传媒|