change calendar color without reloading and implement algorithm™ to choose text color

This commit is contained in:
Georg Ehrke 2016-01-13 23:33:36 +01:00
parent 4dd0245837
commit 4cc5ba2ead
5 changed files with 95 additions and 7 deletions

View File

@ -236,7 +236,9 @@ app.controller('CalController', ['$scope', '$rootScope', '$window', 'CalendarSer
// Sadly fullcalendar doesn't support changing a calendar's
// color without removing and then adding it again as an eventSource
$scope.eventSource[url].color = updatedCalendar.color;
angular.element('.fcCalendar-id-' + url).css('background-color', updatedCalendar.color);
angular.element('.fcCalendar-id-' + updatedCalendar.tmpId).css('background-color', updatedCalendar.color);
angular.element('.fcCalendar-id-' + updatedCalendar.tmpId).css('border-color', updatedCalendar.color);
angular.element('.fcCalendar-id-' + updatedCalendar.tmpId).css('color', updatedCalendar.textColor);
}
$scope.eventSource[url].editable = updatedCalendar.cruds.update;
});

View File

@ -29,6 +29,7 @@ app.factory('Calendar', ['$rootScope', '$filter', 'VEventService', 'TimezoneServ
});
angular.extend(this, {
tmpId: null,
fcEventSource: {
events: function (start, end, timezone, callback) {
console.log('querying events ...');
@ -49,7 +50,6 @@ app.factory('Calendar', ['$rootScope', '$filter', 'VEventService', 'TimezoneServ
});
});
},
color: this._properties.color,
editable: this._properties.cruds.update,
calendar: this
},
@ -67,6 +67,8 @@ app.factory('Calendar', ['$rootScope', '$filter', 'VEventService', 'TimezoneServ
this._properties.components[name] = true;
}
}
this.tmpId = Math.random().toString(36).substr(2);
}
Calendar.prototype = {
@ -97,6 +99,39 @@ app.factory('Calendar', ['$rootScope', '$filter', 'VEventService', 'TimezoneServ
this._properties.color = color;
this._setUpdated('color');
},
get textColor() {
var color = this.color;
var fallbackColor = '#fff';
var c;
switch (color.length) {
case 4:
c = color.match(/^#([0-9a-f]{3})$/i)[1];
if (c) {
return this._generateTextColor(
parseInt(c.charAt(0),16)*0x11,
parseInt(c.charAt(1),16)*0x11,
parseInt(c.charAt(2),16)*0x11
);
}
return fallbackColor;
case 7:
case 9:
var regex = new RegExp('^#([0-9a-f]{' + (color.length - 1) + '})$', 'i');
c = color.match(regex)[1];
if (c) {
return this._generateTextColor(
parseInt(c.substr(0,2),16),
parseInt(c.substr(2,2),16),
parseInt(c.substr(4,2),16)
);
}
return fallbackColor;
default:
return fallbackColor;
}
},
get order() {
return this._properties.order;
},
@ -129,6 +164,10 @@ app.factory('Calendar', ['$rootScope', '$filter', 'VEventService', 'TimezoneServ
},
dropPreviousState: function() {
this._propertiesBackup = {};
},
_generateTextColor: function(r,g,b) {
var brightness = (((r * 299) + (g * 587) + (b * 114)) / 1000);
return (brightness > 130) ? '#000000' : '#FAFAFA';
}
};

View File

@ -80,7 +80,10 @@
function addCalendarDataToFCData(fcData, calendar) {
fcData.calendar = calendar;
fcData.editable = calendar.cruds.update;
fcData.className = 'fcCalendar-id-' + calendar.url;
fcData.backgroundColor = calendar.color;
fcData.borderColor = calendar.color;
fcData.textColor = calendar.textColor;
fcData.className = 'fcCalendar-id-' + calendar.tmpId;
return fcData;
}

View File

@ -256,7 +256,9 @@ app.controller('CalController', ['$scope', '$rootScope', '$window', 'CalendarSer
// Sadly fullcalendar doesn't support changing a calendar's
// color without removing and then adding it again as an eventSource
$scope.eventSource[url].color = updatedCalendar.color;
angular.element('.fcCalendar-id-' + url).css('background-color', updatedCalendar.color);
angular.element('.fcCalendar-id-' + updatedCalendar.tmpId).css('background-color', updatedCalendar.color);
angular.element('.fcCalendar-id-' + updatedCalendar.tmpId).css('border-color', updatedCalendar.color);
angular.element('.fcCalendar-id-' + updatedCalendar.tmpId).css('color', updatedCalendar.textColor);
}
$scope.eventSource[url].editable = updatedCalendar.cruds.update;
});
@ -1361,6 +1363,7 @@ app.factory('Calendar', ['$rootScope', '$filter', 'VEventService', 'TimezoneServ
});
angular.extend(this, {
tmpId: null,
fcEventSource: {
events: function (start, end, timezone, callback) {
console.log('querying events ...');
@ -1381,7 +1384,6 @@ app.factory('Calendar', ['$rootScope', '$filter', 'VEventService', 'TimezoneServ
});
});
},
color: this._properties.color,
editable: this._properties.cruds.update,
calendar: this
},
@ -1399,6 +1401,8 @@ app.factory('Calendar', ['$rootScope', '$filter', 'VEventService', 'TimezoneServ
this._properties.components[name] = true;
}
}
this.tmpId = Math.random().toString(36).substr(2);
}
Calendar.prototype = {
@ -1429,6 +1433,39 @@ app.factory('Calendar', ['$rootScope', '$filter', 'VEventService', 'TimezoneServ
this._properties.color = color;
this._setUpdated('color');
},
get textColor() {
var color = this.color;
var fallbackColor = '#fff';
var c;
switch (color.length) {
case 4:
c = color.match(/^#([0-9a-f]{3})$/i)[1];
if (c) {
return this._generateTextColor(
parseInt(c.charAt(0),16)*0x11,
parseInt(c.charAt(1),16)*0x11,
parseInt(c.charAt(2),16)*0x11
);
}
return fallbackColor;
case 7:
case 9:
var regex = new RegExp('^#([0-9a-f]{' + (color.length - 1) + '})$', 'i');
c = color.match(regex)[1];
if (c) {
return this._generateTextColor(
parseInt(c.substr(0,2),16),
parseInt(c.substr(2,2),16),
parseInt(c.substr(4,2),16)
);
}
return fallbackColor;
default:
return fallbackColor;
}
},
get order() {
return this._properties.order;
},
@ -1461,6 +1498,10 @@ app.factory('Calendar', ['$rootScope', '$filter', 'VEventService', 'TimezoneServ
},
dropPreviousState: function() {
this._propertiesBackup = {};
},
_generateTextColor: function(r,g,b) {
var brightness = (((r * 299) + (g * 587) + (b * 114)) / 1000);
return (brightness > 130) ? '#000000' : '#FAFAFA';
}
};
@ -2129,7 +2170,10 @@ app.factory('fcHelper', function () {
function addCalendarDataToFCData(fcData, calendar) {
fcData.calendar = calendar;
fcData.editable = calendar.cruds.update;
fcData.className = 'fcCalendar-id-' + calendar.url;
fcData.backgroundColor = calendar.color;
fcData.borderColor = calendar.color;
fcData.textColor = calendar.textColor;
fcData.className = 'fcCalendar-id-' + calendar.tmpId;
return fcData;
}

View File

@ -22,7 +22,7 @@
*
*/
?>
<span class="calendarCheckbox" ng-show="!calendar.list.loading && !calendar.list.edit" ng-style="{ background : calendar.enabled == true ? '{{ calendar.color }}' : 'transparent' }"></span>
<span class="calendarCheckbox" ng-show="!calendar.list.loading && !calendar.list.edit" ng-style="{ background : calendar.enabled == true ? calendar.color : 'transparent' }"></span>
<span class="loading pull-left" ng-show="calendar.list.loading && !calendar.list.edit">
<i class="fa fa-spinner fa-spin"></i>
</span>