canvas繪制樹形結構可視圖形的實現_html5教程技巧

來源:腳本之家  責任編輯:小易  

我這里認為大家都稍微了解甚至熟悉canvas的一些API,就不具體說,每一個參數代表什么意思了。<!DOCTYPE html><html><head><meta charset='utf-8'><title>圖片加載平移放大縮小示例</title><style>html,body{margin:0px;padding:0px;}canvas{border: 1px solid #000;}</style></head><body><canvas id="canvas" width="800" height="800"></canvas><script type="text/javascript" src="main.js"></script></body></html>var canvas,context;function int(){canvas=document.getElementById('canvas');context=canvas.getContext('2d');}圖片加載創建一個圖片對象之后,圖片不能馬上繪制到canvas上面,因為圖片還沒有加載完成。所以我們需要監聽圖片對象加載完事件,然后再去繪制。var img,//圖片對象imgIsLoaded//圖片是否加載完成;function loadImg(){img=new Image();img.onload=function(){imgIsLoaded=true;//draw image}img.src="map.jpg";}圖片繪制繪制圖像一個函數就可以搞定,但是需要記錄這個圖像的左上角坐標以及縮放比例。var imgX,imgY,imgScale;function drawImage(){context.clearRect(0,0,canvas.width,canvas.height);context.drawImage(img,0,0,img.width,img.height,imgX,imgY,img.width*imgScale,img.height*imgScale);}圖片平移html5事件最小細度在DOM上,所以我們無法對canvas上的圖像做監聽,只能對canvas監聽。首先監聽鼠標mousedown事件,等事件發生之后,再監聽鼠標mousemove事件和mouseup事件mousemove事件發生之后,獲得鼠標移動的位移,相應的圖片的位置改變多少mouseup事件發生之后,取消對mousemove以及mouseup事件監聽canvas.onmousedown=function(event){var pos=windowToCanvas(canvas,event.clientX,event.clientY);canvas.onmousemove=function(event){canvas.style.cursor="move";var pos1=windowToCanvas(canvas,event.clientX,event.clientY);var x=pos1.x-pos.x;var y=pos1.y-pos.y;pos=pos1;imgX+=x;imgY+=y;drawImage();}canvas.onmouseup=function(){canvas.onmousemove=null;canvas.onmouseup=null;canvas.style.cursor="default";}}function windowToCanvas(canvas,x,y){var bbox = canvas.getBoundingClientRect();return {x:x - bbox.left - (bbox.width - canvas.width) / 2,y:y - bbox.top - (bbox.height - canvas.height) / 2};}圖片縮放其實縮放很簡單,稍微復雜的是,如何讓鼠標成為放大或者縮小的中心。如果數學幾何不好,計算公式就可能看不明白了。canvas.onmousewheel=canvas.onwheel=function(event){//chrome firefox瀏覽器兼容var pos=windowToCanvas(canvas,event.clientX,event.clientY);event.wheelDelta=event.wheelDelta?event.wheelDelta:(event.deltaY*(-40));if(event.wheelDelta>0){imgScale*=2;imgX=imgX*2-pos.x;imgY=imgY*2-pos.y;}else{imgScale/=2;imgX=imgX*0.5+pos.x*0.5;imgY=imgY*0.5+pos.y*0.5;}drawImage();}這個時候,基本功能就實現了,加載一張圖片和加載多張圖片都差不多,維護每一張圖片的位置和大小,下面來整理一下代碼吧。var canvas,context;var img,//圖片對象imgIsLoaded,//圖片是否加載完成;imgX=0,imgY=0,imgScale=1;(function int(){canvas=document.getElementById('canvas');context=canvas.getContext('2d');loadImg();})();function loadImg(){img=new Image();img.onload=function(){imgIsLoaded=true;drawImage();}img.src="map.jpg";}function drawImage(){context.clearRect(0,0,canvas.width,canvas.height);context.drawImage(img,0,0,img.width,img.height,imgX,imgY,img.width*imgScale,img.height*imgScale);}canvas.onmousedown=function(event){var pos=windowToCanvas(canvas,event.clientX,event.clientY);canvas.onmousemove=function(event){canvas.style.cursor="move";var pos1=windowToCanvas(canvas,event.clientX,event.clientY);var x=pos1.x-pos.x;var y=pos1.y-pos.y;pos=pos1;imgX+=x;imgY+=y;drawImage();}canvas.onmouseup=function(){canvas.onmousemove=null;canvas.onmouseup=null;canvas.style.cursor="default";}}canvas.onmousewheel=canvas.onwheel=function(event){var pos=windowToCanvas(canvas,event.clientX,event.clientY);event.wheelDelta=event.wheelDelta?event.wheelDelta:(event.deltaY*(-40));if(event.wheelDelta>0){imgScale*=2;imgX=imgX*2-pos.x;imgY=imgY*2-pos.y;}else{imgScale/=2;imgX=imgX*0.5+pos.x*0.5;imgY=imgY*0.5+pos.y*0.5;}drawImage();}function windowToCanvas(canvas,x,y){var bbox = canvas.getBoundingClientRect();return {x:x - bbox.left - (bbox.width - canvas.width) / 2,y:y - bbox.top - (bbox.height - canvas.height) / 2};www.13333515.buzz防采集請勿采集本網。

如下圖,最近項目中需要這么個樹形結構可視化數據圖形,找了好多可視化插件,沒有找到可用的,所以就自己畫了一個,代碼如下。 樹形分支是后端接口返回數據渲染,可展示多條; 代碼可拓展,可封裝; 點擊節點可查看備注;

XML 描述 2D 圖形的語言。 SVG 基于 XML,這意味著 SVG DOM 中的每個元素都是可用的。您可以為某個元素附加 JavaScript 事件處理器。 在 SVG 中,每個被繪制的圖形均被

<canvas id="canvas" width="750" height="800"></canvas>

HTML5 的 canvas 元素使用 JavaScript 在網頁上繪制圖像。 畫布是一個矩形區域,您可以控制其每一像素。 canvas 擁有多種繪制路徑、矩形、圓形、字符以及添加圖像的方法

const canvas_options={ canvasWidth: 750, canvasHeight: 800, chartZone: [70,70,750,570], //坐標繪制區域 yAxisLabel: ['0%','10%','20%','30%','40%','50%','60%','70%','80%','90%','100%'],//y軸坐標text yAxisLabelWidth: 70,//y軸最大寬度 yAxisLabelMax: 100,//y軸最大值 middleLine: 410, //中間線 pillarWidth: 10,//柱子寬度 distanceBetween: 50,//柱狀圖繪制區域距離兩邊間隙 pillar: [120,70,700,750],//柱狀圖繪制區域 mainTrunkHeight: 90,//底部開始主干高度 dialogWidth: 300,//彈窗寬度 dialogLineHeight: 30,//彈窗高度 dialogDrawLineMax: 4,}const nodeClick = [];var chooseNode = null;const datalist={ showDataInfo: { city:[ { name: '項目1', status: 1, //狀態:0已完成 1進行中 node: [ { value: 10, date: '2020-03-12 15:50:02', content: '用于組織信息和操作,通常也作為詳細信息的入口。' }, { value: 20, date: '2020-03-12 15:50:02', content: '用于組織信息和操作,通常也作為詳細信息的入口。' }, ] }, { name: '項目2', status: 0, //狀態:0已完成 1進行中 node: [ { value: 10, date: '2020-03-12 15:50:02', content: '用于組織信息和操作,通常也作為詳細信息的入口。' }, { value: 50, date: '2020-03-12 15:50:02', content: '用于組織信息和操作,通常也作為詳細信息的入口。' }, { value: 100, date: '2020-03-12 15:50:02', content: '用于組織信息和操作,通常也作為詳細信息的入口。' }, ] }, { name: '項目3', status: 1, //狀態:0已完成 1進行中 node: [ { value: 20, date: '2020-03-12 15:50:02', content: '用于組織信息和操作,通常也作為詳細信息的入口。' }, { value: 30, date: '2020-03-12 15:50:02', content: '用于組織信息和操作,通常也作為詳細信息的入口。' }, { value: 40, date: '2020-03-12 15:50:02', content: '用于組織信息和操作,通常也作為詳細信息的入口。' }, ] }, { name: '項目4', status: 1, //狀態:0已完成 1進行中 node: [ { value: 20, date: '2020-03-12 15:50:02', content: '用于組織信息和操作,通常也作為詳細信息的入口。' }, { value: 30, date: '2020-03-12 15:50:02', content: '用于組織信息和操作,通常也作為詳細信息的入口。' }, ] }, ] }}const canvas = document.getElementById("canvas");const ctx = canvas.getContext('2d');ctx.save();drawYLabel(canvas_options,ctx); //繪制y軸坐標drawStartButton(ctx,canvas_options);drawData(ctx,datalist.showDataInfo,canvas_options);canvas.addEventListener("click",event=>{ //清除之前的彈窗 if(chooseNode!=null){ ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.save(); drawYLabel(canvas_options,ctx); //繪制y軸坐標 drawStartButton(ctx,canvas_options); drawData(ctx,datalist.showDataInfo,canvas_options); chooseNode = null } //判斷點擊節點 let rect = canvas.getBoundingClientRect(); let zoom = rect.width/canvas_options.canvasWidth; let x = (event.clientX/zoom - rect.left/zoom).toFixed(2); let y = (event.clientY/zoom - rect.top/zoom).toFixed(2); for(var t=0;t<nodeClick.length;t++){ ctx.beginPath(); ctx.arc(nodeClick[t].x,nodeClick[t].y,15,0,Math.PI*2,true); if(ctx.isPointInPath(x, y)){ textPrewrap(ctx,`備注描述:${nodeClick[t].date}`,nodeClick[t].x+20,nodeClick[t].y+20,canvas_options.dialogWidth-40); ctx.restore(); chooseNode=t break; }else{ chooseNode=null } }});//content:需要繪制的文本內容; drawX:繪制文本的x坐標; drawY:繪制文本的y坐標;//lineMaxWidth:每行文本的最大寬度function textPrewrap(ctx,content,drawX, drawY, lineMaxWidth){ var drawTxt=''; //當前繪制的內容 var drawLine = 1;//第幾行開始繪制 var drawIndex=0;//當前繪制內容的索引 //判斷內容是夠可以一行繪制完畢 if(ctx.measureText(content).width<=lineMaxWidth){ drawDialog(ctx,canvas_options.dialogWidth,canvas_options.dialogLineHeight,drawX,drawY); ctx.fillText(content.substring(drawIndex,i),drawX.drawY); }else{ for(var i=0;i<content.length;i++){ drawTxt += content[i]; if(ctx.measureText(drawTxt).width>=lineMaxWidth){ drawDialog(ctx,canvas_options.dialogWidth,canvas_options.dialogLineHeight,drawX,drawY); ctx.fillText(content.substring(drawIndex,i+1),drawX,drawY); drawIndex = i+1; drawLine+=1; //drawY+=lineHeight; drawTxt=''; }else{ //內容繪制完畢,但是剩下的內容寬度不到lineMaxWidth if(i===content.length-1){ drawDialog(ctx,canvas_options.dialogWidth,canvas_options.dialogLineHeight,drawX,drawY); ctx.fillText(content.substring(drawIndex,i+1),drawX,drawY) } } } }}function drawDialog(ctx,width,height,x,y){ ctx.beginPath(); ctx.fillStyle="rgba(0,0,0,0.8)"; ctx.fillRect(x,y,width,height); ctx.font="22px ''"; ctx.fillStyle="#fff"; ctx.textAlign = 'left'; ctx.textBaseline="top";}//繪制y軸坐標function drawYLabel(options,ctx){ let labels = options.yAxisLabel; let yLength = (options.chartZone[3]-options.chartZone[1])*0.98; let gap = yLength/(labels.length-1); labels.forEach((item,index)=>{ //繪制圓角背景 //this.radiusButton(ctx,0,options.chartZone[3]-index*gap-13,50,24,8,"#313947"); //繪制坐標文字 ctx.beginPath(); ctx.fillStyle="#878787"; ctx.font="18px ''"; ctx.textAlign="center"; ctx.fillText(item,25,options.chartZone[3]-index*gap+5); //繪制輔助線 ctx.beginPath(); ctx.strokeStyle="#eaeaea"; ctx.strokeWidth=2; ctx.moveTo(options.chartZone[0],options.chartZone[3]-index*gap); ctx.lineTo(options.chartZone[2],options.chartZone[3]-index*gap); ctx.stroke(); })}//繪制開始按鈕function drawStartButton(ctx,options){ //繪制按鈕圖形 this.radiusButton(ctx,options.middleLine-(160/2),options.canvasHeight-50,160,50,8,'#F4C63D'); ctx.fillStyle="#fff"; ctx.font="24px ''"; ctx.textAlign="center"; ctx.fillText('開始',options.middleLine,options.canvasHeight-15); //繪制狀態 ctx.beginPath(); ctx.fillStyle="#333"; ctx.font="24px ''"; ctx.textAlign = "left"; ctx.fillText("已完成",0,options.canvasHeight-100); ctx.fillText("進行中",0,options.canvasHeight-50); //繪制紅色按鈕 ctx.beginPath(); ctx.fillStyle="#d35453"; ctx.arc(options.chartZone[0]+30,options.canvasHeight-100-7,8,0,2 * Math.PI,true); ctx.fill(); ctx.beginPath(); ctx.strokeStyle="#d35453"; ctx.arc(options.chartZone[0]+30,options.canvasHeight-100-7,14,0,2 * Math.PI,true); ctx.stroke(); //繪制藍色按鈕 ctx.beginPath(); ctx.fillStyle="#24b99a"; ctx.arc(options.chartZone[0]+30,options.canvasHeight-50-8,8,0,2 * Math.PI,true); ctx.fill(); ctx.beginPath(); ctx.strokeStyle="#24b99a"; ctx.arc(options.chartZone[0]+30,options.canvasHeight-50-8,14,0,2 * Math.PI,true); ctx.stroke();}//封裝繪制圓角矩形函數function radiusButton(ctx,x,y,width,height,radius,color_back){ ctx.beginPath(); ctx.fillStyle= color_back ctx.moveTo(x,y+radius); ctx.lineTo(x,y+height-radius); ctx.quadraticCurveTo(x,y+height,x+radius,y+height); ctx.lineTo(x+width-radius,y+height); ctx.quadraticCurveTo(x+width,y+height,x+width,y+height-radius); ctx.lineTo(x+width,y+radius); ctx.quadraticCurveTo(x+width,y,x+width-radius,y); ctx.lineTo(x+radius,y); ctx.quadraticCurveTo(x,y,x,y+radius); ctx.fill()}//繪制數據function drawData(ctx,data,options){ //const paths=[]; let number = data.city.length; //繪制矩形 data.city.forEach((item,index)=>{ let indexVal = number==1?1:index; let numberVal = number==1?2:number-1 let x0 = options.chartZone[0]+options.distanceBetween+(options.chartZone[2]-options.chartZone[0]-options.distanceBetween*2)/numberVal*indexVal; let value = item.node[item.node.length-1].value; let height = (value/options.yAxisLabelMax*(options.chartZone[3]-options.chartZone[0])*0.98).toFixed(2); let y0=options.chartZone[3] - height; //柱狀圖底部 ctx.beginPath(); ctx.fillStyle= '#eee'; ctx.fillRect(x0-5,80,options.pillarWidth,options.chartZone[3]-80); //貝塞爾曲線 ctx.beginPath(); ctx.strokeStyle = item.status==0?"#d35453":'#24b99a'; ctx.lineWidth=options.pillarWidth; ctx.moveTo(options.middleLine,options.pillar[3]); //貝塞爾曲線起始點 ctx.lineTo(options.middleLine,options.canvasHeight-50-options.mainTrunkHeight); //貝塞爾曲線中間豎線 ctx.quadraticCurveTo(x0,options.canvasHeight-50-options.mainTrunkHeight,x0,options.chartZone[3]); //繪制柱狀圖進度 ctx.lineTo(x0,y0); ctx.stroke(); //繪制文字 ctx.font="28px ''"; ctx.textAlign='center'; ctx.fillStyle="#333"; ctx.fillText(item.name,x0,options.chartZone[1]-20); //繪制節點 item.node.forEach((node_item,node_index)=>{ let y1= options.chartZone[3] - (node_item.value/options.yAxisLabelMax*(options.chartZone[3]-options.chartZone[0])*0.98).toFixed(2); ctx.beginPath(); ctx.arc(x0,y1,15,0,Math.PI*2,true); ctx.fillStyle="rgba(108,212,148,1)"; ctx.fill(); ctx.beginPath(); ctx.arc(x0,y1,9,0,Math.PI*2,true); ctx.fillStyle="rgba(255,255,255,0.8)"; ctx.fill(); const pointInfo={ x:x0, y:y1, date: node_item.data, content: node_item.content, value: node_item.value }; nodeClick.push(pointInfo); }) })}

我試了下,是同心圓啊。不知道你說的放大縮小是什么操作?我代碼里width和height是相等的,_canvas直接添加到窗口里,你的是不是?

到此這篇關于canvas繪制樹形結構可視圖形的實現的文章就介紹到這了,更多相關canvas樹形結構內容請搜索真格學網以前的文章或繼續瀏覽下面的相關文章,希望大家以后多多支持真格學網!

hide(); var canvas = document.getElementById("canvas"); canvas.width = 800; canvas.height = 600; var ctx = canvas.getContext('2d'); var offcanvas =

HTML5 的標準已經出來好久了,但是似乎其中的 Canvas 現在并沒有在太多的地方用到。一個很重要的原因是,Canvas 的標準還沒有完全確定,不適合大規模用在生產環境。但是,Canvas 的優點也是很明顯的,例如在繪制含有大量元素的圖表的時候,SVG 往往因為性能問題而無法勝任,例如我見過的一次技術分享會的抽獎環節,雖然效果比較炫,但因為每個頭像都是 DOM,利用 CSS3 控制的動畫,導致了性能非常低下。此外,隨著硬件性能的提高,視頻截圖、圖像處理等功能也逐漸可以在網頁上實現了,大多數網站用的是 Flash,但是 Flash 在 Mac 電腦上性能不高,還需要學一些額外的知識。Canvas 則是直接使用 JavaScript 來進行繪圖,對 Mac 友好,所以不失為 Flash 的一個繼承者。使用 Canvas說了這么多,Canvas 究竟是個啥?英文中 Canvas 的意思是“畫布”,不過這里說的 Canvas 是 HTML5 中新出的一個元素,開發者可以在上面繪制一系列圖形。Canvas 在 HTML 文件中的寫法很簡單:<canvas id="canvas" width="寬度" height="高度"></canvas>其中 id 屬性是所有 HTML 元素都可以用的,Canvas 自帶的屬性只有后面兩個(分別控制寬度、高度),沒有其它的了。至于兼容性,CanIUse 上面寫了,基礎的功能目前用戶使用的 90% 的瀏覽器都支持,所以大部分情況下還是可以放心使用的。注意,一定要使用 Canvas 自帶的 width 和 height 屬性,不要使用 CSS 來控制,因為 CSS 控制會導致 Canvas 變形。可以試著與 PhptpShop 對比一下,后者是改變“圖像大小”,前者才是正確的改變“畫布大小”。例如下圖是三張圖片的橫向拼接:最左邊的黑框中是大小為 50px * 50px 的原圖;中間是改變了圖像大小為 100px * 100px 的效果,圖像變得模糊,但是對于圖像本身來說坐標范圍并沒有變大;最右邊才是正確的 100px * 100px 的 Canvas。Canvas 絕大部分的繪圖方法都與 <canvas> 標簽無關,需要使用 JavaScript 對其進行操作,這就是所謂的 Canvas API。我們首先獲取到這個元素:var canvas = document.getElementById('canvas');然后通過一個方法來獲取可以調用一切 Canvas API 的入口:var ctx = canvas.getContext('2d');看到 2d 是不是很激動地聯想到有沒有 3d 呢?沒有 3d 的寫法,不過如果想要開啟 3D 世界的大門,則可以寫 canvas.getContext('webgl')。然而 WebGL 是基于 OpenGL ES 2.0 的一套標準,與本文是徹徹底底的兩條路,因此這里就不討論了。Canvas 中的基本概念坐標與數學上常見的笛卡爾坐標系不太相同,Canvas 的坐標系是計算機中常見的坐標系,它長這樣:畫布的最左上角是 (0,0),往右 x 增大,往下 y 增大,而且 x 和 y 都是整數(就算在計算過程中不是整數,在繪制的時候也會當作整數處理),單位是像素。繪圖帶大家懷舊一下。不知道有多少同學小時候玩過 logo 語言,在里面你可以控制一只小海龜在一塊板子上行走、畫畫、提筆、落筆。Canvas 中也一樣,你需要控制一只畫筆的移動和繪制。然而 Canvas 更高級一些,你可以直接利用一些函數來畫圖,不用去控制那只畫筆的位置。Canvas 中的基本圖形通過上文定義的 ctx 變量可以干許多有意思的事情,我們先看看如何繪制一些基本圖形。線條我們指定畫筆移動到某一點,然后告訴畫筆需要從當前這一點畫到另一點。我們可以讓畫筆多次移動、繪制,最后統一輸出到屏幕上。例子如下:ctx.moveTo(10, 10);ctx.lineTo(150, 50);ctx.lineTo(10, 50);ctx.moveTo(10, 20);ctx.lineTo(40, 70);ctx.stroke();上面的代碼中,lineTo 是產生線條用的函數,執行完之后畫筆就移到了線條的終點。需要注意的是,線條此時并沒有顯示在屏幕上,必須調用 stroke 才會顯示。這樣設計是有道理的,因為向屏幕上輸出內容需要耗費大量的資源,我們完全可以先攢夠一波 lineTo,最后用 stroke 放一個大的。路徑繪制路徑非常簡單,只需要先告訴 ctx 一聲“我要開始畫路徑了”,然后通過各種方法(例如 lineTo)繪制路徑。如果需要畫一個封閉路徑,那就最后告訴 ctx一聲:“我畫完了,你把它封閉起來吧。”當然,不要忘記利用 stroke 輸出到屏幕上。一個簡單的例子:ctx.beginPath();ctx.moveTo(10, 10);ctx.lineTo(150, 50);ctx.lineTo(10, 50);ctx.closePath();ctx.stroke();如果我不想只描繪路徑線條,而是想填充整個路徑呢?可以將最后一行的 stroke 改成 fill,這樣就跟使用了畫圖中的油漆桶一樣,封閉路徑里面的內容就都被填充上顏色了:ctx.fill();弧 / 圓形繪制弧的函數參數比較多:ctx.arc(圓心 x 坐標, 圓心 y 坐標, 半徑, 起始角度, 終止角度, 是否為逆時針);注意,在 Canvas 的坐標系中,角的一邊是以圓心為中心的水平向右的直線。角度單位均為弧度。例如下圖,確定了圓心、起始角度(圖中標明的銳角)和終止角度(圖中標明的鈍角),方向為逆時針,于是就有了這么一個弧。如果方向為順時針,那么就會是一個跟它互補的、非常非常大的弧……所以如果轉了 2π 圈之后,弧就成了圓形,因此也可以使用繪制弧的方式來繪制圓形:ctx.beginPath();ctx.arc(圓心 x 坐標, 圓心 y 坐標, 半徑, 0, Math.PI * 2, true);ctx.closePath();最后一個參數隨便填(當然也可以不填),因為不管是順時針還是逆時針,轉了 2π 圈之后都是一個圓。矩形如果只是想繪制一個橫平豎直的矩形,可以使用下面的兩個方法:// 只描邊ctx.strokeRect(左上角 x 坐標, 左上角 y 坐標, 寬度, 高度);// 只填充ctx.fillRect(左上角 x 坐標, 左上角 y 坐標, 寬度, 高度);線條樣式 / 填充樣式之前繪制的所有圖形都是黑色的,但是 Canvas 肯定不止這么一種顏色(不然標準的制定者會被噴的很慘)。事實上,Canvas 可以單獨設置線條樣式和填充樣式,分別使用的是 strokeStyle 和 fillStyle。可能的值有三種:純色、漸變、圖像。既然線條樣式與填充樣式的使用方法相同,那么下面統一以填充樣式為例。如果想設置線條樣式,直接將所有的 fillStyle改成 strokeStyle 即可,里面的參數都不變。/* 純色填充 */// 普通的顏色ctx.fillStyle = '#0000ff';// 帶有透明度的顏色ctx.fillStyle = 'rgba(64, 0, 127, 0.5)';/* 漸變填充 */// 設置漸變的尺寸(參數分別為起始點的 x 和 y、終止點的 x 和 y)var gradient = ctx.createLinearGradient(0, 0, 170, 0);// 設置過渡色,第一個參數是漸變的位置,第二個參數是顏色gradient.addColorStop(0, 'magenta');gradient.addColorStop(0.5, 'blue');gradient.addColorStop(1.0, 'red');// 設置填充樣式ctx.fillStyle = gradient;/* 圖片填充 */// 創建圖片var image = new Image;image.src = '/path/to/image.png';// 創建圖片筆觸,可以指定圖片的平鋪方式,這里是橫向平鋪var pattern = ctx.createPattern(image, 'repeat-x');// 設置筆觸填充ctx.fillStyle = pattern;關于漸變,除了代碼中提到的線性漸變以外,還有 createRadialGradient,也就是徑向漸變。設置完填充樣式之后,就可以使用 fill 來填充啦!如果設置的是線條樣式,那么就可以使用 stroke 來描邊。當然,對于線條樣式,還有個額外的方法叫 lineWidth 可以用來控制線條的寬度。文字要想在畫布上畫文字,首先需要知道所使用的字體和字號:ctx.font = '30px Verdana';然后就可以通過 strokeText 或者 fillText 來對字體描邊或者填充字體。ctx.strokeText("Hello Coding!", 23, 33);ctx.fillText("Hello Coding!", 23, 66);圖片在 Canvas 中繪制圖片有三種方法:// 指定繪制位置ctx.drawImage(image, x, y);// 指定繪制位置和圖像寬高ctx.drawImage(image, x, y, width, height);// 指定剪裁區域、繪制位置和圖像寬高ctx.drawImage(image, sx, sy, swidth, sheight, x, y, width, height);參數的含義依次如下:image:   要使用的 Image、Canvas 或 Videosx:      可選,開始剪切的 x 坐標sy:      可選,開始剪切的 y 坐標swidth:  可選,被剪切圖像的寬度sheight: 可選,被剪切圖像的高度x:       在畫布上放置圖像的 x 坐標y:       在畫布上放置圖像的 y 坐標width:   可選,要使用的圖像的寬度height:  可選,要使用的圖像的高度畫布設置細心的同學可能會發現,剛才有些屬性是直接對 ctx 變量做設置,例如 ctx.lineWidth,只要設置了它,那么后續畫出來的線條全都是這么個寬度。其實,Canvas 的設置項還有許多,例如我們可以直接移動畫布、旋轉畫布、設置全局的繪制透明度等等。這些設置還可以隨時保存和恢復。要注意的一點是,所有已經畫在畫布上的東西,是已經定死了的,不管之后再次進行任何設置都不會再改變。這個很像 Windows 下的畫圖程序。廢話不多說,直接上代碼:// 移動畫布,其實就是移動坐標系ctx.translate(往右移動的量, 往下移動的量);// 旋轉畫布,旋轉中心為坐標系原點ctx.rotate(順時針旋轉的角度);// 以坐標系原點為中心縮放畫布ctx.scale(橫向放大倍數, 縱向放大倍數);// 設置繪制透明度,如果 fillStyle 等屬性設置了透明度則會疊加ctx.globalAlpha(零到一的小數);// 設置全局組合操作ctx.globalCompositeOperation = 'lighter';// 保存當前設置ctx.save();// 恢復上次保存的設置ctx.restore();移動、旋轉、縮放其實就是在控制繪圖的坐標系,如果你在調用這三個方法的時候,腦子里時刻有一個帶刻度的坐標系,效果會非常好。事實上,Canvas 的坐標變換遵循計算機圖形學的知識:變換矩陣。簡單來說,一個坐標可以看成是一個矩陣,坐標所對應的矩陣乘上變換矩陣就可以實現對坐標的變換。為了提升計算的效率,可以先計算出幾種變換復合之后的變換矩陣,然后直接通過 transform 函數對當前坐標系進行變換,或者通過 setTransform 函數將坐標系重置為初始狀態后再進行變換。至于變換矩陣的內容,對于本文來說就有些超綱了。全局組合操作有點像 PhotoShop 里面的“混合選項”,具體的實現方式還沒有完全確定,目前常見瀏覽器都統一了的實現方式有:source-over、source-atop、destination-over、destination-out、lighter、xor。具體的行為可以看 Mozilla 官方文檔,但是由于標準還未完全確定,因此其它瀏覽器不保證所有的行為都跟 Mozilla 的標準一致。一般來說,比較常見的是 source-over 和 lighter 兩種,這兩種的標準在瀏覽器界也算是無可爭議的。至于保存和恢復設置就有點好玩了,首先需要了解一個叫“棧”的東西。棧是一個一維數組,規定只能從一個方向操作。棧一開始是空的,我們可以從這個方向往數組 push 元素,也只能從這個方向把最后一個元素(棧頂元素)pop 出來,除此以外沒有任何多余的操作。當然,pop 的次數不能多于 push 的次數,因為 pop 到棧底的時候棧里就已經沒有元素了,此時再 pop 是沒有意義的。棧的用處有很多,例如括號匹配、表達式求值、深度優先搜索,甚至絕大部分語言的函數調用都要用到棧。每次我們調用 save 函數,實際上是將當前的全局設置 push 到了一個專門棧上,每次調用 restore 函數的時候將最后一次保存的內容 pop 出來并用它覆蓋當前的全局設置,這樣棧頂就是最近一次保存的內容了。保存和恢復在某些情況下很好用,例如我需要畫一個歪著的圖形,然后繼續畫正著的圖形,這樣就可以先調用 save,然后調用 rotate,畫完圖形之后再 restore 回來,繼續畫其它的圖形。其實 Canvas 還有許多方法,例如 toDataURL 直接將當前畫布上的內容轉換為十六進制的 data-url,getImageData直接將圖像轉換為 RGBA 數組以供圖像處理算法使用,putImageData 將 RGBA 數組轉換為圖片顯示在畫布上等等。如果配上 JavaScript 的定時更新(最好用 requestAnimationFrame 而不是 setInterval),則可以產生動畫效果。網上還有許多 Canvas 的庫,可以讓程序員更簡便地基于 Canvas 編寫屬于自己的特效或功能。在這兒我想說一句話:大家的腦洞有多大,Canvas 的能力就有多強~內容來自www.13333515.buzz請勿采集。


  • 本文相關:
  • html5利用canvas繪畫二級樹形結構圖的示例
  • 什么是canvas以及使用canvas繪制圖形的步驟
  • 如何在html5的canvas繪制地圖
  • 如何利用Tkinter中Canvas繪制曲線圖,請教高手
  • 使用canvas繪制圖形時,使用什么方法可以在當前屬性中填入邊...
  • 熱力圖是由svg還是canvas繪制
  • 如何使用echart中獲取canvas繪制到自己的canvas上去
  • wpf 在canvas繪制圓,怎么繪制出的圓不同心,在放大后可以明顯...
  • 如何使用echart中獲取canvas繪制到自己的canvas上去
  • canvas繪制圖線后,無法旋轉,求助
  • 怎樣使用canvas繪制一個矩形
  • 怎么設置html5中canvas繪制一個圖形所需的時間
  • Html5 用canvas繪制圖片,繪制不出來。
  • 如何獲取SurfaceView中Canvas繪制出的圖片
  • android中,如何用canvas繪制透明?
  • 如何使用HTML5中canvas繪制一個立體金字塔圖形?(javascript...
  • js+html5實現canvas繪制橢圓形圖案的方法
  • 如何使用Canvas繪制drawText旋轉角度
  • 如何在html5的canvas繪制地圖
  • Firefox 下用 Canvas 繪制 GIF 動畫圖只能顯示1幀畫面如何才能...
  • 網站首頁網頁制作腳本下載服務器操作系統網站運營平面設計媒體動畫電腦基礎硬件教程網絡安全主頁網頁制作html5canvashtml5利用canvas繪畫二級樹形結構圖的示例html/xhtmlhtml5cssxml/xsltdreamweaver教程frontpage教程心得技巧css 如何讓背景圖片拉伸填充避免重復顯示html5 input placeholder 顏色修改示例基于第一個phonegap(cordova)的應用詳解 html5配合css3實現帶提示文字的輸入框(擺脫js)html5定位獲取當前位置并在百度地圖上顯示將html5 canvas的內容保存為圖片借助todataurl實現html5中如何顯示視頻呢 html5視頻播放demo讓ie支持html5的方法微信瀏覽器取消緩存的方法html5的存儲方式sessionstorage和localstorage詳解基于html5+tracking.js實現刷臉支付功能html中meta標簽及keywords詳解移動端h5頁面根據屏幕適配的四種方案html5移動端自適應布局的實現html里顯示pdf、word、xls、ppt的方法示例html5 直播瘋狂點贊動畫實現代碼 附源碼html5手指下滑彈出負一屏阻止移動端瀏覽器內置下拉刷canvas 基礎之圖像處理的使用用canvas顯示驗證碼的實現html5給漢字加拼音收起展開組件的實現代碼
    免責聲明 - 關于我們 - 聯系我們 - 廣告聯系 - 友情鏈接 - 幫助中心 - 頻道導航
    Copyright © 2017 www.13333515.buzz All Rights Reserved
    3排列五开奖结果