前言:今天在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自定义水印的更多相关文章

  1. js自定义验证码

    分享一个js自定义的验证码 window.onload = function () {     var code;     $('.changePassword').click(function () ...

  2. js自定义弹出框

    js自定义弹出框: 代码如下 <html> <head><title>自定义弹出对话框</title> <style type ="te ...

  3. 超酷HTML5 Canvas图表应用Chart.js自定义提示折线图

    超酷HTML5 Canvas图表应用Chart.js自定义提示折线图 效果预览 实例代码 <div class="htmleaf-container"> <div ...

  4. 与你相遇好幸运,Sails.js自定义responses

    在 /api/responses/ 新建文件 >serviceDBError.js 自定义的数据库错误 >serviceError.js  自定义的数据错误 >serviceSucc ...

  5. jquery.validate.js默认配置,jquery.validate.js自定义提示信息

    jquery.validate.js默认配置,jquery.validate.js自定义提示信息 配置jQuery.validator默认的处理方法 >>>>>>& ...

  6. web前端对上传的文件进行类型大小判断的js自定义函数

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  7. js自定义事件、DOM/伪DOM自定义事件

    一.说明.引言 我JS还是比较薄弱的,本文的内容属于边学边想边折腾的碎碎念,可能没什么条理,可能有表述不准确的地方,可能内容比较拗口生僻.如果您时间紧迫,或者JS造诣已深,至此您就可以点击右侧广告(木 ...

  8. Vue.js自定义指令的用法与实例

    市面上大多数关于Vue.js自定义指令的文章都在讲语法,很少讲实际的应用场景和用例,以致于即便明白了怎么写,也不知道怎么用.本文不讲语法,就讲自定义指令的用法. 自定义指令是用来操作DOM的.尽管Vu ...

  9. 3.Node.js 自定义微信菜单

    文章目录:         1.Node.js 接入微信公众平台开发         2.Node.js access_token的获取.存储及更新         3.Node.js 自定义微信菜单 ...

随机推荐

  1. vue中提示$index is not defined

    今天学习Vue中遇到了一个报错信息:$index is not defined,是我写了个for循环在HTML中,然后是因为版本的问题 下面是解决方法: 原来的是 v-for="person ...

  2. Koa源码分析(三) -- middleware机制的实现

    Abstract 本系列是关于Koa框架的文章,目前关注版本是Koa v1.主要分为以下几个方面: Koa源码分析(一) -- generator Koa源码分析(二) -- co的实现 Koa源码分 ...

  3. wzyxidian Scanner 与 Readable 的read()方法

    Readable接口中的read()方法实现了将字符串读入charBuffer中,但是只有在需要输出的时候才会调用. Scanner是文本扫描器类,利用Scanner扫描并输出charBuffer中的 ...

  4. JAVA获取微信小程序openid和获取公众号openid,以及通过openid获取用户信息

    一,首先说明下这个微信的openid 为了识别用户,每个用户针对每个公众号会产生一个安全的OpenID,如果需要在多公众号.移动应用之间做用户共通,则需前往微信开放平台,将这些公众号和应用绑定到一个开 ...

  5. A Senior Interview

    1.How many time did they spent to plan the final project? 答:两天左右,两次开会. 4.How many time did they spen ...

  6. python中split()和split(' ')的区别

    用split(" ")测试: s1 = "we are family"#中间一个空格 s2 = "we are family"#中间两个空格 ...

  7. Oracle 12c 安装问题及解决方案

    1. 介绍 今天在我的开发电脑上安装Oracle12c,电脑环境是windows10家庭中文版,安装的Oracle数据库版本Oracle(12.1.0.2.0) - Standard Edition ...

  8. shell脚本学习-循环

    跟着RUNOOB网站的教程学习的笔记 for循环 与其他编程语言类似,shell支持for循环. for循环一般格式为: for var in item1 item2 ... itemN do com ...

  9. 中触发一个断点 其原因可能是堆被损坏,这说明 ***.exe 中或它所加载的任何 DLL 中有 Bug

    软件中使用了DevComponents.DotNetBar2.dll MessageBoxEx.Show("ddd");运行到这句出现这个错误 : 中触发一个断点 其原因可能是堆被 ...

  10. c#项目减少源代码大小

    这次的代码缩减主要通过了这几个方面 1.bin和obj文件的删除(以前真的不知道,只是通过右键属性发现这些文件太大,然后上网搜索才知道,这些文件在源代码备份的时候是建议删掉的) 删掉的好处: 1.减少 ...