Skip to content

Commit 1f34a48

Browse files
committed
Add lightness option and fix up color calculation
1 parent 811f421 commit 1f34a48

File tree

6 files changed

+188
-46
lines changed

6 files changed

+188
-46
lines changed

examples/01-simple.html

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,11 @@ <h1>AngularJS Color Picker</h1>
4141
<select ng-model="options.saturation" class="form-control" ng-options="option.value as option.label for option in boolOptions"></select>
4242
</div>
4343

44+
<div class="row">
45+
<label class="control-label">Lightness (lightness) - whether or not to display the lightness control</label>
46+
<select ng-model="options.lightness" class="form-control" ng-options="option.value as option.label for option in boolOptions"></select>
47+
</div>
48+
4449
<div class="row">
4550
<label class="control-label">Alpha (alpha) - whether or not to display the alpha control</label>
4651
<select ng-model="options.alpha" class="form-control" ng-options="option.value as option.label for option in boolOptions"></select>

examples/app.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@ angular
33
.config(function($provide) {
44
$provide.decorator('ColorPickerOptions', function($delegate) {
55
var options = angular.copy($delegate);
6-
// options.round = true;
7-
// options.saturation = true;
6+
options.round = true;
7+
options.lightness = true;
8+
options.inline = true;
89
options.format = 'hsl';
910
return options;
1011
});

src/scripts/controller.js

Lines changed: 138 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,10 @@ export default class AngularColorPickerController {
286286
this.find('.color-picker-saturation').on('click', this.onSaturationClick.bind(this));
287287
this.find('.color-picker-saturation').on('touchend', this.onSaturationClick.bind(this));
288288

289+
// lightness click
290+
this.find('.color-picker-lightness').on('click', this.onLightnessClick.bind(this));
291+
this.find('.color-picker-lightness').on('touchend', this.onLightnessClick.bind(this));
292+
289293
// opacity click
290294
this.find('.color-picker-opacity').on('click', this.onOpacityClick.bind(this));
291295
this.find('.color-picker-opacity').on('touchend', this.onOpacityClick.bind(this));
@@ -308,6 +312,10 @@ export default class AngularColorPickerController {
308312
} else if (event.target.classList.contains('color-picker-saturation') || event.target.parentNode.classList.contains('color-picker-saturation')) {
309313
this.saturationDown(event);
310314
this.$scope.$apply();
315+
// mouse event on lightness slider
316+
} else if (event.target.classList.contains('color-picker-lightness') || event.target.parentNode.classList.contains('color-picker-lightness')) {
317+
this.lightnessDown(event);
318+
this.$scope.$apply();
311319
// mouse event on opacity slider
312320
} else if (event.target.classList.contains('color-picker-opacity') || event.target.parentNode.classList.contains('color-picker-opacity')) {
313321
this.opacityDown(event);
@@ -337,6 +345,11 @@ export default class AngularColorPickerController {
337345
this.saturationUp(event);
338346
this.$scope.$apply();
339347
this.onChange(event);
348+
// mouse event on lightness slider
349+
} else if (this.lightnessMouse && this.has_moused_moved) {
350+
this.lightnessUp(event);
351+
this.$scope.$apply();
352+
this.onChange(event);
340353
// mouse event on opacity slider
341354
} else if (this.opacityMouse && this.has_moused_moved) {
342355
this.opacityUp(event);
@@ -361,6 +374,11 @@ export default class AngularColorPickerController {
361374
this.has_moused_moved = true;
362375
this.saturationChange(event);
363376
this.$scope.$apply();
377+
// mouse event on lightness slider
378+
} else if (this.lightnessMouse) {
379+
this.has_moused_moved = true;
380+
this.lightnessChange(event);
381+
this.$scope.$apply();
364382
// mouse event on opacity slider
365383
} else if (this.opacityMouse) {
366384
this.has_moused_moved = true;
@@ -403,6 +421,15 @@ export default class AngularColorPickerController {
403421
}
404422
}
405423

424+
onLightnessClick (event) {
425+
if (!this.options.disabled && !this.has_moused_moved) {
426+
this.lightnessChange(event);
427+
this.lightnessUp(event);
428+
this.$scope.$apply();
429+
this.onChange(event);
430+
}
431+
}
432+
406433
onOpacityClick (event) {
407434
if (!this.options.disabled && !this.has_moused_moved) {
408435
this.opacityChange(event);
@@ -493,6 +520,7 @@ export default class AngularColorPickerController {
493520

494521
this.swatchColor = color.toHslString();
495522
this.updateSaturationBackground(color);
523+
this.updateLightnessBackground(color);
496524

497525
var colorString;
498526

@@ -558,15 +586,7 @@ export default class AngularColorPickerController {
558586
this.$timeout(() => {
559587
var container, el, bounding;
560588

561-
if (this.options.round) {
562-
container = this.$element[0].querySelector('.color-picker-saturation');
563-
el = angular.element(this.$element[0].querySelector('.color-picker-saturation .color-picker-slider'));
564-
bounding = container.getBoundingClientRect();
565-
566-
el.css({
567-
'top': (bounding.height * (100 - this.saturationPos) / 100) + 'px',
568-
});
569-
} else {
589+
if (!this.options.round) {
570590
container = this.$element[0].querySelector('.color-picker-grid');
571591
el = angular.element(this.$element[0].querySelector('.color-picker-grid .color-picker-picker'));
572592
bounding = container.getBoundingClientRect();
@@ -575,22 +595,38 @@ export default class AngularColorPickerController {
575595
'left': (bounding.width * this.saturationPos / 100) + 'px',
576596
});
577597
}
598+
599+
container = this.$element[0].querySelector('.color-picker-saturation');
600+
el = angular.element(this.$element[0].querySelector('.color-picker-saturation .color-picker-slider'));
601+
bounding = container.getBoundingClientRect();
602+
603+
el.css({
604+
'top': (bounding.height * (100 - this.saturationPos) / 100) + 'px',
605+
});
578606
});
579607
}
580608

581609
lightnessPosUpdate () {
582610
this.$timeout(() => {
583-
if (this.options.round) {
584-
this.updateRoundPos();
585-
} else {
586-
var container = this.$element[0].querySelector('.color-picker-grid');
587-
var el = angular.element(this.$element[0].querySelector('.color-picker-grid .color-picker-picker'));
588-
var bounding = container.getBoundingClientRect();
611+
var container, el, bounding;
612+
613+
if (!this.options.round) {
614+
container = this.$element[0].querySelector('.color-picker-grid');
615+
el = angular.element(this.$element[0].querySelector('.color-picker-grid .color-picker-picker'));
616+
bounding = container.getBoundingClientRect();
589617

590618
el.css({
591619
'top': (bounding.height * this.lightnessPos / 100) + 'px',
592620
});
593621
}
622+
623+
container = this.$element[0].querySelector('.color-picker-lightness');
624+
el = angular.element(this.$element[0].querySelector('.color-picker-lightness .color-picker-slider'));
625+
bounding = container.getBoundingClientRect();
626+
627+
el.css({
628+
'top': (bounding.height * this.lightnessPos / 100) + 'px',
629+
});
594630
});
595631
}
596632

@@ -663,10 +699,10 @@ export default class AngularColorPickerController {
663699
this.getRoundPos();
664700
this.updateRoundPos();
665701
} else {
666-
this.huePosUpdate();
667702
this.gridUpdate();
668703
}
669704

705+
this.huePosUpdate();
670706
this.update();
671707
}
672708
}
@@ -707,6 +743,11 @@ export default class AngularColorPickerController {
707743

708744
saturationUpdate () {
709745
if (this.saturation !== undefined) {
746+
if (this.options.round) {
747+
this.getRoundPos();
748+
this.updateRoundPos();
749+
}
750+
710751
this.saturationPos = this.saturation;
711752

712753
if (this.saturationPos < 0) {
@@ -730,6 +771,79 @@ export default class AngularColorPickerController {
730771
});
731772
}
732773

774+
updateLightnessBackground (color) {
775+
var el = this.find('.color-picker-lightness');
776+
777+
if (this.options.round) {
778+
var hsl = color.toHsl();
779+
hsl.l = 50;
780+
hsl = tinycolor(hsl);
781+
782+
el.css({
783+
'background': 'linear-gradient(to bottom, #FFFFFF 0%, ' + hsl.toHexString() + ' 50%, #000000 100%)'
784+
});
785+
} else {
786+
var hsv = color.toHsv();
787+
hsv.v = 100;
788+
hsv = tinycolor(hsv);
789+
790+
el.css({
791+
'background': 'linear-gradient(to bottom, ' + hsv.toHexString() + ' 0%, #000000 100%)'
792+
});
793+
}
794+
795+
796+
}
797+
798+
//---------------------------
799+
// lightness functions
800+
//---------------------------
801+
802+
lightnessDown (event) {
803+
event.stopPropagation();
804+
event.preventDefault();
805+
806+
this.lightnessMouse = true;
807+
}
808+
809+
lightnessUp (event) {
810+
event.stopPropagation();
811+
event.preventDefault();
812+
813+
this.lightnessMouse = false;
814+
}
815+
816+
lightnessChange (event) {
817+
event.stopPropagation();
818+
event.preventDefault();
819+
820+
var el = this.find('.color-picker-lightness');
821+
var eventPos = this.getEventPos(event);
822+
823+
this.lightness = Math.round((1 - ((eventPos.pageY - this.offset(el).top) / el.prop('offsetHeight'))) * 100);
824+
825+
if (this.lightness > 100) {
826+
this.lightness = 100;
827+
} else if (this.lightness < 0) {
828+
this.lightness = 0;
829+
}
830+
}
831+
832+
lightnessUpdate () {
833+
if (this.lightness !== undefined) {
834+
this.lightnessPos = 100 - this.lightness;
835+
836+
if (this.lightnessPos < 0) {
837+
this.lightnessPos = 0;
838+
} else if (this.lightnessPos > 100) {
839+
this.lightnessPos = 100;
840+
}
841+
842+
this.lightnessPosUpdate();
843+
this.update();
844+
}
845+
}
846+
733847
//---------------------------
734848
// opacity functions
735849
//---------------------------
@@ -816,15 +930,15 @@ export default class AngularColorPickerController {
816930
}
817931
this.hue = degHue;
818932

819-
var tmpLightness = Math.sqrt(dx * dx + dy * dy);
933+
var tmpSaturation = Math.sqrt(dx * dx + dy * dy);
820934

821-
if (tmpLightness > 1) {
822-
tmpLightness = 1;
823-
} else if (tmpLightness < 0) {
824-
tmpLightness = 0;
935+
if (tmpSaturation > 1) {
936+
tmpSaturation = 1;
937+
} else if (tmpSaturation < 0) {
938+
tmpSaturation = 0;
825939
}
826940

827-
this.lightness = (1 - (tmpLightness / 2)) * 100;
941+
this.saturation = tmpSaturation * 100;
828942
} else {
829943
this.saturation = ((eventPos.pageX - offset.left) / el.prop('offsetWidth')) * 100;
830944
this.lightness = (1 - ((eventPos.pageY - offset.top) / el.prop('offsetHeight'))) * 100;
@@ -843,34 +957,14 @@ export default class AngularColorPickerController {
843957
}
844958
}
845959

846-
lightnessUpdate () {
847-
if (this.lightness !== undefined) {
848-
if (this.options.round) {
849-
this.getRoundPos();
850-
} else {
851-
this.lightnessPos = (1 - (this.lightness / 100)) * 100;
852-
853-
if (this.lightnessPos < 0) {
854-
this.lightnessPos = 0;
855-
} else if (this.lightnessPos > 100) {
856-
this.lightnessPos = 100;
857-
}
858-
}
859-
860-
this.lightnessPosUpdate();
861-
this.update();
862-
}
863-
}
864-
865960
//---------------------------
866961
// helper functions
867962
//---------------------------
868963

869964
getRoundPos() {
870-
var l = (100 - this.lightness) * 2;
871965
var angle = this.hue * 0.01745329251994; // deg to rad
872-
var px = Math.cos(angle) * l;
873-
var py = -Math.sin(angle) * l;
966+
var px = Math.cos(angle) * this.saturation;
967+
var py = -Math.sin(angle) * this.saturation;
874968

875969
this.xPos = (px + 100.0) * 0.5;
876970
this.yPos = (py + 100.0) * 0.5;

src/scripts/options-service.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ export default class AngularColorPickerOptions {
55
disabled: false,
66
hue: true,
77
saturation: false,
8+
lightness: false,
89
alpha: true,
910
round: false,
1011
case: 'upper',

src/scripts/template.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ export default function template($templateCache) {
1717
' \'color-picker-panel-round\': AngularColorPickerController.options.round,' +
1818
' \'color-picker-show-hue\': AngularColorPickerController.options.hue,' +
1919
' \'color-picker-show-saturation\': AngularColorPickerController.options.saturation,' +
20+
' \'color-picker-show-lightness\': AngularColorPickerController.options.lightness,' +
2021
' \'color-picker-show-alpha\': AngularColorPickerController.options.alpha && AngularColorPickerController.options.format !== \'hex\',' +
2122
' \'color-picker-show-inline\': AngularColorPickerController.options.inline,' +
2223
' }">' +
@@ -34,6 +35,9 @@ export default function template($templateCache) {
3435
' <div class="color-picker-saturation" ng-show="AngularColorPickerController.options.saturation">' +
3536
' <div class="color-picker-slider"></div>' +
3637
' </div>' +
38+
' <div class="color-picker-lightness" ng-show="AngularColorPickerController.options.lightness">' +
39+
' <div class="color-picker-slider"></div>' +
40+
' </div>' +
3741
' <div class="color-picker-opacity color-picker-sprite" ng-show="AngularColorPickerController.options.alpha && AngularColorPickerController.options.format !== \'hex\'">' +
3842
' <div class="color-picker-slider"></div>' +
3943
' </div>' +

0 commit comments

Comments
 (0)