首先,仍是謝謝你們的支持,謝謝!記得在以前的文章中我說過本身算是一個半文藝程序員,也一直想着寫一寫技術性和其餘偏文學性的文章。雖然本身的底子沒有多麼優秀,但老是以爲這個過程當中能夠督促本身去思考,督促本身去學習和交流。畢竟天天忙忙碌碌之餘,仍是要活出本身不同的生活。
其次,我開通了我的的 GitHub主頁 ,裏面有本身的技術文章,還會有我的的隨想、思考和日誌。之後全部的文章都會第一時間更新到這裏,而後同步到其餘平臺。有喜歡的朋友能夠沒事去逛逛,再次感謝你們的支持!html
官網介紹 ( 中文):CreateJS 是一組模塊化代碼庫和工具套件,能夠獨立工做也能夠組合工做,用於經過HTML5技術來在網頁上開發豐富的交互式內容。
CreateJS主要包含以下四個類庫:git
EaselJS
– 簡化處理HTML5畫布(核心)TweenJS
– 用來幫助設計H5動畫,調整HTML5屬性SoundJS
– 用來簡化處理HTML5 audio 音頻PreloadJS
– 幫助管理和協調加載中的一些資源今天,主要來了解一下 EaselJS
庫程序員
EaselJS
是一個JavaScript庫,用來簡單快捷的操做HTML5 Canvas
標籤。在建立H5遊戲,生成藝術做品、處理其餘高級圖形化等工做中有着很友好的體驗。
Stage Class
-- 建立舞臺Text Class
-- 繪製文字Graphics Class
-- 繪製圖形Shape Class
-- 繪製圖形Bitmap Class
-- 繪製圖片Ticker Class
-- 定時廣播定義一個<canvas> </canvas>
畫布。github
// HTML: <!-- Text Class 文本類--> <canvas id="demo1" width="650" height="400"></canvas>
調用EaselJS
提供的API - new createjs.Text()
,繪製文字web
// JS <script src="https://code.createjs.com/1.0.0/createjs.min.js"></script> <script> window.onload = () => { /** * Test Class 文本類 -- demo */ let stage1 = new createjs.Stage("demo1"); let text1 = new createjs.Text("Text 1 !", "bold 26px Arial", "#ff7700"); text1.regX = -50; // 沿X軸負方向的偏移量 text1.regY = -50; // 沿Y軸負方向的偏移量 text1.x = 100; // 繪製源點 X座標 text1.y = 50; // 繪製源點 Y座標 let text2 = new createjs.Text("旋轉+XY拉伸!", "bold 18px Arial", "#ff7700"); text2.x = 50; text2.y = 50; text2.rotation = 50; // 旋轉角度 DEG text2.scaleX = 3; // X軸放大(拉伸) text2.scaleY = 2; // X軸放大(拉伸) let text3 = new createjs.Text("XY軸傾斜", "bold 50px Arial", "#ff7700"); text3.x = 300; text3.y = 200; text3.skewX = 45; // X軸傾斜角度 DEG text3.skewY = 20; // Y周傾斜角度 DEG let text4 = new createjs.Text("文字shadow", "bold 30px Arial", "#ff7700"); text4.x = 400; text4.y = 100; text4.shadow = new createjs.Shadow("#000000", 5, 5, 10); // 建立一個shadow實例Object stage1.addChild(text1, text2, text3, text4); stage1.update(); // 更新舞臺,每次修改操做後須要更新真個舞臺纔有效果 } </script>
定義一個<canvas> </canvas>
畫布。canvas
// HTML: <!-- Graphics Class 文本類--> <canvas id="demo2" width="650" height="400"></canvas>
調用EaselJS
提供的API - new createjs.Graphics()
,繪製圖形緩存
// JS <script src="https://code.createjs.com/1.0.0/createjs.min.js"></script> <script> window.onload = () => { /** * Graphics Class 繪圖類 -- demo * 用於生成矢量繪圖指令 */ let stage2 = new createjs.Stage('demo2') // 畫線 let g = new createjs.Graphics(); /* 同一個 Graphics 實例, 能夠屢次繪製,如下線段、折線都是用 g 實例繪製的*/ g.setStrokeStyle(10).beginStroke("#d23c4f").moveTo(400,10).lineTo(600,100) // 簡寫形式 g.ss(20).s('#fafa35').mt(400,100).lt(400,260) // 多點折線的簡寫形式 g.ss(1).s('#000').mt(600,400).lt(600, 200).lt(400,300).lt(500, 550) // Graphics 實例不能直接 addChild() 到舞臺 stage 中,實例化爲 Shape 實例後才能夠 let line = new createjs.Shape(g) // 圓 let g1 = new createjs.Graphics(); g1.setStrokeStyle(1); // 描邊 g1.beginStroke("#000000"); // 描邊顏色 g1.beginFill("red"); // 圖形填充 g1.drawCircle(0,0,100); // 繪製 (X, X, R) let c1 = new createjs.Shape(g1) // 實例化Shape對象 // 矩形 let g2 = new createjs.Graphics().beginStroke("red").beginFill("blue").drawRect(150, 0, 200, 100); // X, Y, W, H let c2 = new createjs.Shape(g2) // 命令對象 let g3 = new createjs.Graphics(); // 每一個圖形接口調用後會生成一個命令對象,可使用.command訪問,它保存對已建立或附加的最後一個命令的引用 let fillCommand = g3.beginFill("green").command; g3.drawCircle(200,200,50); // 繪製 (X, X, R) let c3 = new createjs.Shape(g3); // 一些異步操做後,更新填充樣式/顏色: setTimeout(() => { fillCommand.style = "gray"; stage2.update(); // 不更新舞臺,不會從新渲染 }, 2000); // 點擊事件 //c3.addEventListener('click', () => { // alert(123) // fillCommand.style = "gray"; // stage2.update(); // 不更新舞臺,不會從新渲染 //}) stage2.addChild(c1, c2, c3, line); stage2.update(); } </script>
定義一個<canvas> </canvas>
畫布。dom
// HTML: <!-- Bitmap Class 圖像類--> <canvas id="demo3" width="650" height="400"></canvas>
調用EaselJS
提供的API - new createjs.Bitmap()
,繪製圖像異步
// JS <script src="https://code.createjs.com/1.0.0/createjs.min.js"></script> <script> window.onload = () => { /** * bitmap Class 圖像類 * 用於在畫布顯示列表中渲染圖像 */ let stage3 = new createjs.Stage('demo3') // 渲染圖片 let bitmap = new createjs.Bitmap('./assets/img/hill1.png') bitmap.alpha = 0.6 // 透明度 bitmap.cursor = 'help' // 建立一個shadow實例Object(color, offsetX, offsetY, blur) bitmap.shadow = new createjs.Shadow("#97c89e", 20, 10, 20); // 給圖片添加遮罩 let bitmap2 = new createjs.Bitmap('./assets/img/avatar.jpg') bitmap2.x = 400; // 圖片繪製的起始點X座標 bitmap2.y = 0; // 圖片繪製的起始點Y座標 //遮罩圖形 let shape = new createjs.Shape(); shape.graphics.beginFill('#000').drawCircle(0, 0, 100); shape.x = 500; // 圓心X座標 shape.y = 100; // 圓心Y座標 bitmap2.mask = shape; //給圖片bg添加遮罩 // 繪製一片草地 let groundBg = new createjs.Bitmap("./assets/img/ground.png").image; let ground = new createjs.Shape(); w = stage3.canvas.width; // 650 h = stage3.canvas.height; // 400 stage3.addChild(ground) stage3.addChild(bitmap, bitmap2) stage3.update() // 此處刷新無效 // 監聽定時廣播 createjs.Ticker.timingMode = createjs.Ticker.RAF; createjs.Ticker.addEventListener('tick',(event) => { ground.tileW = groundBg.width; ground.y = h - groundBg.height; ground.graphics.beginBitmapFill(groundBg).drawRect(0, 0, w, groundBg.height); ground.cache(0, 0, w, groundBg.height); stage3.update() }); } </script>
<canvas></canvas>
畫布<!-- HTML --> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>running-man game</title> </head> <body> <canvas id="demoCanvas" width="960" height="400"></canvas> </body> </html>
這裏就不寫具體思路分析了,代碼不長,註釋也很詳細,方便理解,直接上代碼。模塊化
// JS <script src="https://code.createjs.com/1.0.0/createjs.min.js"></script> <script> window.onload = () => { let stage, w, h, loader; let sky, grant, ground, hill, hill2; function init() { stage = new createjs.StageGL("demoCanvas"); // 獲取畫布的寬和高,後面計算使用 w = stage.canvas.width; // 960 h = stage.canvas.height; // 400 // 定義靜態資源 let manifest = [{ src: "spritesheet_grant.png", id: "grant"}, { // 人物動做雪碧圖 src: "sky.png", id: "sky"}, { // 天空 src: "ground.png", id: "ground"}, { // 地面 src: "hill1.png", id: "hill"}, { // 遠山 src: "hill2.png", id: "hill2" // 近山 }]; // Array, String, Object // 建立資源加載隊列 // (Boolean) 用XHR仍是用HTML標籤來加載 // 若是是false的時候,就用標籤來加載,若是不能用標籤的話,就用XHR來加載。默認是true,用XHR來加載。 loader = new createjs.LoadQueue(false); // 添加"資源加載完成"事件 loader.addEventListener("complete", handleComplete); // 加載資源 loader.loadManifest(manifest, true, "./assets/img/"); // (manifest, loadNow, basePath) } /** * 靜態資源加載完成,處理函數 */ function handleComplete() { // 渲染天空 sky = new createjs.Shape(); sky.graphics.beginBitmapFill(loader.getResult("sky")).drawRect(0, 0, w, h); // 定義緩存區域(整個天空的區域)) sky.cache(0, 0, w, h); // 渲染地面 let groundImg = loader.getResult("ground"); ground = new createjs.Shape(); // 注意:drawRect()寬度要躲繪製一個單位 ground.graphics.beginBitmapFill(groundImg).drawRect(0, 0, w + groundImg.width, groundImg.height); ground.tileW = groundImg.width; ground.y = h - groundImg.height; // 緩存區域(地面的區域) ground.cache(0, 0, w + groundImg.width, groundImg.height); // 隨機渲染遠處山脈 hill = new createjs.Bitmap(loader.getResult("hill")); // 設置圖像轉換 // setTransform([x=0], [y=0], [scaleX=1], [scaleY=1], [rotation=0], [skewX=0], [skewY=0], [regX=0], [regY=0]) hill.setTransform(Math.random() * w, h - hill.image.height * 4 - groundImg.height, 4, 4); hill.alpha = 0.5; // 設置透明度 // 隨機渲染近處山脈 hill2 = new createjs.Bitmap(loader.getResult("hill2")); hill2.setTransform(Math.random() * w, h - hill2.image.height * 3 - groundImg.height, 3, 3); // 建立雪碧圖動畫 let spriteSheet = new createjs.SpriteSheet({ framerate: 30, // 幀率 FPS "images": [loader.getResult("grant")], // 雪碧圖原圖 "frames": {"width": 165, "height": 292, "count": 64, "regX": 82, "regY": 0}, // 初始化 // 定義動畫 "animations": { "run": [0, 25, "run"], // name: [開始索引, 結束索引, '下一個動畫名稱', 倍率] "jump": [26, 63, "run"] } }); // 繪製動畫 grant = new createjs.Sprite(spriteSheet, "run"); // 處理雪碧圖人物下方空白 grant.y = 35; // 將生成的全部內容渲染至舞臺 stage.addChild(sky, ground, hill, hill2, grant); // 監聽舞臺上的鼠標點擊事件 stage.addEventListener("stagemousedown", () => { // 跳轉播放 jump 動畫 grant.gotoAndPlay("jump"); }); createjs.Ticker.timingMode = createjs.Ticker.RAF; // RAF / RAF_SYNCHED / TIMEOUT createjs.Ticker.addEventListener("tick", tick); } /** * 定時器-重繪舞臺 */ function tick(event) { // event.delta -- 上一次tick到當前tick的ms let deltaS = event.delta / 1000; // 雪碧圖人物移動距離 let position = grant.x + 150 * deltaS; // getBounds() -- 返回當前幀相對於雪碧圖原點的邊界 let grantW = grant.getBounds().width * grant.scaleX; grant.x = (position >= w + grantW) ? -grantW : position; ground.x = (ground.x - deltaS * 150) % ground.tileW; // 從右至左移動山脈 hill.x = (hill.x - deltaS * 30); // 若是山脈從左側離開屏幕 if (hill.x + hill.image.width * hill.scaleX <= 0) { hill.x = w; // 重置回屏幕最右側 } // 處理如上 hill2.x = (hill2.x - deltaS * 45); if (hill2.x + hill2.image.width * hill2.scaleX <= 0) { hill2.x = w; } stage.update(); } // 程序主入口-初始化 init() } </script>
示例demo的GitHub地址: 完整代碼