I have made some changes. It will work for both scenario,
- if user change from color name(
textfield
) then RGB will change.
- If user will change from number field than color name(
textfield
) will be changed.
Try this code in your sencha fiddle
Ext.create({
xtype: 'viewport',
renderTo: Ext.getBody(),
viewModel: {
data: {
theColor: {
name: 'Blue',
hex: '3366CC'
}
},
formulas: {
containerValue: {
bind: '{theColor.hex}',
get: function (value) {
return {
hex: value
};
},
set: function (value) {
this.set('theColor.hex', value.hex);
}
}
}
},
items: [{
region: 'center',
xtype: 'form',
bodyPadding: 10,
height: 300,
fieldDefaults: {
labelWidth: 90,
},
items: [{
xtype: 'component',
width: 30,
height: 30,
bind: {
style: {
background: '#{theColor.hex}'
}
}
}, {
xtype: 'textfield',
fieldLabel: 'Name',
bind: '{theColor.name}',
listeners:{
blur:function(textfield,e,eOpts){
var viewModel = textfield.up('viewport').getViewModel();
colorName = textfield.getValue(),
hex = colorToHex(colorName);
viewModel.set('theColor',{
name: colorName,
hex: hex
});
function colorToRGBA(color) {
// Returns the color as an array of [r, g, b, a] -- all range from 0 - 255
// color must be a valid canvas fillStyle. This will cover most anything
// you'd want to use.
// Examples:
// colorToRGBA('red') # [255, 0, 0, 255]
// colorToRGBA('#f00') # [255, 0, 0, 255]
var cvs, ctx;
cvs = document.createElement('canvas');
cvs.height = 1;
cvs.width = 1;
ctx = cvs.getContext('2d');
ctx.fillStyle = color;
ctx.fillRect(0, 0, 1, 1);
return ctx.getImageData(0, 0, 1, 1).data;
}
function byteToHex(num) {
// Turns a number (0-255) into a 2-character hex number (00-ff)
return ('0'+num.toString(16)).slice(-2);
}
function colorToHex(color) {
// Convert any CSS color to a hex representation
// Examples:
// colorToHex('red') # '#ff0000'
// colorToHex('rgb(255, 0, 0)') # '#ff0000'
var rgba, hex;
rgba = colorToRGBA(color);
hex = [0,1,2].map(
function(idx) { return byteToHex(rgba[idx]); }
).join('');
return hex;
}
}
}
}, {
xtype: 'container',
setValue: function (value) {
const hex = value.hex || '000000';
const red = parseInt(hex.substr(0, 2), 16);
const green = parseInt(hex.substr(2, 2), 16);
const blue = parseInt(hex.substr(4, 2), 16);
const items = this.query('');
items[0].setValue(red);
items[1].setValue(green);
items[2].setValue(blue);
},
bind: {
value: '{containerValue}',
},
defaults: {
xtype: 'numberfield',
maxValue: 255,
minValue: 0,
allowBlank: false,
width: 175,
listeners:{
change:function(numberfield){
if(numberfield.hasFocus){
var viewModel = numberfield.up('viewport').getViewModel(),
items = this.up().query(''),
red = items[0].getValue() || 0,
green = items[1].getValue() || 0,
blue = items[2].getValue() || 0,
hex = rgbToHex(red,green,blue);
viewModel.set('theColor',{
name: hex,//For hex to color name you have to search for that, here I am giving hax color.
hex: hex
});
function componentToHex(c) {
var hex = c.toString(16);
return hex.length == 1 ? "0" + hex : hex;
}
function rgbToHex(r, g, b) {
return componentToHex(r) + componentToHex(g) + componentToHex(b);
}
}
}
}
},
items: [{
fieldLabel: 'R',
}, {
fieldLabel: 'G',
}, {
fieldLabel: 'B',
}]
}]
}]
});