前言:今天在github上看到了一個定義水印的項目,由於獲取的星星還蠻多,就多看了幾眼,發現該項目簡單有趣,心想之後可能會用的到,而且我下載到本地並親自測試運行了一波。其實該項目最吸引個人是它定義js方法的方式(其實我看過不少項目都是這樣定義js方法的,由於他們的項目太大,分析太過於複雜。這個項目讓我有了一個切入點)。下面我就把該項目的分析過程與你們分享一下。html
由於對js,canvan不是太熟悉,故添加了註釋已幫助理解和記憶node
!function (root, factory) { // root=window factory=方法(能夠理解爲工廠方法) if (typeof module === 'object' && module.exports) { // 實際上是作的兼容處理(使用方式的兼容處理即js模塊開發) module.exports = factory(root); // nodejs support module.exports['default'] = module.exports; // es6 support } else root.alimask = factory(root); // 咱們用到的代碼 }(typeof window !== 'undefined' ? window : this, function () { var canvas, ctx; // merge the default value function mergeOptions(options) { //合併默認參數和可選參數 return Object.assign({ width: 200, height: 70, color: '#ebebeb', alpha: 0.8, font: '50px Arial' }, options); } return function(text, options) { if (!canvas || !ctx) { // if not exist, then initial if (typeof document !== 'undefined') { canvas = document.createElement('canvas'); } else { var Canvas = module.require('canvas'); canvas = new Canvas(); } ctx = canvas && canvas.getContext && canvas.getContext('2d'); if (!canvas || !ctx) return ''; // if not exist also, then return blank. } options = mergeOptions(options); var width = options.width, height = options.height; canvas.width = width; canvas.height = height; ctx.clearRect(0, 0, width, height); // clear the canvas ctx.globalAlpha = 0; // backgroud is alpha // ctx.fillStyle = 'white'; // no need because of alipha = 0; ctx.fillRect(0, 0, width, height); ctx.globalAlpha= options.alpha; // text alpha 透明度 ctx.fillStyle = options.color; ctx.font = options.font; ctx.textAlign = 'left'; ctx.textBaseline = 'bottom'; ctx.translate(width * 0.1, height * 0.9); // margin: 10 ctx.rotate(-Math.PI / 12); // 15 degree 圖片傾斜角度 ctx.fillText(text, 0, 0); return canvas.toDataURL(); //生成圖片URl }; });
源碼的簡化結構git
!function (root, factory) { // root=window factory=方法(能夠理解爲工廠方法) root.method //暴露的屬性或方法(該js暴露是方法) *****經過root對象暴露全局 你能夠理解爲全局屬性****** }(arg1, function () { // 1.arg1=window()由於window是單例對象並暴露全局2.arg2=function() ******隱藏做用域即閉包 全局的子做用域(對對全局隱藏)******* function f1(options) { //該方法 作到可隱藏 即只讀方法 (只能在該做用域或子做用域中訪問到 該做用域對全局做用域隱藏) } return function(text, options) { // 參數2 ******提供對隱藏域的訪問接口******* //調用方法f1 f1(); var obj = new **(); return obj; } });
分析:經過定義當即執行帶參數的當即執行函數來隱藏方法(參數2)和方法f1es6
原理就是js閉包,相關文章可參考http://www.javashuo.com/article/p-dpyrvtln-em.htmlgithub
備註: 合併兩個對象的屬性方法 canvas
Object.assign(obj1,obj2) //以obj1爲主,當obj2中有相同的屬性時,obj1的屬性值被覆蓋。當obj2中的屬性obj1沒有時,obj1添加該屬性和值
利用該方法實現了,可選參數和默認參數的機制。
參考地址:https://github.com/hustcc/alimask