diva.js 6.0.2 → 7.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. package/.clang-format +7 -0
  2. package/.github/workflows/npm-publish.yml +45 -0
  3. package/LICENSE +55 -0
  4. package/Makefile +75 -0
  5. package/README.md +15 -114
  6. package/elm.json +32 -0
  7. package/package.json +12 -59
  8. package/review/elm.json +52 -0
  9. package/review/src/ReviewConfig.elm +87 -0
  10. package/scripts/elm-esm.sh +40 -0
  11. package/scripts/minify-css.mjs +31 -0
  12. package/src/Filters.elm +1044 -0
  13. package/src/Main.elm +1217 -0
  14. package/src/Model.elm +213 -0
  15. package/src/Msg.elm +59 -0
  16. package/src/Utilities.elm +46 -0
  17. package/src/View/CollectionExplorer.elm +172 -0
  18. package/src/View/Helpers.elm +86 -0
  19. package/src/View/HtmlRenderer.elm +136 -0
  20. package/src/View/Icons.elm +159 -0
  21. package/src/View/ManifestInfoModal.elm +363 -0
  22. package/src/View/PageViewModal.elm +1046 -0
  23. package/src/View/Sidebar.elm +786 -0
  24. package/src/View/Toolbar.elm +189 -0
  25. package/src/View.elm +244 -0
  26. package/src/diva.ts +802 -0
  27. package/src/filters.ts +1843 -0
  28. package/src/styles/app.css +328 -0
  29. package/src/styles/collection.css +75 -0
  30. package/src/styles/modal.css +388 -0
  31. package/src/styles/sidebar.css +215 -0
  32. package/src/styles/theme.css +39 -0
  33. package/src/styles/toolbar.css +154 -0
  34. package/src/viewer-element.ts +1307 -0
  35. package/testing/index.html +52 -0
  36. package/testing/testing.html +231 -0
  37. package/tsconfig.json +12 -0
  38. package/AUTHORS +0 -22
  39. package/build/diva.css +0 -554
  40. package/build/diva.css.map +0 -1
  41. package/build/diva.js +0 -9
  42. package/build/diva.js.map +0 -1
  43. package/build/plugins/download.js +0 -2
  44. package/build/plugins/download.js.map +0 -1
  45. package/build/plugins/manipulation.js +0 -2
  46. package/build/plugins/manipulation.js.map +0 -1
  47. package/build/plugins/metadata.js +0 -2
  48. package/build/plugins/metadata.js.map +0 -1
  49. package/index.html +0 -28
  50. package/karma.conf.js +0 -87
  51. package/source/css/_mixins.scss +0 -43
  52. package/source/css/_variables.scss +0 -50
  53. package/source/css/_viewer.scss +0 -462
  54. package/source/css/diva.scss +0 -15
  55. package/source/css/plugins/_manipulation.scss +0 -228
  56. package/source/css/plugins/_metadata.scss +0 -31
  57. package/source/img/adjust.svg +0 -11
  58. package/source/img/book-view.svg +0 -6
  59. package/source/img/close.svg +0 -6
  60. package/source/img/download.svg +0 -6
  61. package/source/img/from-fullscreen.svg +0 -8
  62. package/source/img/grid-fewer.svg +0 -6
  63. package/source/img/grid-more.svg +0 -6
  64. package/source/img/grid-view.svg +0 -6
  65. package/source/img/link.svg +0 -6
  66. package/source/img/metadata.svg +0 -9
  67. package/source/img/page-view.svg +0 -6
  68. package/source/img/to-fullscreen.svg +0 -11
  69. package/source/img/zoom-in.svg +0 -6
  70. package/source/img/zoom-out.svg +0 -7
  71. package/source/js/composite-image.js +0 -174
  72. package/source/js/diva-global.js +0 -7
  73. package/source/js/diva.js +0 -1543
  74. package/source/js/document-handler.js +0 -180
  75. package/source/js/document-layout.js +0 -286
  76. package/source/js/exceptions.js +0 -26
  77. package/source/js/gesture-events.js +0 -190
  78. package/source/js/grid-handler.js +0 -122
  79. package/source/js/iiif-source-adapter.js +0 -63
  80. package/source/js/image-cache.js +0 -113
  81. package/source/js/image-manifest.js +0 -157
  82. package/source/js/image-request-handler.js +0 -76
  83. package/source/js/interpolate-animation.js +0 -122
  84. package/source/js/page-layouts/book-layout.js +0 -161
  85. package/source/js/page-layouts/grid-layout.js +0 -97
  86. package/source/js/page-layouts/index.js +0 -38
  87. package/source/js/page-layouts/page-dimensions.js +0 -9
  88. package/source/js/page-layouts/singles-layout.js +0 -27
  89. package/source/js/page-overlay-manager.js +0 -102
  90. package/source/js/page-tools-overlay.js +0 -95
  91. package/source/js/parse-iiif-manifest.js +0 -302
  92. package/source/js/plugins/_filters.js +0 -679
  93. package/source/js/plugins/download.js +0 -83
  94. package/source/js/plugins/manipulation.js +0 -837
  95. package/source/js/plugins/metadata.js +0 -190
  96. package/source/js/renderer.js +0 -584
  97. package/source/js/settings-view.js +0 -30
  98. package/source/js/tile-coverage-map.js +0 -25
  99. package/source/js/toolbar.js +0 -573
  100. package/source/js/utils/dragscroll.js +0 -106
  101. package/source/js/utils/elt.js +0 -94
  102. package/source/js/utils/events.js +0 -190
  103. package/source/js/utils/get-scrollbar-width.js +0 -29
  104. package/source/js/utils/hash-params.js +0 -86
  105. package/source/js/utils/parse-label-value.js +0 -34
  106. package/source/js/utils/vanilla.kinetic.js +0 -527
  107. package/source/js/validation-runner.js +0 -177
  108. package/source/js/viewer-core.js +0 -1514
  109. package/source/js/viewport.js +0 -143
  110. package/test/_setup.js +0 -13
  111. package/test/composite-image_test.js +0 -94
  112. package/test/diva_test.js +0 -43
  113. package/test/hash-params_test.js +0 -221
  114. package/test/image-cache_test.js +0 -106
  115. package/test/main.js +0 -6
  116. package/test/manifests/beromunsterManifest.json +0 -15514
  117. package/test/manifests/iiifv2.json +0 -11032
  118. package/test/manifests/iiifv2pages.json +0 -30437
  119. package/test/manifests/iiifv3.json +0 -10965
  120. package/test/navigation_test.js +0 -355
  121. package/test/parse-iiif-manifest_test.js +0 -68
  122. package/test/public_test.js +0 -881
  123. package/test/settings_test.js +0 -487
  124. package/test/utils/book-layout_test.js +0 -148
  125. package/test/utils/elt_test.js +0 -102
  126. package/test/utils/events_test.js +0 -245
  127. package/test/utils/hash-params_test.js +0 -79
  128. package/test/utils/parse-label-value_test.js +0 -45
  129. package/test/z_plugins_test.js +0 -180
  130. package/webpack.config.js +0 -58
  131. package/webpack.config.test.js +0 -45
@@ -1,679 +0,0 @@
1
-
2
- // stores an array of objects, each object stores the function, image data, adjust to apply, and name
3
- let _filterQueue = [];
4
- // stores whether the invert filter was used (for if it should be reapplied)
5
- let inverted = false;
6
-
7
- export function resetFilters ()
8
- {
9
- _filterQueue = [];
10
- inverted = false;
11
- }
12
-
13
- // Add a filter to the array. If it is new, apply the filter's function to the image data of
14
- // the previous filter's returned image data (or the default image data if it's the first filter),
15
- // and return this new image data. Pass string 'name' since function.name with minifiedJS = bad
16
- // Threshold is exclusive to other filters and vice versa
17
- export function addFilterToQueue (data, filter, adjust, name)
18
- {
19
- // index of the filter in the queue, -1 if not found
20
- let index = _filterQueue.findIndex(f => f.filter.name === filter.name);
21
- if (index !== -1) // adjust a filter already in the queue
22
- {
23
- let filtObj = _filterQueue[index];
24
- filtObj.adjust = adjust;
25
-
26
- // all filters except sharpness use _apply (from within their private function 'filter')
27
- // whereas sharpness uses convolve, so need to check (ie. can't generalize for all filters)
28
- if (filtObj.name === 'Sharpness')
29
- {
30
- // if adjust[1] is 0, then sharpness should be reset (cancelled)
31
- if (filtObj.adjust[1] === 0)
32
- filtObj.postData = filtObj.prevData;
33
- else
34
- filtObj.postData = convolve(filtObj.prevData, filtObj.adjust);
35
- }
36
- else if (filtObj.name === 'Invert')
37
- {
38
- // invert filter should toggle, so use post-alteration image data
39
- filtObj.postData = _apply(filtObj.postData, filtObj.filter, filtObj.adjust);
40
- inverted = !inverted;
41
- }
42
- else
43
- filtObj.postData = _apply(filtObj.prevData, filtObj.filter, filtObj.adjust);
44
-
45
- // reapply all filters that come after in the queue
46
- for (let i = index + 1, len = _filterQueue.length; i < len; i++)
47
- {
48
- let otherFiltObj = _filterQueue[i];
49
-
50
- if (otherFiltObj.name === 'Invert' && !inverted) // don't reinvert the image
51
- continue;
52
-
53
- otherFiltObj.prevData = _filterQueue[i - 1].postData; // starts at filt
54
-
55
- if (otherFiltObj.name === 'Sharpness')
56
- if (otherFiltObj.adjust[1] === 0)
57
- otherFiltObj.postData = otherFiltObj.prevData;
58
- else
59
- otherFiltObj.postData = convolve(otherFiltObj.prevData, otherFiltObj.adjust);
60
- else
61
- otherFiltObj.postData = _apply(otherFiltObj.prevData, otherFiltObj.filter, otherFiltObj.adjust);
62
-
63
- if (i === len - 1) // last filter
64
- return otherFiltObj.postData;
65
- }
66
-
67
- // only two filters in queue and second was modified
68
- return filtObj.postData;
69
- }
70
- else // add new filter to the queue
71
- {
72
- // handle threshold uniqueness
73
- if (name === 'Threshold' || (_filterQueue[0] && _filterQueue[0].name === 'Threshold'))
74
- {
75
- // reset filter queue
76
- resetFilters();
77
-
78
- // reset appropriate sliders
79
- let tools = document.getElementsByClassName('manipulation-tools')[0];
80
- for (let i = 0, len = tools.children.length; i < len; i++)
81
- {
82
- let tool = tools.children[i].children[0];
83
-
84
- if (tool && tool.type === 'range')
85
- {
86
- let isThreshold = tool.parentElement.textContent.includes('Threshold');
87
- let isZoom = tool.parentElement.textContent.includes('Zoom');
88
- let isRotate = tool.parentElement.textContent.includes('Rotation');
89
-
90
- if (name === 'Threshold' && !isThreshold && !isZoom && !isRotate) // reset all except
91
- tool.value = 0;
92
- else if (name !== 'Threshold' && isThreshold) // reset only threshold
93
- tool.value = 0;
94
- }
95
- }
96
-
97
- // reset log
98
- document.getElementById('filter-log').innerHTML = "<h3> Filter Application Order <h3>";
99
- }
100
-
101
- _filterQueue.push({
102
- filter: filter,
103
- prevData: _filterQueue.length === 0 ? data : _filterQueue[_filterQueue.length - 1].postData,
104
- adjust: adjust,
105
- name: name
106
- });
107
-
108
- let filtObj = _filterQueue[_filterQueue.length - 1];
109
-
110
- if (filtObj.name === 'Sharpness')
111
- filtObj.postData = convolve(filtObj.prevData, filtObj.adjust);
112
- else
113
- filtObj.postData = _apply(filtObj.prevData, filtObj.filter, filtObj.adjust);
114
-
115
- // invert filter was added to queue
116
- if (filtObj.name === 'Invert')
117
- inverted = true;
118
-
119
- // add name to applied filters log
120
- let p = document.createElement('p');
121
- p.setAttribute('style', 'color: white; margin: 0;');
122
- p.innerText = filtObj.name;
123
- document.getElementById('filter-log').appendChild(p);
124
-
125
- return filtObj.postData;
126
- }
127
- }
128
-
129
- /**
130
- * Pre-paints the adjustment to an offscreen canvas before moving it to the on-screen canvas.
131
- **/
132
- function _getOffscreenCanvasData (w, h)
133
- {
134
- let tmpCanvas = document.createElement('canvas');
135
- let tmpCtx = tmpCanvas.getContext('2d');
136
-
137
- return tmpCtx.createImageData(w, h);
138
- }
139
-
140
- function _manipulateImage (data, func, adjustment)
141
- {
142
- let len = data.length;
143
-
144
- for (let i = 0; i < len; i += 4)
145
- {
146
- let r = data[i];
147
- let g = data[i + 1];
148
- let b = data[i + 2];
149
-
150
- let newPixelValue = func(r, g, b, adjustment);
151
-
152
- data[i] = newPixelValue[0];
153
- data[i + 1] = newPixelValue[1];
154
- data[i + 2] = newPixelValue[2];
155
- data[i + 3] = newPixelValue[3];
156
- }
157
-
158
- return data;
159
- }
160
-
161
- function _apply (data, pixelFunc, adjust)
162
- {
163
- let dataArr = new Uint8ClampedArray(data.data);
164
- let inverted = _manipulateImage(dataArr, pixelFunc, adjust);
165
-
166
- let newCanvasData = _getOffscreenCanvasData(data.width, data.height);
167
- newCanvasData.data.set(inverted);
168
-
169
- return newCanvasData;
170
- }
171
-
172
- /**
173
- * Inverts the colours of a canvas.
174
- *
175
- * @params {object} data - A canvas image data object.
176
- * @returns {object} A new canvas data object.
177
- **/
178
- export function grayscale(data)
179
- {
180
- return addFilterToQueue(data, _grayscale, null, 'Grayscale');
181
- }
182
-
183
- /**
184
- * See: https://en.wikipedia.org/wiki/Grayscale#Converting_color_to_grayscale
185
- *
186
- * Reference: http://www.phpied.com/image-fun/ and https://github.com/meltingice/CamanJS/blob/master/src/lib/filters.coffee#L89
187
- *
188
- * @params {integer} r - the value of the red pixel
189
- * @params {integer} g - the value of the green pixel
190
- * @params {integer} b - the value of the blue pixel
191
- * @returns {Array} - The computed RGB values for the input, with a constant 255 for the alpha channel.
192
- **/
193
- function _grayscale (r, g, b)
194
- {
195
- let pixelAverage = (0.3 * r + 0.59 * g + 0.11 * b);
196
-
197
- return [pixelAverage, pixelAverage, pixelAverage, 255];
198
- }
199
-
200
- export function saturation (data, adjust)
201
- {
202
- return addFilterToQueue(data, _saturation, adjust, 'Saturation');
203
- }
204
-
205
- /**
206
- * Adjusts the color saturation of the image.
207
- * Range is -100 to 100. Values < 0 will desaturate the image while values > 0 will saturate it.
208
- *
209
- * See https://github.com/meltingice/CamanJS/blob/master/src/lib/filters.coffee#L42-L58
210
- *
211
- * @params {integer} r - the value of the red pixel
212
- * @params {integer} g - the value of the green pixel
213
- * @params {integer} b - the value of the blue pixel
214
- * @params {integer} adjust - the saturation value for adjustment, -100 to 100
215
- * @returns {Array} - The computed RGB values for the input, with a constant 255 for the alpha channel.
216
- **/
217
- function _saturation (r, g, b, adjust)
218
- {
219
- let adj = adjust * -0.01;
220
- let max = Math.max(r, g, b);
221
-
222
- return [
223
- r !== max ? r + (max - r) * adj : r,
224
- g !== max ? g + (max - g) * adj : g,
225
- b !== max ? b + (max - b) * adj : b,
226
- 255
227
- ];
228
- }
229
-
230
- export function vibrance (data, adjust)
231
- {
232
- return addFilterToQueue(data, _vibrance, adjust, 'Vibrance');
233
- }
234
-
235
- /**
236
- * Similar to saturation, but adjusts the saturation levels in a slightly smarter, more subtle way.
237
- * Vibrance will attempt to boost colors that are less saturated more and boost already saturated
238
- * colors less, while saturation boosts all colors by the same level.
239
- *
240
- * See: https://github.com/meltingice/CamanJS/blob/master/src/lib/filters.coffee#L60
241
- *
242
- * @params {integer} r - the value of the red pixel
243
- * @params {integer} g - the value of the green pixel
244
- * @params {integer} b - the value of the blue pixel
245
- * @params {integer} adjust - the vibrance value for adjustment, -100 to 100
246
- * @returns {Array} - The computed RGB values for the input, with a constant 255 for the alpha channel.
247
- **/
248
- function _vibrance (r, g, b, adjust)
249
- {
250
- let adj = adjust * -1;
251
-
252
- let max = Math.max(r, g, b);
253
- let avg = r + g + b / 3;
254
- let amt = ((Math.abs(max - avg) * 2 / 255) * adj) / 100;
255
-
256
- return [
257
- r !== max ? r + (max - r) * amt : r,
258
- g !== max ? g + (max - g) * amt : g,
259
- b !== max ? b + (max - b) * amt : b,
260
- 255
261
- ];
262
- }
263
-
264
- export function brightness (data, adjust)
265
- {
266
- return addFilterToQueue(data, _brightness, adjust, 'Brightness');
267
- }
268
-
269
- function _brightness (r, g, b, adjust)
270
- {
271
- let adj = Math.floor(255 * (adjust / 100));
272
-
273
- return [
274
- r + adj,
275
- g + adj,
276
- b + adj,
277
- 255
278
- ];
279
- }
280
-
281
- export function contrast (data, adjust)
282
- {
283
- return addFilterToQueue(data, _contrast, adjust, 'Contrast');
284
- }
285
-
286
- /**
287
- * Increases or decreases the color contrast of the image.
288
- *
289
- * @params {integer} r - the value of the red pixel
290
- * @params {integer} g - the value of the green pixel
291
- * @params {integer} b - the value of the blue pixel
292
- * @params {integer} adjust - the contrast value for adjustment, -100 to 100
293
- * @returns {Array} - The computed RGB values for the input, with a constant 255 for the alpha channel.
294
- **/
295
- function _contrast (r, g, b, adjust)
296
- {
297
- let adj = Math.pow((adjust + 100) / 100, 2);
298
- let rr = r, gg = g, bb = b;
299
-
300
- rr /= 255;
301
- rr -= 0.5;
302
- rr *= adj;
303
- rr += 0.5;
304
- rr *= 255;
305
-
306
- gg /= 255;
307
- gg -= 0.5;
308
- gg *= adj;
309
- gg += 0.5;
310
- gg *= 255;
311
-
312
- bb /= 255;
313
- bb -= 0.5;
314
- bb *= adj;
315
- bb += 0.5;
316
- bb *= 255;
317
-
318
- return [
319
- rr, gg, bb, 255
320
- ];
321
- }
322
- /**
323
- * Inverts the colours of a canvas.
324
- *
325
- * @params {object} data - A canvas image data object.
326
- * @returns {object} A new canvas data object.
327
- **/
328
- export function invert(data)
329
- {
330
- return addFilterToQueue(data, _invert, null, 'Invert');
331
- }
332
-
333
- /**
334
- * Inverts the colours of the image.
335
- * See: https://github.com/meltingice/CamanJS/blob/master/src/lib/filters.coffee#L183
336
- *
337
- * @params {integer} r - the value of the red pixel
338
- * @params {integer} g - the value of the green pixel
339
- * @params {integer} b - the value of the blue pixel
340
- * @returns {Array} - The computed RGB values for the input, with a constant 255 for the alpha channel.
341
- **/
342
- function _invert (r, g, b)
343
- {
344
- return [
345
- 255 - r,
346
- 255 - g,
347
- 255 - b,
348
- 255
349
- ];
350
- }
351
-
352
- export function threshold(data, adjust)
353
- {
354
- return addFilterToQueue(data, _threshold, adjust, 'Threshold');
355
- }
356
-
357
- /**
358
- * Black pixels above a certain value (0-255); otherwise white. Perceptively weighted.
359
- *
360
- * See: https://www.html5rocks.com/en/tutorials/canvas/imagefilters/
361
- *
362
- * @params {integer} r - the value of the red pixel
363
- * @params {integer} g - the value of the green pixel
364
- * @params {integer} b - the value of the blue pixel
365
- * @params {integer} adjust - the threshold value, 0-255
366
- * @returns {Array} - The computed RGB values for the input, with a constant 255 for the alpha channel.
367
- **/
368
- function _threshold (r, g, b, adjust)
369
- {
370
- let v = (0.2126 * r + 0.7152 * g + 0.0722 * b >= adjust) ? 255 : 0;
371
-
372
- return [
373
- v, v, v, 255
374
- ];
375
-
376
- }
377
-
378
- export function hue (data, adjust)
379
- {
380
- return addFilterToQueue(data, _hue, adjust, 'Hue');
381
- }
382
-
383
- function _hue (r, g, b, adjust)
384
- {
385
- let {h, s, v} = rgbToHSV(r, g, b);
386
-
387
- h = h * 100;
388
- h += Math.abs(adjust);
389
- h = h % 100;
390
- h /= 100;
391
-
392
- let res = hsvToRGB(h, s, v);
393
-
394
- return [
395
- res.r, res.g, res.b, 255
396
- ];
397
- }
398
-
399
- export function gamma (data, adjust)
400
- {
401
- return addFilterToQueue(data, _gamma, adjust, 'Gamma');
402
- }
403
-
404
- /**
405
- * Adjusts the gamma of the image.
406
- * Range is 0 to 4. Values between 0 and 1 will lessen the contrast while values greater
407
- * than 1 will increase it. Starts at 1 default. The actual adjust slider is from -100 to
408
- * 300 (so default can be 0 and offset accordingly), so must scale properly
409
- * See https://github.com/meltingice/CamanJS/blob/master/src/lib/filters.coffee#L210-L221
410
- *
411
- * @params {integer} r - the value of the red pixel
412
- * @params {integer} g - the value of the green pixel
413
- * @params {integer} b - the value of the blue pixel
414
- * @params {integer} adjust - the gamma value for adjustment, 0 to 400
415
- * @returns {Array} - The computed RGB values for the input, with a constant 255 for the alpha channel.
416
- **/
417
- function _gamma (r, g, b, adjust)
418
- {
419
- let adj = adjust / 100 + 1;
420
- if (adj < 0)
421
- adj *= -1;
422
-
423
- return [
424
- Math.pow(r / 255, adj) * 255,
425
- Math.pow(g / 255, adj) * 255,
426
- Math.pow(b / 255, adj) * 255,
427
- 255
428
- ];
429
- }
430
-
431
- export function ccRed (data, adjust)
432
- {
433
- return addFilterToQueue(data, _ccRed, adjust, 'CC Red');
434
- }
435
-
436
- /**
437
- * Adjusts the red intensity of the image.
438
- *
439
- * See https://github.com/meltingice/CamanJS/blob/master/src/lib/filters.coffee#L274-L305
440
- *
441
- * @params {integer} r - the value of the red pixel
442
- * @params {integer} g - the value of the green pixel
443
- * @params {integer} b - the value of the blue pixel
444
- * @params {integer} adjust - the red value for adjustment, -100 to 100
445
- * @returns {Array} - The computed RGB values for the input, with a constant 255 for the alpha channel.
446
- */
447
- function _ccRed (r, g, b, adjust)
448
- {
449
- let adj = adjust / 100;
450
-
451
- return [
452
- adj > 0 ? r + (255 - r) * adj : r - r * Math.abs(adj),
453
- g,
454
- b,
455
- 255
456
- ];
457
- }
458
-
459
- export function ccGreen (data, adjust)
460
- {
461
- return addFilterToQueue(data, _ccGreen, adjust, 'CC Green');
462
- }
463
-
464
- /**
465
- * Adjusts the green intensity of the image.
466
- *
467
- * See https://github.com/meltingice/CamanJS/blob/master/src/lib/filters.coffee#L274-L305
468
- *
469
- * @params {integer} r - the value of the red pixel
470
- * @params {integer} g - the value of the green pixel
471
- * @params {integer} b - the value of the blue pixel
472
- * @params {integer} adjust - the green value for adjustment, -100 to 100
473
- * @returns {Array} - The computed RGB values for the input, with a constant 255 for the alpha channel.
474
- */
475
- function _ccGreen (r, g, b, adjust)
476
- {
477
- let adj = adjust / 100;
478
-
479
- return [
480
- r,
481
- adj > 0 ? g + (255 - g) * adj : g - g * Math.abs(adj),
482
- b,
483
- 255
484
- ];
485
- }
486
-
487
- export function ccBlue (data, adjust)
488
- {
489
- return addFilterToQueue(data, _ccBlue, adjust, 'CC Blue');
490
- }
491
-
492
- /**
493
- * Adjusts the blue intensity of the image.
494
- *
495
- * See https://github.com/meltingice/CamanJS/blob/master/src/lib/filters.coffee#L274-L305
496
- *
497
- * @params {integer} r - the value of the red pixel
498
- * @params {integer} g - the value of the green pixel
499
- * @params {integer} b - the value of the blue pixel
500
- * @params {integer} adjust - the blue value for adjustment, -100 to 100
501
- * @returns {Array} - The computed RGB values for the input, with a constant 255 for the alpha channel.
502
- */
503
- function _ccBlue (r, g, b, adjust)
504
- {
505
- let adj = adjust / 100;
506
-
507
- return [
508
- r,
509
- g,
510
- adj > 0 ? b + (255 - b) * adj : b - b * Math.abs(adj),
511
- 255
512
- ];
513
- }
514
-
515
- export function rgbToHSV (r, g, b)
516
- {
517
- let rr = r, gg = g, bb = b;
518
-
519
- rr /= 255;
520
- gg /= 255;
521
- bb /= 255;
522
-
523
- let max = Math.max(rr, gg, bb);
524
- let min = Math.min(rr, gg, bb);
525
- let v = max;
526
- let d = max - min;
527
-
528
- let s = max === 0 ? 0 : d / max;
529
- let h;
530
-
531
- if (max === min)
532
- h = 0;
533
- else
534
- {
535
- switch (max)
536
- {
537
- case rr:
538
- h = (gg - bb) / d + (gg < bb ? 6 : 0);
539
- break;
540
- case gg:
541
- h = (bb - rr) / d + 2;
542
- break;
543
- case bb:
544
- h = (rr - gg) / d + 4;
545
- break;
546
- }
547
-
548
- h /= 6;
549
- }
550
-
551
- return {h, s, v};
552
- }
553
-
554
- export function hsvToRGB (h, s, v)
555
- {
556
- let b, f, g, i, p, q, r, t;
557
- i = Math.floor(h * 6);
558
- f = h * 6 - i;
559
- p = v * (1 - s);
560
- q = v * (1 - f * s);
561
- t = v * (1 - (1 - f) * s);
562
-
563
- switch (i % 6)
564
- {
565
- case 0:
566
- r = v;
567
- g = t;
568
- b = p;
569
- break;
570
- case 1:
571
- r = q;
572
- g = v;
573
- b = p;
574
- break;
575
- case 2:
576
- r = p;
577
- g = v;
578
- b = t;
579
- break;
580
- case 3:
581
- r = p;
582
- g = q;
583
- b = v;
584
- break;
585
- case 4:
586
- r = t;
587
- g = p;
588
- b = v;
589
- break;
590
- case 5:
591
- r = v;
592
- g = p;
593
- b = q;
594
- break;
595
- }
596
-
597
- return {
598
- r: Math.floor(r * 255),
599
- g: Math.floor(g * 255),
600
- b: Math.floor(b * 255)
601
- };
602
- }
603
-
604
-
605
- /*********************************************
606
- Convolution filters
607
- *********************************************/
608
-
609
- function convolve (data, weights, opaque)
610
- {
611
- let side = Math.round(Math.sqrt(weights.length));
612
- let halfSide = Math.floor(side / 2);
613
-
614
- let srcData = data.data;
615
- let sw = data.width;
616
- let sh = data.height;
617
- let w = sw;
618
- let h = sh;
619
-
620
- let output = _getOffscreenCanvasData(w, h);
621
- let dst = output.data;
622
-
623
- let alphaFac = opaque ? 1 : 0;
624
-
625
- for (let y = 0; y < h; y++)
626
- {
627
- for (let x = 0; x < w; x++)
628
- {
629
- let sy = y;
630
- let sx = x;
631
- let dstOff = (y * w + x) * 4;
632
-
633
- let r = 0, g = 0, b = 0, a = 0;
634
-
635
- for (let cy = 0; cy < side; cy++)
636
- {
637
- for (let cx = 0; cx < side; cx++)
638
- {
639
- let scy = sy + cy - halfSide;
640
- let scx = sx + cx - halfSide;
641
-
642
- if (scy >= 0 && scy < sh && scx >= 0 && scx < sw)
643
- {
644
- let srcOff = (scy * sw + scx) * 4;
645
- let wt = weights[cy * side + cx];
646
- r += srcData[srcOff] * wt;
647
- g += srcData[srcOff + 1] * wt;
648
- b += srcData[srcOff + 2] * wt;
649
- a += srcData[srcOff + 3] * wt;
650
- }
651
- }
652
- }
653
-
654
- dst[dstOff] = r;
655
- dst[dstOff + 1] = g;
656
- dst[dstOff + 2] = b;
657
- dst[dstOff + 3] = a + alphaFac * (255 - a);
658
- }
659
- }
660
- return output;
661
- }
662
-
663
-
664
- export function sharpen (data, adjust)
665
- {
666
- let adj = adjust ? adjust : 100;
667
- adj /= 100;
668
-
669
- if (adjust === 0) // reset value
670
- adj = 0;
671
-
672
- let weights = [
673
- 0, -adj, 0,
674
- -adj, 4 * adj + 1, -adj,
675
- 0, -adj, 0
676
- ];
677
-
678
- return addFilterToQueue(data, convolve, weights, 'Sharpness');
679
- }