Something went wrong. Try again.
This repository has no description
Something went wrong. Try again.
2.1 kB · 41 lines
Python
at fixes-stack
123456789101112131415161718192021222324252627282930313233343536373839404142import math,sysdef srgb(h): h=h.lstrip('#'); return [int(h[i:i+2],16)/255 for i in (0,2,4)]def lin(c): return c/12.92 if c<=0.04045 else ((c+0.055)/1.055)**2.4def oklab(hex_): r,g,b=[lin(c) for c in srgb(hex_)] l=0.4122214708*r+0.5363325363*g+0.0514459929*b m=0.2119034982*r+0.6806995451*g+0.1073969566*b s=0.0883024619*r+0.2817188376*g+0.6299787005*b l,m,s=[x**(1/3) if x>0 else -((-x)**(1/3)) for x in (l,m,s)] return (0.2104542553*l+0.7936177850*m-0.0040720468*s, 1.9779984951*l-2.4285922050*m+0.4505937099*s, 0.0259040371*l+0.7827717662*m-0.8086757660*s)def lum(hex_): r,g,b=[lin(c) for c in srgb(hex_)] return 0.2126*r+0.7152*g+0.0722*bdef contrast(a,b): l1,l2=sorted([lum(a),lum(b)],reverse=True); return (l1+0.05)/(l2+0.05)def lch(hex_): L,A,B=oklab(hex_); return L, math.hypot(A,B), (math.degrees(math.atan2(B,A))%360)def de(a,b): x,y=oklab(a),oklab(b); return 100*math.dist(x,y)def ordinal(ramp,surface): print(f" ordinal ramp on {surface}: {len(ramp)} steps") Ls=[lch(c)[0] for c in ramp] mono = all(Ls[i]>Ls[i+1] for i in range(len(Ls)-1)) or all(Ls[i]<Ls[i+1] for i in range(len(Ls)-1)) print(f" [{'PASS' if mono else 'FAIL'}] lightness monotone L={[round(x,3) for x in Ls]}") gaps=[abs(Ls[i]-Ls[i+1]) for i in range(len(Ls)-1)] ok=all(g>=0.06 for g in gaps) print(f" [{'PASS' if ok else 'FAIL'}] adjacent dL >= 0.06 gaps={[round(g,3) for g in gaps]}") end=max(ramp,key=lambda c:abs(lum(c)-lum(surface))) near=min(ramp,key=lambda c:abs(lum(c)-lum(surface))) cr=contrast(near,surface) print(f" [{'PASS' if cr>=2 else 'FAIL'}] surface-end contrast {near} at {cr:.2f}:1") hs=[lch(c)[2] for c in ramp]; spread=max(hs)-min(hs) print(f" [{'PASS' if spread<=25 else 'WARN'}] single hue spread {spread:.0f}deg hues={[round(h) for h in hs]}") ch=[lch(c)[1] for c in ramp] print(f" chroma={[round(c,3) for c in ch]}")if __name__=="__main__": surface=sys.argv[2] if len(sys.argv)>2 else "#000000" ordinal(sys.argv[1].split(","),surface)