1/* @preserve 2 * Project: jQuery plugin Watermark 3 * Description: Add watermark on images use HTML5 and Javascript. 4 * Author: Zzbaivong (devs.forumvi.com) 5 * Version: 0.2 6 * License: MIT 7 */ 8 9/* 10 * jquery-boilerplate - v3.4.0 11 * A jump-start for jQuery plugins development. 12 * http://jqueryboilerplate.com 13 * 14 * Made by Zeno Rocha 15 * Under MIT License 16 */ 17;(function ($, window, document, undefined) { 18 19 'use strict'; 20 21 var pluginName = 'watermark', 22 defaults = { 23 path: 'watermark.png', 24 25 text: '', 26 textWidth: 130, 27 textSize: 13, 28 textColor: 'white', 29 textBg: 'rgba(0, 0, 0, 0.4)', 30 31 gravity: 'se', // nw | n | ne | w | e | sw | s | se 32 opacity: 0.7, 33 margin: 10, 34 35 outputWidth: 'auto', 36 outputHeight: 'auto', 37 outputType: 'jpeg', // jpeg | png | webp 38 39 done: function (imgURL) { 40 this.src = imgURL; 41 }, 42 fail: function ( /*imgURL*/ ) { 43 // console.error(imgURL, 'image error!'); 44 }, 45 always: function ( /*imgURL*/ ) { 46 // console.log(imgURL, 'image URL!'); 47 } 48 }; 49 50 function Plugin(element, options) { 51 this.element = element; 52 this.settings = $.extend({}, defaults, options); 53 this._defaults = defaults; 54 this._name = pluginName; 55 this.init(); 56 } 57 58 $.extend(Plugin.prototype, { 59 init: function () { 60 61 var _this = this, 62 ele = _this.element, 63 set = _this.settings, 64 65 wmData = { 66 imgurl: set.path, 67 type: 'png', 68 cross: true 69 }, 70 71 imageData = { 72 imgurl: ele.src, 73 cross: true, 74 type: set.outputType, 75 width: set.outputWidth, 76 height: set.outputHeight 77 }; 78 79 // Watermark dạng base64 80 if (set.path.search(/data:image\/(png|jpg|jpeg|gif);base64,/) === 0) { 81 wmData.cross = false; 82 } 83 84 // Ảnh Äang duyá»t dạng base64 85 if (ele.src.search(/data:image\/(png|jpg|jpeg|gif);base64,/) === 0) { 86 imageData.cross = false; 87 } 88 89 var defer = $.Deferred(); 90 91 $.when(defer).done(function (imgObj) { 92 imageData.wmObj = imgObj; 93 _this.imgurltodata(imageData, function (dataURL) { 94 set.done.call(ele, dataURL); 95 set.always.call(ele, dataURL); 96 }); 97 }); 98 99 if (set.text !== '') { 100 wmData.imgurl = _this.textwatermark(); 101 wmData.cross = false; 102 } 103 104 _this.imgurltodata(wmData, function (imgObj) { 105 defer.resolve(imgObj); 106 }); 107 }, 108 109 /** 110 * Chuyá»n text sang ảnh Äá» là m watermark 111 * @returns {String} URL ảnh dạng base64 112 */ 113 textwatermark: function () { 114 var _this = this, 115 set = _this.settings, 116 117 canvas = document.createElement('CANVAS'), 118 ctx = canvas.getContext('2d'), 119 120 w = set.textWidth, 121 h = set.textSize + 8; 122 123 canvas.width = w; 124 canvas.height = h; 125 126 ctx.fillStyle = set.textBg; 127 ctx.fillRect(0, 0, w, h); 128 129 ctx.fillStyle = set.textColor; 130 ctx.textAlign = 'center'; 131 ctx.font = '500 ' + set.textSize + 'px Sans-serif'; 132 133 ctx.fillText(set.text, (w / 2), (set.textSize + 2)); 134 135 return canvas.toDataURL(); 136 }, 137 138 /** 139 * Chuyá»n ảnh sang dạng base64 140 * @param {Object} data Các thông sá» thiết láºp Äá» phân biá»t loại ảnh và vá»i watermark 141 * @param {String} callback URL ảnh dạng base64 142 */ 143 imgurltodata: function (data, callback) { 144 145 var _this = this, 146 set = _this.settings, 147 ele = _this.element; 148 149 var img = new Image(); 150 151 if (data.cross) { 152 img.crossOrigin = 'Anonymous'; 153 } 154 155 img.onload = function () { 156 var canvas = document.createElement('CANVAS'); 157 var ctx = canvas.getContext('2d'); 158 159 var w = this.width, // image height 160 h = this.height, // image width 161 ctxH; 162 163 if (data.wmObj) { 164 165 if (data.width !== 'auto' && data.height === 'auto' && data.width < w) { 166 h = h / w * data.width; 167 w = data.width; 168 } else if (data.width === 'auto' && data.height !== 'auto' && data.height < h) { 169 w = w / h * data.height; 170 h = data.height; 171 } else if (data.width !== 'auto' && data.height !== 'auto' && data.width < w && data.height < h) { 172 w = data.width; 173 h = data.height; 174 } 175 176 } 177 178 // Xoay dá»c watermark sá» dụng text, khi á» vá» trà giữa mép dá»c 179 if ((set.gravity === 'w' || set.gravity === 'e') && !data.wmObj) { 180 canvas.width = h; 181 canvas.height = w; 182 ctxH = -h; 183 ctx.rotate(90 * Math.PI / 180); 184 } else { 185 canvas.width = w; 186 canvas.height = h; 187 ctxH = 0; 188 } 189 190 // Tô ná»n trắng cho ảnh xuất ra dạng jpeg 191 if (data.type === 'jpeg') { 192 ctx.fillStyle = '#ffffff'; 193 ctx.fillRect(0, 0, w, h); 194 } 195 196 ctx.drawImage(this, 0, ctxH, w, h); 197
198 // Xá» lý watermark ÄÆ°á»£c chèn và o 199 if (data.wmObj) { 200 201 // Äá» trong suá»t 202 var op = set.opacity; 203 if (op > 0 && op < 1) { 204 ctx.globalAlpha = set.opacity; 205 } 206 207 // Vá» trà chèn, gá»i theo hưá»ng trên bản Äá» 208 var wmW = data.wmObj.width, 209 wmH = data.wmObj.height, 210 pos = set.margin, 211 gLeft, gTop; 212 213 switch (set.gravity) { // nw | n | ne | w | e | sw | s | se 214 case 'nw': // Tây bắc 215 gLeft = pos; 216 gTop = pos; 217 break; 218 case 'n': // Bắc 219 gLeft = w / 2 - wmW / 2; 220 gTop = pos; 221 break; 222 case 'ne': // Äông Bắc 223 gLeft = w - wmW - pos; 224 gTop = pos; 225 break; 226 case 'w': // Tây 227 gLeft = pos; 228 gTop = h / 2 - wmH / 2; 229 break; 230 case 'e': // Äông 231 gLeft = w - wmW - pos; 232 gTop = h / 2 - wmH / 2; 233 break; 234 case 'sw': // Tây Nam 235 gLeft = pos; 236 gTop = h - wmH - pos; 237 break; 238 case 's': // Nam 239 gLeft = w / 2 - wmW / 2; 240 gTop = h - wmH - pos; 241 break; 242 default: // Äông Nam 243 gLeft = w - wmW - pos; 244 gTop = h - wmH - pos; 245 } 246 ctx.drawImage(data.wmObj, gLeft, gTop, wmW, wmH); 247 } 248 249 // Xuất ra url ảnh dạng base64 250 var dataURL = canvas.toDataURL('image/' + data.type); 251 252 if (typeof callback === 'function') { 253 254 if (data.wmObj) { // Äã có watermark 255 callback(dataURL); 256 257 } else { // watermark 258 var wmNew = new Image(); 259 wmNew.src = dataURL; 260 callback(wmNew); 261 } 262 } 263 264 canvas = null; 265 }; 266 267 // Xá» lý ảnh tải lá»i hoặc có thá» do từ chá»i CORS headers 268 img.onerror = function () { 269 set.fail.call(this, this.src); 270 set.always.call(ele, this.src); 271 return false; 272 }; 273 274 img.src = data.imgurl; 275 } 276 }); 277 278 $.fn[pluginName] = function (options) { 279 return this.each(function () { 280 if (!$.data(this, 'plugin_' + pluginName)) { 281 $.data(this, 'plugin_' + pluginName, new Plugin(this, options)); 282 } 283 }); 284 }; 285 286}(jQuery, window, document));
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.