1/* global fx, ImageFilters, canvas_active */ 2 3var VINTAGE = new VINTAGE_CLASS(); 4 5/** 6 * adds vintage effect 7 * 8 * @author toolpic.com 9 * 10 * Functions: 11 * - adjust_color 12 * - lower_contrast 13 * - blur 14 * - light_leak 15 * - chemicals 16 * - exposure 17 * - grains 18 * - grains_big 19 * - optics 20 * - dusts 21 * 22 * Usage: VINTAGE.___function___(canvas_ctx, width, height, param1, param2, ...); 23 * 24 * libs: 25 * - imagefilters.js, url: https://github.com/arahaya/ImageFilters.js 26 * - glfx.js url: http://evanw.github.com/glfx.js/ 27 */ 28function VINTAGE_CLASS() { 29 var fx_filter = false; 30 31 //increasing red color 32 this.adjust_color = function (context, W, H, level_red) { //level = [0, 200], default 70 33 var param_green = 0; 34 var param_blue = 0; 35 var imageData = context.getImageData(0, 0, W, H); 36 var filtered = ImageFilters.ColorTransformFilter(imageData, 1, 1, 1, 1, level_red, param_green, param_blue, 1); 37 context.putImageData(filtered, 0, 0); 38 }; 39 40 //decreasing contrast 41 this.lower_contrast = function (context, W, H, level) { //level = [0, 50], default 15 42 var imageData = context.getImageData(0, 0, W, H); 43 var filtered = ImageFilters.BrightnessContrastPhotoshop(imageData, 0, -level); 44 context.putImageData(filtered, 0, 0); 45 }; 46 47 //adding blur 48 this.blur = function (context, W, H, level) { //level = [0, 2], default 0 49 if (level < 1) 50 return context; 51 var imageData = context.getImageData(0, 0, W, H); 52 var filtered = ImageFilters.GaussianBlur(imageData, level); 53 context.putImageData(filtered, 0, 0); 54 }; 55 56 //creating transparent #ffa500 radial gradients 57 this.light_leak = function (context, W, H, level) { //level = [0, 150], default 90 58 var click_x = this.getRandomInt(0, W); 59 var click_y = this.getRandomInt(0, H); 60 var distance = Math.min(W, H) * 0.6; 61 var radgrad = canvas_active().createRadialGradient( 62 click_x, click_y, distance * level / 255, 63 click_x, click_y, distance); 64 radgrad.addColorStop(0, "rgba(255, 165, 0, " + level / 255 + ")"); 65 radgrad.addColorStop(1, "rgba(255, 255, 255, 0)"); 66 67 context.fillStyle = radgrad; 68 context.fillRect(0, 0, W, H); 69 }; 70 71 //de-saturate 72 this.chemicals = function (context, W, H, level) { //level = [0, 100], default 40 73 var imageData = context.getImageData(0, 0, W, H); 74 var filtered = ImageFilters.HSLAdjustment(imageData, 0, -level, 0); 75 context.putImageData(filtered, 0, 0); 76 }; 77 78 //creating transparent vertical black-to-white gradients 79 this.exposure = function (context, W, H, level) { //level = [0, 150], default 80 80 context.rect(0, 0, W, H); 81 var grd = canvas_active().createLinearGradient(0, 0, 0, H); 82 if (this.getRandomInt(1, 10) < 5) { 83 //dark at top 84 grd.addColorStop(0, "rgba(0, 0, 0, " + level / 255 + ")"); 85 grd.addColorStop(1, "rgba(255, 255, 255, " + level / 255 + ")"); 86 } 87 else { 88 //bright at top 89 grd.addColorStop(0, "rgba(255, 255, 255, " + level / 255 + ")"); 90 grd.addColorStop(1, "rgba(0, 0, 0, " + level / 255 + ")"); 91 } 92 context.fillStyle = grd; 93 context.fill(); 94 }; 95 96 //add grains, noise 97 this.grains = function (context, W, H, level) { //level = [0, 50], default 10 98 if (level == 0) 99 return context; 100 var img = context.getImageData(0, 0, W, H); 101 var imgData = img.data; 102 for (var j = 0; j < H; j++) { 103 for (var i = 0; i < W; i++) { 104 var x = (i + j * W) * 4; 105 if (imgData[x + 3] == 0) 106 continue; //transparent 107 //increase it's lightness 108 var delta = this.getRandomInt(0, level); 109 if (delta == 0) 110 continue; 111 112 if (imgData[x] - delta < 0) 113 imgData[x] = -(imgData[x] - delta); 114 else 115 imgData[x] = imgData[x] - delta; 116 if (imgData[x + 1] - delta < 0) 117 imgData[x + 1] = -(imgData[x + 1] - delta); 118 else 119 imgData[x + 1] = imgData[x + 1] - delta; 120 if (imgData[x + 2] - delta < 0) 121 imgData[x + 2] = -(imgData[x + 2] - delta); 122 else 123 imgData[x + 2] = imgData[x + 2] - delta; 124 } 125 } 126 context.putImageData(img, 0, 0); 127 }; 128 129 //add big grains, noise 130 this.grains_big = function (context, W, H, level) { //level = [0, 50], default 20 131 if (level == 0) 132 return context; 133 var n = W * H / 100 * level; //density 134 var color = 200; 135 for (var i = 0; i < n; i++) { 136 var power = this.getRandomInt(5, 10 + level); 137 var size = 2; 138 var x = this.getRandomInt(0, W); 139 var y = this.getRandomInt(0, H); 140 context.fillStyle = "rgba(" + color + ", " + color + ", " + color + ", " + power / 255 + ")"; 141 context.fillRect(x, y, size, size); 142 } 143 }; 144
145 //adding vignette effect - blured dark borders 146 this.optics = function (context, W, H, param1, param2) { //param1 [0, 0.5], param2 [0, 0.7], default 0.3, 0.5 147 //make sure FX lib loaded 148 if(fx_filter == false){ 149 fx_filter = fx.canvas(); 150 } 151 152 var texture = fx_filter.texture(context.getImageData(0, 0, W, H)); 153 fx_filter.draw(texture).vignette(param1, param2).update(); 154 context.drawImage(fx_filter, 0, 0); 155 }; 156 157 //add dust and hairs 158 this.dusts = function (context, W, H, level) { //level = [0, 100], default 70 159 var n = level / 100 * (W * H) / 1000; 160 //add dust 161 context.fillStyle = "rgba(200, 200, 200, 0.3)"; 162 for (var i = 0; i < n; i++) { 163 var x = this.getRandomInt(0, W); 164 var y = this.getRandomInt(0, H); 165 var mode = this.getRandomInt(1, 2); 166 if (mode == 1) { 167 var w = 1; 168 var h = this.getRandomInt(1, 3); 169 } 170 else if (mode == 2) { 171 var w = this.getRandomInt(1, 3); 172 var h = 1; 173 } 174 context.beginPath(); 175 context.rect(x, y, w, h); 176 context.fill(); 177 } 178 179 //add hairs 180 context.strokeStyle = "rgba(200, 200, 200, 0.2)"; 181 for (var i = 0; i < n / 3; i++) { 182 var x = this.getRandomInt(0, W); 183 var y = this.getRandomInt(0, H); 184 var radius = this.getRandomInt(5, 15); 185 var start_nr = this.getRandomInt(0, 20) / 10; 186 var start_angle = Math.PI * start_nr; 187 var end_angle = Math.PI * (start_nr + this.getRandomInt(7, 15) / 10); 188 context.beginPath(); 189 context.arc(x, y, radius, start_angle, end_angle); 190 context.stroke(); 191 } 192 193 return context; 194 }; 195 196 //random number generator 197 this.getRandomInt = function (min, max) { 198 return Math.floor(Math.random() * (max - min + 1)) + min; 199 }; 200}
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.