@bigfishtv/cockpit
Version:
181 lines (159 loc) • 5.25 kB
JavaScript
import {
curvesHashTable,
getContrastCurve,
getVibranceMatrix,
getTemperatureRGB,
interpolateGradient,
} from './colorUtils'
import isCrossDomain from './isCrossDomain'
export function init(Caman = window.Caman) {
if (!Caman) {
console.warn('Caman object does not exist. Cannot add custom Tank filters.')
return
}
const INITED = '__tankCamanInited__'
if (Caman[INITED]) {
return
}
Caman[INITED] = true
// replace Caman's isURLRemote with our own
Caman.IO.isURLRemote = isCrossDomain
// Created my own color matrix filter
// http://developer.android.com/reference/android/graphics/ColorMatrix.html
Caman.Filter.register('colorMatrix', function(matrix) {
return this.process('matrix', function(rgba) {
rgba.r /= 255
rgba.g /= 255
rgba.b /= 255
rgba.a /= 255
rgba.r = matrix[0] * rgba.r + matrix[1] * rgba.g + matrix[2] * rgba.b + matrix[3] * rgba.a + matrix[4]
rgba.g = matrix[5] * rgba.r + matrix[6] * rgba.g + matrix[7] * rgba.b + matrix[8] * rgba.a + matrix[9]
rgba.b = matrix[10] * rgba.r + matrix[11] * rgba.g + matrix[12] * rgba.b + matrix[13] * rgba.a + matrix[14]
rgba.a = matrix[15] * rgba.r + matrix[16] * rgba.g + matrix[17] * rgba.b + matrix[18] * rgba.a + matrix[19]
rgba.r = Math.min(Math.max(rgba.r * 255, 0), 255)
rgba.g = Math.min(Math.max(rgba.g * 255, 0), 255)
rgba.b = Math.min(Math.max(rgba.b * 255, 0), 255)
rgba.a = Math.min(Math.max(rgba.a * 255, 0), 255)
return rgba
})
})
// We overwrite caman's contrast filter in favour of our custom one
Caman.Filter.register('contrast', function(adjust) {
this.curves.apply(this, ['rgb', ...getContrastCurve(adjust), curvesHashTable])
})
// We overwrite caman's contrast filter in favour of our custom one
Caman.Filter.register('exposure', function(adjust) {
const p = Math.abs(adjust) / 100
const ctrl1 = [0, 255 * p]
const ctrl2 = [255 - 255 * p, 255]
if (adjust < 0) {
ctrl1.reverse()
ctrl2.reverse()
}
this.curves.apply(this, ['rgb', ctrl1, ctrl2, curvesHashTable])
})
Caman.Filter.register('fade', function(adjust) {
const ctrl1 = [0, adjust]
const ctrl2 = [255, 255 - adjust / 2]
this.curves.apply(this, ['rgb', ctrl1, ctrl2, curvesHashTable])
})
// We overwrite caman's vibrance filter in favour of our custom one
Caman.Filter.register('vibrance', function(adjust) {
const matrix = getVibranceMatrix(adjust)
this.colorMatrix.apply(this, [matrix])
})
// We overwrite caman's channels (tint) filter in favour of our custom one
Caman.Filter.register('channels', function(options) {
const red = options.red ? options.red / 100 : 0
const green = options.green ? options.green / 100 : 0
const blue = options.blue ? options.blue / 100 : 0
/* prettier-ignore */
const matrix = [
1, 0, 0, 0, red,
0, 1, 0, 0, green,
0, 0, 1, 0, blue,
0, 0, 0, 1, 0
]
this.colorMatrix.apply(this, [matrix])
})
Caman.Filter.register('temperature', function(adjust) {
const { red, green, blue } = getTemperatureRGB(adjust)
/* prettier-ignore */
const matrix = [
red/255, 0, 0, 0, 0,
0, green/255, 0, 0, 0,
0, 0, blue/255, 0, 0,
0, 0, 0, 1, 0
]
this.colorMatrix.apply(this, [matrix])
})
Caman.Filter.register('curves', function() {
let algo, i, _i, _j, _ref, _ref1
let isBezier = false
let channels = arguments[0]
const ctrlPts = arguments.length >= 2 ? Array.prototype.slice.call(arguments, 1) : []
const last = ctrlPts[ctrlPts.length - 1]
switch (typeof last) {
case 'function':
algo = last
ctrlPts.pop()
break
case 'string':
algo = Caman.Calculate[last]
ctrlPts.pop()
break
default:
isBezier = true
algo = Caman.Calculate.bezier
break
}
if (typeof channels === 'string') {
channels = channels.split('')
}
if (channels[0] === 'v') {
channels = ['r', 'g', 'b']
}
if (ctrlPts.length < 2) {
console.warn(ctrlPt)
throw 'Invalid number of arguments to curves filter'
}
const bezier = isBezier ? algo.apply(this, [...ctrlPts, 0, 255]) : algo(ctrlPts, 0, 255)
const start = ctrlPts[0]
if (start[0] > 0) {
for (i = _i = 0, _ref = start[0]; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
bezier[i] = start[1]
}
}
const end = ctrlPts[ctrlPts.length - 1]
if (end[0] < 255) {
for (i = _j = _ref1 = end[0]; _ref1 <= 255 ? _j <= 255 : _j >= 255; i = _ref1 <= 255 ? ++_j : --_j) {
bezier[i] = end[1]
}
}
return this.process('curves', function(rgba) {
let _k, _ref2
for (i = _k = 0, _ref2 = channels.length; 0 <= _ref2 ? _k < _ref2 : _k > _ref2; i = 0 <= _ref2 ? ++_k : --_k) {
rgba[channels[i]] = bezier[rgba[channels[i]]]
}
return rgba
})
})
Caman.Filter.register('blur', function() {
/* prettier-ignore */
this.processKernel("Blur", [
1, 1, 1,
1, 1, 1,
1, 1, 1,
])
})
Caman.Filter.register('gradientMap', function(...markers) {
const gradientMap = interpolateGradient(markers, 256)
return this.process('matrix', function(rgba) {
// const avg = Caman.Calculate.luminance(rgba)
rgba.r = Math.floor(gradientMap[rgba.r * 4])
rgba.g = Math.floor(gradientMap[rgba.g * 4 + 1])
rgba.b = Math.floor(gradientMap[rgba.b * 4 + 2])
return rgba
})
})
}