Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 亚洲国产一区在线二区三区,国产青青久久,国产精品久久久影院

          整合營(yíng)銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          HTML5(十)-Canvas 與 SVG 區(qū)別

          為一名前端攻城獅,Canvas 和 SVG 對(duì)于我們并不陌生,canvas 是 HTML5 提供的新元素,而 svg 存在的時(shí)間要比 canvas 長(zhǎng)很多,svg 并不屬于 html,最初的 svg 是由 XML 定義的,在 html 5 中 canvas 與 svg 看著相似,其實(shí)不同。

          一、基本介紹

          Canvas

          • 通過 js 來繪制 2D圖形。
          • canvas 圖像單位是像素。
          • canvas 圖像繪制完畢之后,瀏覽器將不再關(guān)注它,如果位置發(fā)生變換,就需要重新繪制。

          SVG

          • svg 使用 XML 描述的2D圖像。
          • svg 是基于 xml 的,所以 svg 中繪制圖形還是使用的元素,js 給元素任意添加事件。
          • svg 繪制的圖像是一個(gè)對(duì)象,如果對(duì)象的屬性發(fā)生改變,瀏覽器將重新繪制圖形。

          二、SVG與Canvas比較

          1. svg 是一種矢量圖,而 canvas 依賴于分辨率。所以 svg 放大不會(huì)失真,但是 canvas 繪制的圖形會(huì)失真。
          2. svg 支持事件處理器,而 canvas 不支持事件處理器。
          3. svg 中的文字獨(dú)立于圖像,文字可保留,可編輯和可搜索,canvas 的文本渲染能力弱。
          4. canvas 適合圖像密集型的游戲,頻繁地重繪圖像,svg 繪制的復(fù)雜度高時(shí)減慢渲染的速度。
          5. canvas 繪制的圖形可以多種格式 (jpg、png) 保存圖片,但是 svg 繪制的只能以 .svg 格式保存,使用時(shí)可以引入 html 文件。
          6. canvas 適合開發(fā)游戲,svg 不適合游戲應(yīng)用。

          二、如何應(yīng)用

          2.1、功能上來說

          canvas 是一個(gè)畫布,繪制出來的圖形是位圖,因此 canvas 可以繪制圖片,在實(shí)際應(yīng)用中,由于渲染性能高,所以大型游戲開發(fā)都用的 canvas 。除此之外,還有統(tǒng)計(jì)中常見的柱狀圖、餅圖、雷達(dá)圖等也使用的 canvas 。而 svg 繪制的是矢量圖,放大后不會(huì)失真,所以很適合做地圖。

          2.2、操作方面講

          canvas 繪制的圖形,只能給 canvas 整個(gè)畫布添加事件,而不能給某個(gè)圖形或文件添加事件處理器,但是 svg 支持事件綁定,如果需要添加帶有事件的動(dòng)畫效果時(shí),就需要選擇 svg。

          TML5 Canvas是HTML5新增的一個(gè)元素,它提供了一個(gè)可執(zhí)行JavaScript腳本繪制圖形的區(qū)域。Canvas元素通過使用JavaScript API,可以在瀏覽器上繪制圖形、渲染動(dòng)畫和實(shí)現(xiàn)交互效果等。

          使用原理:
          HTML5 Canvas通過使用JavaScript API在瀏覽器中創(chuàng)建一塊畫布(Canvas),然后可以使用腳本語言(通常是JavaScript)在畫布上繪制各種形狀、線條、圖像和文本等。Canvas使用像素渲染,可以直接操作像素?cái)?shù)據(jù),因此在性能方面相比其他圖形技術(shù)(如SVG)更具優(yōu)勢(shì)。

          場(chǎng)景:
          HTML5 Canvas可以應(yīng)用于各種需要圖形繪制、動(dòng)畫渲染和交互效果的場(chǎng)景,例如:

          1. 游戲開發(fā):Canvas可以用來開發(fā)2D或3D游戲,通過繪制游戲場(chǎng)景、角色和動(dòng)畫等實(shí)現(xiàn)游戲效果。
          2. 數(shù)據(jù)可視化:Canvas可以用來繪制各種圖表和圖形,實(shí)現(xiàn)數(shù)據(jù)可視化效果。
          3. 圖像處理:Canvas可以對(duì)圖像進(jìn)行像素級(jí)別的操作,實(shí)現(xiàn)圖像處理功能,例如濾鏡、裁剪和合成等。
          4. 實(shí)時(shí)視頻處理:Canvas可以結(jié)合WebRTC等技術(shù)實(shí)現(xiàn)實(shí)時(shí)視頻處理,例如在視頻通話中添加特效和濾鏡等。

          代碼示例:
          以下是一個(gè)簡(jiǎn)單的HTML5 Canvas代碼示例,用于在畫布上繪制一個(gè)矩形和一個(gè)圓形:

          <!DOCTYPE html>  
          <html>  
              <head>  
               			<title>HTML5 Canvas示例</title>  
              </head>  
                <body>  
                     <canvas id="myCanvas" width="400" height="400"></canvas>  
                       <script>  
                           // 獲取Canvas元素和繪圖上下文  
                           var canvas = document.getElementById("myCanvas");  
                           var ctx = canvas.getContext("2d");  
                           // 繪制矩形  
                           ctx.fillStyle = "blue";  
                           ctx.fillRect(50, 50, 100, 100);  
                           // 繪制圓形  
                           ctx.beginPath();  
                           ctx.arc(200, 200, 50, 0, Math.PI * 2);  
                           ctx.fillStyle = "red";  
                           ctx.fill();  
                       </script>  
                </body>  
          </html>

          在上述代碼中,我們首先獲取了Canvas元素和繪圖上下文(Context),然后使用fillRect()方法繪制了一個(gè)藍(lán)色的矩形,使用arc()方法繪制了一個(gè)紅色的圓形。最后,我們使用fill()方法填充了圓形的顏色。

          SVG是構(gòu)建XML樹的方式來達(dá)到繪制圖形的,canvas是通過調(diào)用相關(guān)的方法來繪制圖形的。

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

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

          需要獲得上下文對(duì)象的時(shí)候,需要調(diào)用畫布的getContext方法,獲得繪畫的上下文。

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

          關(guān)于3D圖形,即,webGL 為封裝了基本的OPENGL,當(dāng)調(diào)用webGL的時(shí)候,其瀏覽器會(huì)調(diào)用OpenGL相關(guān)的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>第一個(gè)園</br>
           <canvas id="square" width="10" height="100">
           </canvas>
          </div>
          <div>
           第二個(gè)園
           <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");
          // 設(shè)置填充顏色為紅色
          context.fillStyle = "#f00";
          // 填充一個(gè)正方形
          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();

          // 進(jìn)行填充

          context.fill();

          繪制多邊形

          以五邊形為例子,

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

          同理,畫圓

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

          非零繞數(shù)原則

          要檢測(cè)一個(gè)點(diǎn)p是否在路徑內(nèi)部,使用非零繞數(shù)原則,即,一條從點(diǎn)p出發(fā)沿著任意方向無限延伸,或者一直延伸到路徑所在的區(qū)域外某點(diǎn)的射線,現(xiàn)在從0開始初始化一個(gè)計(jì)數(shù)器,對(duì)穿過這條射線的路徑進(jìn)行枚舉,每當(dāng)一條路徑順時(shí)針方向穿過射線的時(shí)候,計(jì)數(shù)器加1,逆時(shí)針減1,最后,枚舉完所有路徑以后,如果計(jì)時(shí)器的值不是0,那么就認(rèn)為p在路徑內(nèi),反過來,計(jì)數(shù)器的值為0,p在路徑外。

          js根據(jù)非零繞數(shù)原則確定那個(gè)在路徑內(nèi),那個(gè)在路徑外,用于進(jìn)行填充。

          圖形屬性

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

          對(duì)于canvas來說,每次獲取上下文對(duì)象的時(shí)候,都會(huì)返回同一個(gè)上下文對(duì)象,即,上下文對(duì)象為單例的。

          還可以使用save方法,把當(dāng)前的狀態(tài),壓入已經(jīng)保存的棧中,調(diào)用restore方法,把狀態(tài)進(jìn)行恢復(fù),即彈棧。

          畫布尺寸坐標(biāo)

          畫布的默認(rèn)的坐標(biāo)系為左上角的坐標(biāo)原點(diǎn)(0,0),右邊數(shù)值大,下數(shù)值大,使用浮點(diǎn)數(shù)指定坐標(biāo),但不會(huì)自動(dòng)轉(zhuǎn)換為整數(shù),會(huì)用反鋸齒的方式,模擬填充部分元素。

          畫布尺寸不能隨意改變,對(duì)任意屬性進(jìn)行操作,都會(huì)清空整個(gè)畫布。

          坐標(biāo)系變換

          每一個(gè)點(diǎn)的坐標(biāo)都會(huì)映射到css像素上,css像素會(huì)映射到一個(gè)或多個(gè)設(shè)備像素。

          畫布中的特定操作,屬性使用默認(rèn)坐標(biāo)系。

          畫布還有當(dāng)前變換矩陣。

          畫布還有當(dāng)前變換矩陣,當(dāng)前變換矩陣作為圖形狀態(tài)的一部分。矩陣定義了當(dāng)前畫布的坐標(biāo)系。

          畫布的操作會(huì)把該點(diǎn)映射到當(dāng)前的坐標(biāo)系中。

          坐標(biāo)變換

          當(dāng)調(diào)用c.translate(dx,dy)方法的時(shí)候,會(huì)進(jìn)行如下變換

          translate會(huì)進(jìn)行坐標(biāo)的上下移動(dòng)

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

          縮放

          如要進(jìn)行縮放,進(jìn)行的是如下的變換

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

          進(jìn)行旋轉(zhuǎn)操作,進(jìn)行的是如下變換

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

          如果要先變換再伸縮,進(jìn)行如下變換

          需要先把現(xiàn)有坐標(biāo)系映射成為坐標(biāo)系中的點(diǎn)x’, y’ 然后再變換到x‘’ , y‘’

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

          如果變換順序相反進(jìn)行如下變換

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

          這種變換稱為仿射變換,并且仿射變換會(huì)修改點(diǎn)的距離和線段間的夾角。對(duì)于平行線來說,仿射變換也會(huì)保持平行。仿射變換用6個(gè)參數(shù)描述成為如下表述

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

          通過傳入?yún)?shù)實(shí)現(xiàn)仿射變換

          對(duì)于坐標(biāo)變換來說,除非進(jìn)行刷新,否則,已經(jīng)繪制的圖形,不會(huì)進(jìn)行消失,所有的變換,都不能對(duì)已經(jīng)繪制的圖形進(jìn)行更改。栗子如下

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

          已經(jīng)繪制的圖形不會(huì)進(jìn)行改變,改變的是已經(jīng)繪制的圖形

          科赫雪花

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

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

          // 通過坐標(biāo)變換實(shí)現(xiàn)科赫雪花

          // 當(dāng)前狀態(tài)入棧

          function leg(n) {

          // 保存狀態(tài)

          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);

          }

          // 坐標(biāo)恢復(fù)變換

          context.restore();

          // 恢復(fù)下一個(gè)坐標(biāo)為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");
          // 工具函數(shù),角度轉(zhuǎn)弧度
          function rads(x) {
           return Math.PI * x / 180;
          }
          // 繪制園
          context.beginPath();
          context.arc(100,100,40, 0, rads(360), false);
          context.stroke();
          context.fill();
          

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

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

          繪制一個(gè)漸變

          需要使用createLinearGradient獲取一個(gè)進(jìn)行漸變的上下文,對(duì)這個(gè)上下文進(jìn)行處理。然后其顏色設(shè)置為這個(gè)漸變的上下文,即,fillStyle屬性。

          線段繪制

          封頂

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

          在繪制圖形以后,會(huì)參數(shù)尖角,圓角,平角,三種。

          lineCap屬性

          文本

          和css類似,基線問題。

          裁剪

          直接調(diào)動(dòng)clip即可,當(dāng)前路徑也會(huì)被裁剪進(jìn)入,路徑外的統(tǒng)統(tǒng)不會(huì)顯示。

          陰影

          設(shè)置shadow屬性即可

          圖片

          畫布API支持位圖圖片,同時(shí)也支持canvas導(dǎo)出成為圖片。

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

          合成

          一些api不在闡述

          像素操作

          調(diào)用getImageDate方法返回ImageDate對(duì)象

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

          進(jìn)行動(dòng)態(tài)模糊先獲取像素的ImageDate對(duì)象,然后再獲取該對(duì)象的data屬性,該data為一個(gè)數(shù)組。為一個(gè)維數(shù)組。每四個(gè)元素代表紅色分量,綠色分量,藍(lán)色分量,透明度分量。(Alpha分量)

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

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

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

          然后把其色素塊進(jìn)行復(fù)制回去即可。

          其中每個(gè)像素占據(jù)一個(gè)字節(jié),一個(gè)四個(gè)字節(jié)。

          命中檢測(cè)

          isPointInPath方法用來確定一個(gè)點(diǎn)是否落在當(dāng)前路徑中。

          即命中檢測(cè)。

          命中檢測(cè)可以和鼠標(biāo)事件相互轉(zhuǎn)化

          但是坐標(biāo)需要進(jìn)行轉(zhuǎn)換。


          主站蜘蛛池模板: 日韩福利视频一区| 国产一区二区三区在线免费| 国产日产久久高清欧美一区| 日本一区二区三区免费高清在线 | 日本人的色道www免费一区| 一区二区三区日本视频| 日本高清一区二区三区| 久久一区二区三区精品| 亚洲第一区精品日韩在线播放| 亚洲香蕉久久一区二区三区四区| 国产一区三区二区中文在线| 精品国产亚洲第一区二区三区| 亚洲第一区视频在线观看| 国产在线视频一区| 一区二区精品久久| 国产精品一区二区三区高清在线| 中文字幕在线看视频一区二区三区 | 日韩精品中文字幕视频一区| 末成年女AV片一区二区| 亚洲欧洲∨国产一区二区三区| 国产伦精品一区二区| 少妇一晚三次一区二区三区| 亚洲国产一区在线观看| 日韩内射美女人妻一区二区三区| 中文字幕在线播放一区| 一区二区三区四区在线观看视频| 波多野结衣AV一区二区三区中文| 中文字幕精品一区二区2021年 | 精品人妻系列无码一区二区三区| 国产一区二区精品久久| 国产成人无码AV一区二区 | 中文字幕在线观看一区二区 | 国产成人久久精品一区二区三区| 国产精品污WWW一区二区三区| 日本视频一区二区三区| 国产主播一区二区三区在线观看| 蜜臀AV无码一区二区三区| 午夜福利无码一区二区| 亚洲日韩AV一区二区三区四区| 国产一区二区三区乱码网站| 69福利视频一区二区|