您好,登錄后才能下訂單哦!
今天小編給大家分享一下如何用html制作一個動畫網頁的相關知識點,內容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。
html5新增的canvas無疑是一個非常出彩的設計。網頁由此只需要引入一個html元素(正是),即可進行圖形繪制。相應地,flash動畫是網頁中一直以來很常見的內容,它的特色也是矢量圖形繪制。因此,很容易聯想到,是不是也可以用canvas來制作動畫。
canvas并不像flash那樣是被設計為做動畫的。但是,通過一定的方法,確實可以使用canvas制作出flash那樣的圖形動畫,而且效果同樣很棒。
動畫的原理
動畫的原理相信很多人也聽說過,就是把繪制好的多張靜態圖,以一定的頻率,按照一定的順序依次切換顯示,即形成動態的畫面。當頻率高于一定數值后,人眼就察覺不出切換的過程,這時也就形成了連貫的動畫。同時,在同一場景(也稱為分鏡)中,相鄰的靜態圖只會有微小差異,由此通過相當數量的靜態圖的組合創建過渡(一般稱為動畫分格),使畫面平滑自然。
在動畫中,每一張靜態圖對應的靜態畫面,稱為幀。靜態畫面的切換頻率,則稱為幀頻。在flash的時間軸面板中,可以很容易找到它們。
canvas動畫的實現
圖形繪制
使用canvas繪圖的做法是:先在html中加入元素。
然后,獲取這個元素對應的context(可以稱為繪圖上下文)。
var drawing=document.getElementById("drawing");
if (drawing.getContext) {
var context=drawing.getContext("2d");
}
這里的變量context表示的繪圖上下文,是canvas圖形繪制的核心,它有一系列的繪圖屬性和繪圖方法。簡單地說,所有的繪圖都是操作這個context實現。
動畫中的圖形
canvas的context有一個clearRect()方法,可以清除畫布上的某一矩形區域內的所有圖形。聯系前文所述的動畫的原理,可以知道,如果以某一頻率不斷地先清除,再繪制,而且每一次繪制的內容稍有不同,就可以看到變化的圖形,形成動畫。
如何讓每一次繪制的內容稍有不同呢?對此,較為合理的做法是,為需要繪制的圖形,創建類,每一個類對應一種圖形。任意一種圖形,都有自己的一些屬性,而且有一個屬性指向canvas的繪圖上下文。同時,圖形類都定義了一個繪圖方法draw()(這只是我用的命名,可以自定),這個繪圖方法draw()包含了一系列代碼,依次做以下兩件事:依照當前的屬性值(或者叫狀態)操作繪圖上下文把自己繪制在canvas畫布上,以及更新當前屬性值。
比如,下面是可以移動的球體(其實就是圓)的類的定義:
// 類定義,球體
var Ball=function(config, context) {
this.x=config.x; // X坐標
this.y=config.y; // Y坐標
this.color=config.color; // 例如rgba(0,0,0,1)
this.radius=config.radius; // 半徑
this.speedX=config.speedX; // 水平方向速度
this.speedY=config.speedY; // 垂直方向速度
this.context=context; // 獲取context的引用
};
Ball.prototype.move=function() {
this.x +=this.speedX;
this.y +=this.speedY;
};
Ball.prototype.draw=function() {
// 繪圖
var context=this.context;
context.fillStyle=this.color;
context.beginPath();
context.arc(this.x, this.y, this.radius, 0, Math.PI * 2, true);
context.fill();
// 移動,更新位置
this.move();
};
可以看出,每一次調用這個類的draw()方法,都會把這個圖形繪制上去。而每一次draw()的調用,也會更新實例的屬性值,從而使下一次繪制的時候,圖形有所不同(這里的示例是位置的移動)。
舞臺
在畫布中以動畫形式展現的圖形,應該有一個元素對它們做管理。參考flash中的動畫結構,這個元素就是舞臺。因此,建立一個舞臺類(Stage)。Stage類的定義是:
var Stage=function(config, context) {
this.stageWidth=config.stageWidth; // 舞臺寬
this.stageHeight=config.stageHeight; // 舞臺高
this.playFlag=false; // 播放標識,初始為false
this.childs={}; // 存放舞臺中的元素
this.context=context; // 保存context的引用
};
Stage.prototype={
constructor: Stage,
// 添加舞臺元素
addChild: function(name, elem) {
this.childs[name]=elem;
},
// 移除舞臺元素
removeChild: function(name) {
delete this.childs[name];
},
// 渲染,繪制每一幀的舞臺中有的所有圖形
render: function() {
this.context.clearRect(0, 0, this.stageWidth, this.stageHeight); // 清除上一幀繪制的圖形
var childs=this.childs;
for (var i in childs) {
childs[i].draw(); // 調用舞臺中的所有圖形的draw()方法
}
if (this.playFlag) {
requestAnimationFrame((function(thisReplace) {
return function() {
thisReplace.render(); // 循環調用
};
})(this));
}
},
// 播放
play: function() {
if (!this.playFlag) {
this.playFlag=true;
this.render();
}
},
// 停止
stop: function() {
if (this.playFlag) {
this.playFlag=false;
}
}
};
在這段定義中,Stage類的render()方法最為重要。render()調用時,首先清除上一幀,然后通過一個循環,調用了舞臺中的所有圖形的draw()方法,從而完成當前幀的繪圖,并且更新了所有圖形的屬性值,由此確定了下一幀的所有圖形的狀態。然后通過一個對自身的循環調用,實現連續的逐幀繪制。這樣,動畫就產生了。
連續逐幀繪制是需要參照一個頻率的,一般會想到的就是使用setTimeout()和setInterval()。但是,現代瀏覽器考慮到動畫實現的需要,專門為此提供了一個API,就是requestAnimationFrame()。這個方法在不同瀏覽器下的寫法不同,因此應該使用一個跨瀏覽器的動畫運行控制函數:(來源于Paul Irish的requestAnimationFrame for Smart Animating)
if (!window.requestAnimationFrame) {
window.requestAnimationFrame=(function() {
return window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(callback, element) {
window.setTimeout(callback, 1000 / 60);
};
})();
}
至于為什么應該使用requestAnimationFrame(),請看基于腳本的動畫的計時控制。簡單的表述理由的話,就是“我們更專業”(——?——)。
動畫過程
在有了前面的類定義后,實現動畫的方法就很明晰了。首先創建舞臺和動畫圖形的實例,然后把動畫圖形實例通過舞臺的addChild()方法添加進去,然后調用舞臺的play()方法。這部分對應的代碼示例:
// 假定stageConfig, ballConfig已有適當定義,context也已獲得繪圖上下文引用
var stage=new Stage(stageConfig, context),
ball=new Ball(ballConfig.context);
stage.addChild("ball", ball); // 添加到舞臺(顯示)
stage.play(); // 動畫播放
這樣,canvas元素就開始了連貫的動態繪制,也就是能看到的動畫了。
以上就是“如何用html制作一個動畫網頁”這篇文章的所有內容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。