Skip to content

Commit

Permalink
🐛 Fix hue-rotate filter not accounted when computing a token color
Browse files Browse the repository at this point in the history
Other filters are still not handled tough.

Fixes #330
  • Loading branch information
abe33 committed Jun 1, 2015
1 parent 610e124 commit 53fa706
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 1 deletion.
59 changes: 58 additions & 1 deletion lib/mixins/dom-styles-reader.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,11 @@ class DOMStylesReader extends Mixin
parent.appendChild(node) if parent?
parent = node

value = getComputedStyle(parent).getPropertyValue(property)
style = getComputedStyle(parent)
filter = style.getPropertyValue('-webkit-filter')
value = style.getPropertyValue(property)
value = @rotateHue(value, filter) if filter.indexOf('hue-rotate') isnt -1

@dummyNode.innerHTML = ''

@constructor.domStylesCache[key][property] = value unless value is ""
Expand Down Expand Up @@ -69,3 +73,56 @@ class DOMStylesReader extends Mixin

@invalidateCache()
@constructor.hasTokenizedOnce = true

rotateHue: (value, filter) ->
[_,_,r,g,b,_,a] = value.match(/rgb(a?)\((\d+), (\d+), (\d+)(, (\d+(\.\d+)?))?\)/)
[_,hue] = filter.match(/hue-rotate\((\d+)deg\)/)

[r,g,b,a,hue] = [r,g,b,a,hue].map(Number)

[r,g,b] = rotate‡(r,g,b,hue)

This comment has been minimized.

Copy link
@xax

xax Jun 1, 2015

There's superfluous character ("") right after the "e" in rotate…

This comment has been minimized.

Copy link
@abe33

abe33 Jun 1, 2015

Author Contributor

Yup, sorry for the inconvenience, I just pushed a patch for that typo.


if isNaN(a)
"rgb(#{r}, #{g}, #{b})"
else
"rgba(#{r}, #{g}, #{b}, #{a})"

# ## ## ######## ## ######## ######## ######## ######
# ## ## ## ## ## ## ## ## ## ## ##
# ## ## ## ## ## ## ## ## ## ##
# ######### ###### ## ######## ###### ######## ######
# ## ## ## ## ## ## ## ## ##
# ## ## ## ## ## ## ## ## ## ##
# ## ## ######## ######## ## ######## ## ## ######

rotate = (r,g,b,angle) ->
clamp = (num) -> Math.ceil(Math.max(0, Math.min(255, num)))
matrix = [1, 0, 0, 0, 1, 0, 0, 0, 1]

# Luminance coefficients.
lumR = 0.2126
lumG = 0.7152
lumB = 0.0722

# Hue rotate coefficients.
hueRotateR = 0.143
hueRotateG = 0.140
hueRotateB = 0.283

cos = Math.cos(angle * Math.PI / 180)
sin = Math.sin(angle * Math.PI / 180)
matrix[0] = lumR + (1 - lumR) * cos - (lumR * sin)
matrix[1] = lumG - (lumG * cos) - (lumG * sin)
matrix[2] = lumB - (lumB * cos) + (1 - lumB) * sin
matrix[3] = lumR - (lumR * cos) + hueRotateR * sin
matrix[4] = lumG + (1 - lumG) * cos + hueRotateG * sin
matrix[5] = lumB - (lumB * cos) - (hueRotateB * sin)
matrix[6] = lumR - (lumR * cos) - ((1 - lumR) * sin)
matrix[7] = lumG - (lumG * cos) + lumG * sin
matrix[8] = lumB + (1 - lumB) * cos + lumB * sin

R = clamp(matrix[0] * r + matrix[1] * g + matrix[2] * b)
G = clamp(matrix[3] * r + matrix[4] * g + matrix[5] * b)
B = clamp(matrix[6] * r + matrix[7] * g + matrix[8] * b)

[R,G,B]
53 changes: 53 additions & 0 deletions spec/minimap-element-spec.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,59 @@ describe 'MinimapElement', ->
it 'requests an update', ->
expect(minimapElement.frameRequested).toBeTruthy()

# ###### ###### ######
# ## ## ## ## ## ##
# ## ## ##
# ## ###### ######
# ## ## ##
# ## ## ## ## ## ##
# ###### ###### ######

fdescribe 'with css filters', ->
describe 'when a hue-rotate filter is applied to a rgb color', ->
[additionnalStyleNode] = []
beforeEach ->
minimapElement.invalidateCache()

additionnalStyleNode = document.createElement('style')
additionnalStyleNode.textContent = """
#{stylesheet}
.editor {
color: red;
-webkit-filter: hue-rotate(180deg);
}
"""

jasmineContent.appendChild(additionnalStyleNode)

it 'computes the new color by applying the hue rotation', ->
nextAnimationFrame()
expect(minimapElement.retrieveStyleFromDom(['.editor'], 'color')).toEqual("rgb(0, #{0x6d}, #{0x6d})")

describe 'when a hue-rotate filter is applied to a rgba color', ->
[additionnalStyleNode] = []

beforeEach ->
minimapElement.invalidateCache()

additionnalStyleNode = document.createElement('style')
additionnalStyleNode.textContent = """
#{stylesheet}
.editor {
color: rgba(255,0,0,0);
-webkit-filter: hue-rotate(180deg);
}
"""

jasmineContent.appendChild(additionnalStyleNode)

it 'computes the new color by applying the hue rotation', ->
nextAnimationFrame()
expect(minimapElement.retrieveStyleFromDom(['.editor'], 'color')).toEqual("rgba(0, #{0x6d}, #{0x6d}, 0)")


# ## ## ######## ######## ### ######## ########
# ## ## ## ## ## ## ## ## ## ##
# ## ## ## ## ## ## ## ## ## ##
Expand Down

0 comments on commit 53fa706

Please sign in to comment.