前言:今天在github上看到了一个定义水印的项目,因为获取的星星还蛮多,就多看了几眼,发现该项目简单有趣,心想以后可能会用的到,并且我下载到本地并亲自测试运行了一波。其实该项目最吸引我的是它定义js方法的方式(其实我看过很多项目都是这样定义js方法的,因为他们的项目太大,分析太过于复杂。这个项目让我有了一个切入点)。下面我就把该项目的分析过程与大家分享一下。
一:源码
因为对js,canvan不是太熟悉,故添加了注释已帮助理解和记忆
!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 ?};});
二 :源码结构分析
源码的简化结构
!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)和方法f1
原理就是js闭包,相关文章可参考https://www.cnblogs.com/jinliang374003909/p/10352464.html
备注: 合并两个对象的属性方法
????Object.assign(obj1,obj2) //以obj1为主,当obj2中有相同的属性时,obj1的属性值被覆盖。当obj2中的属性obj1没有时,obj1添加该属性和值
????利用该方法实现了,可选参数和默认参数的机制。 ??
参考地址:https://github.com/hustcc/alimask
js自定义水印
原文地址:https://www.cnblogs.com/jinliang374003909/p/10601000.html