PageSourceSearch

https://www.toolpic.com/app/editor/libs/vintage.js

js toolpic.com collected 2026-10-02 10:53:19 UTC 6,288 bytes, 200 lines download raw bytes

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.