checkpoint colors
This commit is contained in:
@@ -100,17 +100,26 @@ class Color():
|
||||
def hue(self, *args):
|
||||
"""
|
||||
"""
|
||||
pass
|
||||
if args:
|
||||
h, l, s = self._hextohls(args[0])
|
||||
return round(h * 360, 3)
|
||||
raise ValueError('Illegal color values')
|
||||
|
||||
def saturation(self, *args):
|
||||
"""
|
||||
"""
|
||||
pass
|
||||
if args:
|
||||
h, l, s = self._hextohls(args[0])
|
||||
return s * 100
|
||||
raise ValueError('Illegal color values')
|
||||
|
||||
def lightness(self, *args):
|
||||
"""
|
||||
"""
|
||||
pass
|
||||
if args:
|
||||
h, l, s = self._hextohls(args[0])
|
||||
return l * 100
|
||||
raise ValueError('Illegal color values')
|
||||
|
||||
def opacity(self, *args):
|
||||
"""
|
||||
@@ -156,6 +165,7 @@ class Color():
|
||||
|
||||
def grayscale(self, *args):
|
||||
"""
|
||||
Simply 100% desaturate.
|
||||
"""
|
||||
if len(args) == 2:
|
||||
return self.desaturate(args[0], 100)
|
||||
@@ -163,6 +173,7 @@ class Color():
|
||||
|
||||
def greyscale(self, *args):
|
||||
"""
|
||||
Wrapper for grayscale
|
||||
"""
|
||||
return self.grayscale(*args)
|
||||
|
||||
@@ -182,22 +193,43 @@ class Color():
|
||||
|
||||
def mix(self, *args):
|
||||
"""
|
||||
Mix to colors
|
||||
This algorithm factors in both the user-provided weight
|
||||
and the difference between the alpha values of the two colors
|
||||
to decide how to perform the weighted average of the two RGB values.
|
||||
|
||||
It works by first normalizing both parameters to be within [-1, 1],
|
||||
where 1 indicates "only use color1", -1 indicates "only use color 0",
|
||||
and all values in between indicated a proportionately weighted average.
|
||||
|
||||
Once we have the normalized variables w and a,
|
||||
we apply the formula (w + a)/(1 + w*a)
|
||||
to get the combined weight (in [-1, 1]) of color1.
|
||||
This formula has two especially nice properties:
|
||||
|
||||
* When either w or a are -1 or 1, the combined weight is also that number
|
||||
(cases where w * a == -1 are undefined, and handled as a special case).
|
||||
|
||||
* When a is 0, the combined weight is w, and vice versa
|
||||
|
||||
Finally, the weight of color1 is renormalized to be within [0, 1]
|
||||
and the weight of color2 is given by 1 minus the weight of color1.
|
||||
|
||||
Copyright (c) 2006-2009 Hampton Catlin, Nathan Weizenbaum, and Chris Eppstein
|
||||
http://sass-lang.com
|
||||
"""
|
||||
if len(args) >= 2:
|
||||
try:
|
||||
c1, c2, w = args
|
||||
if type(w) == str: w = int(w.strip('%'))
|
||||
w = ((w / 100.0) * 2) - 1
|
||||
except ValueError:
|
||||
c1, c2 = args
|
||||
w = 1
|
||||
w = 50
|
||||
if type(w) == str: w = int(w.strip('%'))
|
||||
w = ((w / 100.0) * 2) - 1
|
||||
rgb1 = self._hextorgb(c1)
|
||||
rgb2 = self._hextorgb(c2)
|
||||
a = 0
|
||||
w1 = (((w if (w * a) == -1 else (w + a)) / (1 + w * a)) + 1) / 2.0
|
||||
w1 = (((w if w * a == -1 else w + a) / (1 + w * a)) + 1)
|
||||
w1 = w1 / 2.0
|
||||
w2 = 1 - w1
|
||||
rgb = [
|
||||
rgb1[0] * w1 + rgb2[0] * w2,
|
||||
|
||||
154
lesscpy/test/css/colors.css
Normal file
154
lesscpy/test/css/colors.css
Normal file
@@ -0,0 +1,154 @@
|
||||
#yellow #short {
|
||||
color: #ffeeaa;
|
||||
}
|
||||
#yellow #long {
|
||||
color: #ffeeaa;
|
||||
}
|
||||
#blue #short {
|
||||
color: #0000ff;
|
||||
}
|
||||
#blue #long {
|
||||
color: #0000ff;
|
||||
}
|
||||
#overflow .a {
|
||||
color: #000000;
|
||||
}
|
||||
#overflow .b {
|
||||
color: #ffffff;
|
||||
}
|
||||
#overflow .c {
|
||||
color: #ffffff;
|
||||
}
|
||||
#overflow .d {
|
||||
color: #00ff00;
|
||||
}
|
||||
#grey {
|
||||
color: #c8c8c8;
|
||||
}
|
||||
#808080 {
|
||||
color: #808080;
|
||||
}
|
||||
#00ff00 {
|
||||
color: #00ff00;
|
||||
}
|
||||
.hsl {
|
||||
color: #ffffff;
|
||||
color: #ffffff;
|
||||
color: #000000;
|
||||
color: #000000;
|
||||
}
|
||||
.saturate {
|
||||
color: #565454;
|
||||
color: #5e4c4c;
|
||||
color: #664444;
|
||||
color: #773333;
|
||||
color: #882222;
|
||||
color: #aa0000;
|
||||
color: #000000;
|
||||
color: #000000;
|
||||
color: #ffffff;
|
||||
color: #ffffff;
|
||||
color: #29332f;
|
||||
color: #243830;
|
||||
color: #203c31;
|
||||
color: #174533;
|
||||
color: #0d4f35;
|
||||
color: #005c37;
|
||||
}
|
||||
.desaturate {
|
||||
color: #555555;
|
||||
color: #555555;
|
||||
color: #555555;
|
||||
color: #555555;
|
||||
color: #555555;
|
||||
color: #555555;
|
||||
color: #000000;
|
||||
color: #000000;
|
||||
color: #ffffff;
|
||||
color: #ffffff;
|
||||
color: #29332f;
|
||||
color: #2e2e2e;
|
||||
color: #2e2e2e;
|
||||
color: #2e2e2e;
|
||||
color: #2e2e2e;
|
||||
color: #2e2e2e;
|
||||
}
|
||||
.lighten {
|
||||
color: #585858;
|
||||
color: #6e6e6e;
|
||||
color: #888888;
|
||||
color: #bbbbbb;
|
||||
color: #eeeeee;
|
||||
color: #ffffff;
|
||||
color: #ffffff;
|
||||
color: #000000;
|
||||
color: #ffffff;
|
||||
color: #ffffff;
|
||||
color: #2b3632;
|
||||
color: #404f49;
|
||||
color: #566c63;
|
||||
color: #88a096;
|
||||
color: #c1cdc8;
|
||||
color: #ffffff;
|
||||
}
|
||||
.lighten {
|
||||
color: #525252;
|
||||
color: #3b3b3b;
|
||||
color: #222222;
|
||||
color: #000000;
|
||||
color: #000000;
|
||||
color: #000000;
|
||||
color: #000000;
|
||||
color: #000000;
|
||||
color: #000000;
|
||||
color: #ffffff;
|
||||
color: #27302c;
|
||||
color: #121715;
|
||||
color: #000000;
|
||||
color: #000000;
|
||||
color: #000000;
|
||||
color: #000000;
|
||||
}
|
||||
.spin {
|
||||
color: #555555;
|
||||
color: #555555;
|
||||
color: #555555;
|
||||
color: #555555;
|
||||
color: #555555;
|
||||
color: #555555;
|
||||
color: #000000;
|
||||
color: #000000;
|
||||
color: #ffffff;
|
||||
color: #ffffff;
|
||||
color: #29332f;
|
||||
color: #29332d;
|
||||
color: #293332;
|
||||
color: #2a3329;
|
||||
color: #292d33;
|
||||
color: #2c2933;
|
||||
}
|
||||
.grayscale {
|
||||
color: #000000;
|
||||
color: #000000;
|
||||
color: #ffffff;
|
||||
color: #ffffff;
|
||||
color: #2e2e2e;
|
||||
color: #2e2e2e;
|
||||
color: #2e2e2e;
|
||||
color: #2e2e2e;
|
||||
color: #2e2e2e;
|
||||
color: #2e2e2e;
|
||||
}
|
||||
.mix {
|
||||
color: #7f007f;
|
||||
color: #7f7f7f;
|
||||
color: #7f9055;
|
||||
color: #3f00bf;
|
||||
color: #ff0000;
|
||||
color: #0000ff;
|
||||
}
|
||||
.vars {
|
||||
color: #f6430f;
|
||||
background-color: #f8b38d;
|
||||
color: #f1dfda;
|
||||
}
|
||||
20
lesscpy/test/css/colors.min.css
vendored
Normal file
20
lesscpy/test/css/colors.min.css
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
#yellow #short{color:#ffeeaa;}
|
||||
#yellow #long{color:#ffeeaa;}
|
||||
#blue #short{color:#0000ff;}
|
||||
#blue #long{color:#0000ff;}
|
||||
#overflow .a{color:#000000;}
|
||||
#overflow .b{color:#ffffff;}
|
||||
#overflow .c{color:#ffffff;}
|
||||
#overflow .d{color:#00ff00;}
|
||||
#grey{color:#c8c8c8;}
|
||||
#808080{color:#808080;}
|
||||
#00ff00{color:#00ff00;}
|
||||
.hsl{color:#ffffff;color:#ffffff;color:#000000;color:#000000;}
|
||||
.saturate{color:#565454;color:#5e4c4c;color:#664444;color:#773333;color:#882222;color:#aa0000;color:#000000;color:#000000;color:#ffffff;color:#ffffff;color:#29332f;color:#243830;color:#203c31;color:#174533;color:#0d4f35;color:#005c37;}
|
||||
.desaturate{color:#555555;color:#555555;color:#555555;color:#555555;color:#555555;color:#555555;color:#000000;color:#000000;color:#ffffff;color:#ffffff;color:#29332f;color:#2e2e2e;color:#2e2e2e;color:#2e2e2e;color:#2e2e2e;color:#2e2e2e;}
|
||||
.lighten{color:#585858;color:#6e6e6e;color:#888888;color:#bbbbbb;color:#eeeeee;color:#ffffff;color:#ffffff;color:#000000;color:#ffffff;color:#ffffff;color:#2b3632;color:#404f49;color:#566c63;color:#88a096;color:#c1cdc8;color:#ffffff;}
|
||||
.lighten{color:#525252;color:#3b3b3b;color:#222222;color:#000000;color:#000000;color:#000000;color:#000000;color:#000000;color:#000000;color:#ffffff;color:#27302c;color:#121715;color:#000000;color:#000000;color:#000000;color:#000000;}
|
||||
.spin{color:#555555;color:#555555;color:#555555;color:#555555;color:#555555;color:#555555;color:#000000;color:#000000;color:#ffffff;color:#ffffff;color:#29332f;color:#29332d;color:#293332;color:#2a3329;color:#292d33;color:#2c2933;}
|
||||
.grayscale{color:#000000;color:#000000;color:#ffffff;color:#ffffff;color:#2e2e2e;color:#2e2e2e;color:#2e2e2e;color:#2e2e2e;color:#2e2e2e;color:#2e2e2e;}
|
||||
.mix{color:#7f007f;color:#7f7f7f;color:#7f9055;color:#3f00bf;color:#ff0000;color:#0000ff;}
|
||||
.vars{color:#f6430f;background-color:#f8b38d;color:#f1dfda;}
|
||||
20
lesscpy/test/less/colors-alpha.less
Normal file
20
lesscpy/test/less/colors-alpha.less
Normal file
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
Color alpha-channel
|
||||
*/
|
||||
#hsla_rgba {
|
||||
color: hsla(31, 1%, 4%, 60%);
|
||||
color: hsla(31, 10%, 4%, 60%);
|
||||
color: hsla(31, 30%, 4%, 60%);
|
||||
color: hsla(31, 60%, 4%, 60%);
|
||||
color: hsla(31, 100%, 4%, 60%);
|
||||
|
||||
color: rgba(0, 0, 255, 0.1);
|
||||
color: rgba(10,10,10,0.6);
|
||||
color: rgba(11,10,9,0.6);
|
||||
color: rgba(13,10,7,0.6);
|
||||
color: rgba(16,10,4,0.6);
|
||||
color: rgba(20,11,0,0.6);
|
||||
}
|
||||
#argb {
|
||||
color: argb(rgba(0, 0, 255, 0.1));
|
||||
}
|
||||
@@ -117,22 +117,22 @@
|
||||
color: darken(#29332f, 100%);
|
||||
}
|
||||
.spin {
|
||||
color: spin(#555, 1%);
|
||||
color: spin(#555, 10%);
|
||||
color: spin(#555, 20%);
|
||||
color: spin(#555, 40%);
|
||||
color: spin(#555, 60%);
|
||||
color: spin(#555, 100%);
|
||||
color: spin(#000, 100%);
|
||||
color: spin(#000, 0%);
|
||||
color: spin(#fff, 100%);
|
||||
color: spin(#fff, 0%);
|
||||
color: spin(#29332f, 1%);
|
||||
color: spin(#29332f, 10%);
|
||||
color: spin(#29332f, 20%);
|
||||
color: spin(#29332f, 40%);
|
||||
color: spin(#29332f, 60%);
|
||||
color: spin(#29332f, 100%);
|
||||
color: spin(#555, 1);
|
||||
color: spin(#555, -10);
|
||||
color: spin(#555, 20);
|
||||
color: spin(#555, -40);
|
||||
color: spin(#555, 60);
|
||||
color: spin(#555, -100);
|
||||
color: spin(#000, 100);
|
||||
color: spin(#000, 0);
|
||||
color: spin(#fff, 100);
|
||||
color: spin(#fff, 0);
|
||||
color: spin(#29332f, 1);
|
||||
color: spin(#29332f, -10);
|
||||
color: spin(#29332f, 20);
|
||||
color: spin(#29332f, -40);
|
||||
color: spin(#29332f, 60);
|
||||
color: spin(#29332f, 100);
|
||||
}
|
||||
.grayscale {
|
||||
color: grayscale(#000, 100%);
|
||||
@@ -146,4 +146,21 @@
|
||||
color: grayscale(#29332f, 60%);
|
||||
color: grayscale(#29332f, 100%);
|
||||
}
|
||||
|
||||
.mix {
|
||||
color: mix(#f00, #00f);
|
||||
color: mix(#f00, #0ff);
|
||||
color: mix(#f70, #0aa);
|
||||
color: mix(#f00, #00f, 25%);
|
||||
color: mix(#f00, #00f, 100%);
|
||||
color: mix(#f00, #00f, 0%);
|
||||
}
|
||||
/*
|
||||
Variables
|
||||
*/
|
||||
@base: #f04615;
|
||||
.vars {
|
||||
color: saturate(@base, 5%);
|
||||
background-color: lighten(spin(@base, 8), 25%);
|
||||
@new: hsl(hue(@base), 45%, 90%);
|
||||
color: @new;
|
||||
}
|
||||
|
||||
162
lesscpy/test/testcolor.py
Normal file
162
lesscpy/test/testcolor.py
Normal file
@@ -0,0 +1,162 @@
|
||||
"""
|
||||
lesscpy tests.
|
||||
"""
|
||||
import unittest
|
||||
if __name__ == '__main__':
|
||||
import bootstrap
|
||||
from lesscpy.lessc import color
|
||||
|
||||
|
||||
class TestLessColor(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.color = color.Color()
|
||||
|
||||
def test_rgb(self):
|
||||
test = self.color.rgb
|
||||
for r, g, b, v in [
|
||||
(255,255,255,'#ffffff'),
|
||||
(100,100,100,'#646464'),
|
||||
(0,0,0,'#000000'),
|
||||
('70%','70%','70%', '#b2b2b2'),
|
||||
('1%','1%','1%', '#020202'),
|
||||
('100%','100%','100%', '#ffffff'),
|
||||
('0%','0%','0%', '#000000'),
|
||||
]:
|
||||
self.assertEqual(test(r, g, b), v)
|
||||
for args in [
|
||||
(255,255,256),
|
||||
(0,-1,0),
|
||||
('100%', '100%', 200),
|
||||
('100%', '100%', '200%'),
|
||||
]:
|
||||
self.assertRaises(ValueError, test, args)
|
||||
|
||||
def test_rgba(self):
|
||||
test = self.color.rgba
|
||||
for r, g, b, a, v in [
|
||||
(255,255,255,255,'#ffffffff'),
|
||||
(100,100,100,100,'#64646464'),
|
||||
(0,0,0,0,'#00000000'),
|
||||
('70%','70%','70%', '70%', '#b2b2b2b2'),
|
||||
('1%','1%','1%', '1%', '#02020202'),
|
||||
('100%','100%','100%','100%', '#ffffffff'),
|
||||
('0%','0%','0%','0%', '#00000000'),
|
||||
]:
|
||||
self.assertEqual(test(r, g, b, a), v)
|
||||
for args in [
|
||||
(255,255,255,256),
|
||||
(0,0,0,-1),
|
||||
('100%', '100%', '100%', 200),
|
||||
('100%', '100%', '100%', '200%'),
|
||||
]:
|
||||
self.assertRaises(ValueError, test, args)
|
||||
|
||||
def test_hsl(self):
|
||||
"""
|
||||
"""
|
||||
test = self.color.hsl
|
||||
for h, s, l, v in [
|
||||
(31, '1%', '4%', '#0a0a0a'),
|
||||
(0, '100%', '100%', '#ffffff'),
|
||||
(100, '100%', '100%', '#ffffff'),
|
||||
(0, '0%', '0%', '#000000'),
|
||||
(100, '0%', '0%', '#000000'),
|
||||
]:
|
||||
self.assertEqual(test(h, s, l), v)
|
||||
|
||||
def test_hsla(self):
|
||||
test = self.color.hsla
|
||||
for h, s, l, a, v in [
|
||||
(31, '1%', '4%', '0%', 'rgba(10,10,10,0.0)'),
|
||||
(31, '30%', '4%', '1%', 'rgba(13,10,7,0.01)'),
|
||||
(31, '60%', '4%', '20%', 'rgba(16,10,4,0.2)'),
|
||||
(31, '90%', '4%', '60%', 'rgba(19,11,1,0.6)'),
|
||||
(31, '100%', '4%', '100%', 'rgba(20,11,0,1.0)'),
|
||||
]:
|
||||
self.assertEqual(test(h, s, l, a), v)
|
||||
|
||||
def test_fmt(self):
|
||||
test = self.color.fmt
|
||||
self.assertEqual(test('#000'), '#000000')
|
||||
self.assertEqual(test('#000000'), '#000000')
|
||||
self.assertEqual(test('#0000'), '#00000000')
|
||||
self.assertEqual(test('#00000000'), '#00000000')
|
||||
self.assertEqual(test('#AAA'), '#aaaaaa')
|
||||
self.assertEqual(test('#Abc'), '#aabbcc')
|
||||
self.assertEqual(test('#AbCdEf'), '#abcdef')
|
||||
self.assertRaises(ValueError, test, '#xxx')
|
||||
self.assertRaises(ValueError, test, None)
|
||||
self.assertRaises(ValueError, test, 'aabbcc')
|
||||
self.assertRaises(ValueError, test, '#4aabbcc')
|
||||
|
||||
def test_saturate(self):
|
||||
test = self.color.saturate
|
||||
for c, p, v in [
|
||||
('#555', '1%', '#565454'),
|
||||
('#555', '10%', '#5e4c4c'),
|
||||
('#555', '20%', '#664444'),
|
||||
('#555', '40%', '#773333'),
|
||||
('#555', '60%', '#882222'),
|
||||
('#555', '100%', '#aa0000'),
|
||||
('#000', '100%', '#000000'),
|
||||
('#000', '0%', '#000000'),
|
||||
('#fff', '100%', '#ffffff'),
|
||||
('#fff', '0%', '#ffffff'),
|
||||
('#29332f', '1%', '#29332f'),
|
||||
('#29332f', '10%', '#243830'),
|
||||
('#29332f', '20%', '#203c31'),
|
||||
('#29332f', '40%', '#174533'),
|
||||
('#29332f', '60%', '#0d4f35'),
|
||||
('#29332f', '100%', '#005c37'),
|
||||
|
||||
]:
|
||||
self.assertEqual(test(c, p), v, v)
|
||||
|
||||
def test_desaturate(self):
|
||||
test = self.color.desaturate
|
||||
for c, p, v in [
|
||||
('#555', '1%', '#555555'),
|
||||
('#555', '10%', '#555555'),
|
||||
('#555', '20%', '#555555'),
|
||||
('#555', '40%', '#555555'),
|
||||
('#555', '60%', '#555555'),
|
||||
('#555', '100%', '#555555'),
|
||||
('#000', '100%', '#000000'),
|
||||
('#000', '0%', '#000000'),
|
||||
('#fff', '100%', '#ffffff'),
|
||||
('#fff', '0%', '#ffffff'),
|
||||
('#29332f', '1%', '#29332f'),
|
||||
('#29332f', '10%', '#2e2e2e'),
|
||||
('#29332f', '20%', '#2e2e2e'),
|
||||
('#29332f', '40%', '#2e2e2e'),
|
||||
('#29332f', '60%', '#2e2e2e'),
|
||||
('#29332f', '100%', '#2e2e2e'),
|
||||
|
||||
]:
|
||||
self.assertEqual(test(c, p), v, v)
|
||||
|
||||
def test_spin(self):
|
||||
test = self.color.spin
|
||||
for c, p, v in [
|
||||
('#555', '1%', '#555555'),
|
||||
('#555', '10%', '#555555'),
|
||||
('#555', '20%', '#555555'),
|
||||
('#555', '40%', '#555555'),
|
||||
('#555', '60%', '#555555'),
|
||||
('#555', '100%', '#555555'),
|
||||
('#000', '100%', '#000000'),
|
||||
('#000', '0%', '#000000'),
|
||||
('#fff', '100%', '#ffffff'),
|
||||
('#fff', '0%', '#ffffff'),
|
||||
('#29332f', '1%', '#29332f'),
|
||||
('#29332f', '10%', '#293331'),
|
||||
('#29332f', '20%', '#293332'),
|
||||
('#29332f', '40%', '#293033'),
|
||||
('#29332f', '60%', '#292d33'),
|
||||
('#29332f', '100%', '#2c2933'),
|
||||
|
||||
]:
|
||||
self.assertEqual(test(c, p), v, v)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user