溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

創(chuàng)造運(yùn)用淺談canvas的設(shè)計(jì)藝術(shù)

發(fā)布時(shí)間:2020-06-13 09:59:06 來源:網(wǎng)絡(luò) 閱讀:235 作者:陰陽光 欄目:web開發(fā)

創(chuàng)造運(yùn)用淺談canvas的設(shè)計(jì)藝術(shù)

知道<canvas>嗎?如果你不熟悉<canvas>,學(xué)習(xí)他的最好方法是去看一個(gè)簡單的例子。下面的HTML和JavaScript將在<canvas>域內(nèi)生成一個(gè)橙色的矩形區(qū)域。推薦學(xué)習(xí)相關(guān)HTML高級教程

<canvas id="example1" width="400" height="300"></canvas>
// get the canvasvar canvas = document.getElementById('example1');// 
get the "2d" contextvar context = canvas.getContext('2d');//
 change fill style to orangecontext.fillStyle = '#ff7700';// 
draw an orange rectanglecontext.fillRect(0, 0, 400, 300);
你總是通過找到web文檔中的元素,然后選擇“context”開始canvas繪畫。在本例中, context是2 d, 因?yàn)槲覀兿胗胏anvas 畫二維形狀。選擇一個(gè)context之后,canvas API包含了很多有用的繪圖功能,如填充樣式,形狀,中風(fēng),陰影,和大量的其他特性,允許我們給 圖片做出奇特的改變。我們的編寫的腳本的結(jié)果看起來是 這樣的 。
<canvas>的偉大之處就是它是一個(gè)JavaScript  API,這意味著我們可以利用所有的JavaScript變量,事件,循環(huán) 等等的特點(diǎn)。讓我們應(yīng)用我們的腳本使用一個(gè)簡單的JavaScript循環(huán)在我們的canvas區(qū)域創(chuàng)建一個(gè)網(wǎng)格的小區(qū)域。
<canvas id="example2" width="400" height="300"></canvas>
// get the canvas and contextvar canvas = document.getElementById('example2');
var context = canvas.getContext('2d');// orange fill stylecontext.fillStyle = '#ff7700';// 
create squares in a loopfor(var x = 0; x < canvas.width; x += 25){  for(var y = 0; y 
< canvas.height; y += 25){    context.fillRect(x, y, 20, 20);  }}
短短幾行JavaScript, 在我們的canvas區(qū)域能夠產(chǎn)生192個(gè)方塊。在我看來,這是<canvas>的真正價(jià)值。它允許我們利用web瀏覽器的處理能力來生成數(shù)學(xué)幾何和圖紙。再加上一點(diǎn)工作和大量的創(chuàng)造力,我們甚至可以利用這種力量的實(shí)現(xiàn) 藝術(shù)效果。
動(dòng)畫

在我們繼續(xù)這個(gè)話題之前,我們需要了解如何使用<canvas>創(chuàng)建一個(gè)動(dòng)畫。這是一個(gè)有點(diǎn)更難做的事情。首先,請理解,以阻礙web瀏覽器 性能的方式使用canvas API是很容易的。在canvas上繪畫是需要處理器密集型的工作,特別是如果你不斷更新動(dòng)畫之類的圖紙。緩解任何性能問 題,我將使用一個(gè)新功能叫做requestAnimationFrame,允許我們的web瀏覽器來決定更新canvas的頻率, 同時(shí)在我們的web文 檔保持最佳性能。這不是在所有瀏覽器都可用的, 但幸運(yùn)的是保羅愛爾蘭曾寫過一個(gè)出色的poly-fill將此功能添加到舊版本的web瀏覽器。他在他的博客寫下了這個(gè)腳本和web瀏覽器這個(gè)的特性。

為了簡便起見,我不打算在我的代碼示例中包含保羅的腳本,但是你應(yīng)該在自己的代碼中使用它。使用requestAnimationFrame,我們可以在我們的腳本中創(chuàng)建一個(gè)基本的“動(dòng)畫循環(huán)”。它看上去是 這樣的
<canvas id="example3" width="400" height="300"></canvas>
// get the canvasvar canvas = document.getElementById('example3');var context = 
canvas.getContext('2d');context.fillStyle = '#ff7700';var time = false;//
 box positionvar x = -100;// animation loopvar loop = function(){  // 
get time since last frame  var now = new Date().getTime();  
var d = now - (time || now);  time = now;   // clear previously 
drawn rectangles  context.clearRect(0, 0, canvas.width, canvas.height); 
 // draw new rectangle  context.fillRect(x, 100, 100, 100); 
 // advance horizontal position  x += 0.1 * d;
  // reset horizontal position  if(x > canvas.width){    x = -100;  }    //
 request next frame  requestAnimationFrame(loop);};// first frameloop();
當(dāng)在canvas元素中使用動(dòng)畫, 所有繪畫應(yīng)由一個(gè)可重復(fù)的函數(shù)完成。在示例中,使用loop()函數(shù)在我們的canvas上畫一個(gè)正方形。 requestAnimationFrame函數(shù)基于可用的處理能力告訴瀏覽器時(shí)自動(dòng)選擇什么時(shí)候繪制下一個(gè)框架,結(jié)果是我們的loop()函數(shù)一遍又一 遍的運(yùn)行, 從左到右推進(jìn)我們的橙色盒子前進(jìn)。請注意,我們使用d變量(delta)來確定幀之間的時(shí)間,以毫秒為單位。這是使我們的動(dòng)畫速度正常的一個(gè) 重要的增加項(xiàng)。沒有它,我們的動(dòng)畫在有好一點(diǎn)的處理器的計(jì)算機(jī)上會跑的更快,幾年后當(dāng)電腦獲得更多的處理能力,我們的動(dòng)畫可以跑的更快之快,以至于混淆或 誤導(dǎo)用戶。使用delta變量,我們可以每毫秒指定一個(gè)速度。在我們的示例中, 方塊的位置每毫秒前進(jìn)0.1 * d,或0.1像素,轉(zhuǎn)化后即為每秒 100像素。無論您的處理器的速度是多少, 動(dòng)畫總是花同樣多的時(shí)間完成。
藝術(shù)元素
既然我們了解canvas元素以及如何使用它創(chuàng)建動(dòng)畫,我們可以在這些基礎(chǔ)上加上一些藝術(shù)創(chuàng)造力來創(chuàng)造更有意思的東西。在下一個(gè)示例中,我們將在canvas元素中隨機(jī)生成彩色圓圈并且和給他們隨機(jī)軌跡。通過使用漸變畫圓圈而不是純色,我們的“北極光”腳本變得生動(dòng)起來。
<canvas id="example4" width="400" height="300" ></canvas>
// get the canvasvar canvas = document.getElementById('example4');var context = 
canvas.getContext('2d');var time = false;// create an empty array of "circles"var circles 
= [];// animation loopvar loop = function(){  // get time since last frame  var now = new Date().getTime();  
var d = now - (time || now);  time = now;  // clear the canvas  context.clearRect(0, 0, canvas.width,
 canvas.height);  // draw circles  for(var i = 0; i < circles.length; i++){    
circles[i].update(d);    circles[i].draw();  }  // request next frame  requestAnimationFrame(loop);};// 
circle objectvar circle = function(options){  // configuration  var circle = this;  circle.settings = 
{    x: 0,    y: 0,    radius: 20,    orientation: 0, 
   vector: { x: 0, y: 0 },    speed: 1,    color: { red: 0, green: 0, blue: 0, alpha: 1 }  }; 
 // merge options into settings  var newsettings = {};  
for(var attrname in circle.settings){ newsettings[attrname] 
= circle.settings[attrname]; }  for(var attrname in options){ newsettings[attrname] = options[attrname]; }  
circle.settings = newsettings;  // update circle  circle.update = function(d){    // update position  
  circle.settings.x += circle.settings.vector.x * circle.settings.speed * d;   
 circle.settings.y += circle.settings.vector.y * circle.settings.speed * d;    // bounce  
  if(circle.settings.x < 0 && circle.settings.vector.x < 0 || circle.settings.x >
 canvas.width && circle.settings.vector.x > 0){     

 circle.settings.vector.x = circle.settings.vector.x * -1;    }  

 

if(circle.settings.y < 0 && circle.settings.vector.y < 0 || circle.settings.y > 
canvas.height && circle.settings.vector.y > 0){      
circle.settings.vector.y = circle.settings.vector.y * -1; 
   }  };  // draw circle  circle.draw = function(){    // gradient fill    var gradient =
 context.createRadialGradient(circle.settings.x, circle.settings.y, 
circle.settings.radius / 10, circle.settings.x, circle.settings.y, circle.settings.radius);  
  gradient.addColorStop(0, 'rgba(' + circle.settings.color.red + ', ' + circle.settings.color.green
 + ', ' + circle.settings.color.blue + ', ' + circle.settings.color.alpha + ')');    
gradient.addColorStop(1, 'rgba(' + circle.settings.color.red + ', ' + circle.settings.color.green 
+ ', ' + circle.settings.color.blue + ', ' + circle.settings.color.alpha / 50 + ')');   
 context.fillStyle = gradient;     // draw    context.beginPath();    
context.arc(circle.settings.x, circle.settings.y, circle.settings.radius, 0, 2 * Math.PI, false);  
  context.fill();   };};// create new circlesvar newcircles = function(){  // remove old circles  circles 
= [];    // create 5 new circles  for(var i = 0; i < 5; i++){    // create a new circle    
var newcircle = new circle({      x: Math.floor(Math.random() * canvas.width),  
    y: Math.floor(Math.random() * canvas.height),     
 radius: Math.floor(Math.random() * canvas.width),    
  orientation: Math.floor(Math.random() * 360),     
 vector: {        x: Math.random() / 40,   
     y: Math.random() / 40      },      speed: Math.random(),   
   color: {      
  red: 100 + Math.floor(Math.random() * 155),        
green: 100 + Math.floor(Math.random() * 155),    
    blue: 100 + Math.floor(Math.random() * 155),       
 alpha: 0.1 + Math.random()      }    });   
     // add new circle to circles array    
circles.push(newcircle);     
}};// generate new circleswindow.addEventListener('click', newcircles, false);
window.addEventListener

('touchend', newcircles, false);newcircles();// first frameloop();

在這個(gè)窗口每次單擊,新的隨機(jī)圓圈將會出現(xiàn)。
我們才剛剛開始理解和利用<canvas>的力量。我渴望了解這個(gè)行業(yè)如何采用它以及SVG等技術(shù)構(gòu)建驚奇和藝術(shù)的web內(nèi)容。在我的下一篇 文章中,我將展示如何采用此代碼使用鍵盤快捷鍵和動(dòng)畫來創(chuàng)建一個(gè)簡單的基于canvas的游戲,讓你可以在web瀏覽器中玩這種游戲。還有更多HTML教程視頻供你學(xué)習(xí)沒請登錄e良師益友網(wǎng)。


向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI