added histogram/waveform components...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2020-05-15 21:23:13 +03:00
parent 9f4a378cc3
commit b0f52c82f1
4 changed files with 265 additions and 14 deletions

View File

@ -20,7 +20,7 @@ if(typeof(process) != 'undefined'){
try {
// do this only if browser is loaded...
var graph = window != null ?
requirejs('experiments/ig-image-graph-obj')
requirejs('lib/components/ig-image-graph')
: null
} catch(e){}
}
@ -346,7 +346,7 @@ var MetadataUIActions = actions.Actions({
'metadata-graph': true,
'metadata-graph-config': {
graph: 'waveform',
mode: 'color',
mode: 'luminance',
},
},
@ -408,13 +408,17 @@ var MetadataUIActions = actions.Actions({
that.images.getBestPreview(gid, size || 300, null, true).url
: that.getImagePath(gid)
var elem = this.graph =
this.graph ?
Object.assign(this.graph, config)
: graph.makeImageGraph(url, config)
Object.assign(
this.graph
|| document.createElement('ig-image-graph'),
config)
Object.assign(elem.style, {
width: '500px',
height: '200px',
})
// delay drawing a bit...
setTimeout(function(){
elem.src = url }, 0)
return elem }
// preview...

View File

@ -0,0 +1,213 @@
<!DOCTYPE html>
<html>
<style>
.graph {
position: relative;
display: inline-block;
width: attr(image-width);
height: attr(graph-height);
}
.graph canvas {
width: 100%;
height: 100%;
}
.graph .controls {
display: inline-block;
position: absolute;
top: 2px;
right: 2px;
}
.graph .controls button {
background: transparent;
border: none;
color: white;
opacity: 0.7;
}
.graph .controls button.current {
text-decoration: underline;
opacity: 0.9;
}
.graph .controls button.R:hover,
.graph .controls button.current.R {
background: red;
}
.graph .controls button.G:hover,
.graph .controls button.current.G {
background: green;
}
.graph .controls button.B:hover,
.graph .controls button.current.B {
background: blue;
}
.graph .controls button:hover {
opacity: 1;
}
</style>
<script src="../../ext-lib/jquery.js"></script>
<script src="../../ext-lib/jquery-ui.js"></script>
<script src="../../lib/jli.js"></script>
<script src="ig-image-graph.js"></script>
<script>
// XXX should we make this a web components???
// + would make everything transparent
// - add a tag
// - edit props
// - handle events
// - not sure what is the differenence practically...
var makeWaveform = function(img, options){
var color_modes = ['normalized', 'white', 'color']
options = options || {}
options.mode = options.mode || 'color'
options.color = options.color || color_modes[0]
// XXX configurable...
var type = 'waveform'
var graph = waveform
var buttons
var update = function(m){
m = options.mode = m || options.mode
graph(img, canvas, m, options.color)
;(buttons || [])
.forEach(function(b){
b.classList.contains(m) ?
b.classList.add('current')
: b.classList.remove('current') }) }
// handle img urls...
if(typeof(img) == typeof('str')){
var src = img
img = document.createElement('img')
img.onload = function(){
container.setAttribute('image-width', img.width)
container.setAttribute('image-height', img.height)
update() }
img.src = src }
// container...
var container = document.createElement('div')
container.classList.add('graph', type)
// XXX not sure why would we need shadow dom here...
//var shadow = container.attachShadow({mode: 'open'})
// canvas...
var canvas = document.createElement('canvas')
container.appendChild(canvas)
// controls...
if(controls || controls === undefined){
var controls = document.createElement('div')
controls.classList.add('controls')
// buttons...
buttons = ['luminance', 'color', 'R', 'G', 'B']
.map(function(m){
var button = document.createElement('button')
button.innerText = m
button.classList.add(m)
button.onclick = function(){
update(m) }
controls.appendChild(button)
return button })
// color mode switch...
var button = document.createElement('button')
button.innerText = '('+ options.color[0] +')'
button.onclick = function(){
options.color = color_modes[
(color_modes.indexOf(options.color) + 1)
% color_modes.length]
this.innerText = '('+ options.color[0] +')'
update() }
controls.appendChild(button)
// add to block...
container.appendChild(controls) }
// meta stuff...
container.setAttribute('graph-width', canvas.width)
container.setAttribute('graph-height', canvas.height)
container.setAttribute('image-width', img.width)
container.setAttribute('image-height', img.height)
// init...
update()
return container
}
var start = function(){
//waveform(document.getElementById('input'), document.getElementById('waveform'), 'color')
//histogram(document.getElementById('input'), document.getElementById('histogram'), 'color')
//document.body.appendChild(makeWaveform(document.getElementById('input'), 'color', 'normalized'))
document.body.appendChild(makeWaveform(document.getElementById('input')))
document.body.appendChild(makeWaveform('../images/splash-800x500.jpg'))
}
</script>
<body>
<img id="input" src="../images/splash-800x500.jpg" onload="start()"/>
<br>
<ig-image-graph
graph="histogram"
src="../images/splash-800x500.jpg"
mode="color"
color="normalized"
style="width: 600px; height: 300px"></ig-image-graph>
<ig-image-graph
graph="waveform"
src="../images/splash-800x500.jpg"
mode="color"
color="normalized" ></ig-image-graph>
<!--
<br>
<canvas id="waveform"></canvas>
<br>
<button onclick="waveform(getElementById('input'), getElementById('waveform'), 'luminance')">Luminance</button>
<button onclick="waveform(getElementById('input'), getElementById('waveform'), 'color')">Color</button>
<button onclick="waveform(getElementById('input'), getElementById('waveform'), 'R')">R</button>
<button onclick="waveform(getElementById('input'), getElementById('waveform'), 'G')">G</button>
<button onclick="waveform(getElementById('input'), getElementById('waveform'), 'B')">B</button>
<br>
<canvas id="histogram"></canvas>
<br>
<button onclick="histogram(getElementById('input'), getElementById('histogram'), 'luminance')">Luminance</button>
<button onclick="histogram(getElementById('input'), getElementById('histogram'), 'color')">Color</button>
<button onclick="histogram(getElementById('input'), getElementById('histogram'), 'R')">R</button>
<button onclick="histogram(getElementById('input'), getElementById('histogram'), 'G')">G</button>
<button onclick="histogram(getElementById('input'), getElementById('histogram'), 'B')">B</button>
-->
<br>
<br>
<br>
</body>
</html>
<!-- vim:set ts=4 sw=4 : -->

View File

@ -0,0 +1,27 @@
/**********************************************************************
*
*
*
* XXX still thinking on how to package this correctly...
* XXX add worker support...
*
**********************************************************************/
// var htmlCanvas = document.getElementById("canvas")
// var offscreen = htmlCanvas.transferControlToOffscreen()
//
// var worker = new Worker("offscreencanvas.js")
// worker.postMessage({canvas: offscreen}, [offscreen])
//
// XXX also test for OffscreenWorker(..)...
onmessage = function(evt){
var canvas = evt.data.canvas
// XXX
}
/**********************************************************************
* vim:set ts=4 sw=4 : */

View File

@ -1,12 +1,14 @@
//---------------------------------------------------------------------
//
//
// XXX still thinking on how to package this correctly...
//
//---------------------------------------------------------------------
/**********************************************************************
*
*
*
* XXX still thinking on how to package this correctly...
* XXX add worker support...
*
**********************************************************************/
((typeof define)[0]=='u'?function(f){module.exports=f(require)}:define)
(function(require){ var module={} // make module AMD/node compatible...
//---------------------------------------------------------------------
/*********************************************************************/
var object = require('lib/object')
@ -249,7 +251,7 @@ function(img, canvas, mode, color){
//---------------------------------------------------------------------
// Custom element...
igImageGraph_template = `
var igImageGraph_template = `
<style>
:host {
position: relative;
@ -259,13 +261,17 @@ igImageGraph_template = `
width: attr(image-width);
height: attr(graph-height);
padding-top: 16px;
padding-bottom: 10px;
}
:host canvas {
box-sizing: border-box;
width: 100%;
height: 100%;
border: 2px solid gray;
border-top: 1px dashed rgba(255, 255, 255, 0.2);
border-bottom: 1px dashed rgba(255, 255, 255, 0.2);
}
:host .controls {
display: inline-block;
@ -280,6 +286,7 @@ igImageGraph_template = `
color: white;
opacity: 0.7;
float: right;
font-size: 12px;
}
:host .controls button.current {
text-decoration: underline;