Created
November 3, 2022 15:42
-
-
Save amw/842b1087167c9f682e3bd5144c4836df to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<title>Broken CSS Filters Referencing SVG</title> | |
<style> | |
body { | |
display: grid; | |
grid-template-columns: max-content 25vh; | |
grid-template-rows: 2em 25vh 25vh 25vh; | |
align-items: center; | |
gap: 0 2em; | |
} | |
img, svg { | |
height: 25vh; | |
} | |
</style> | |
</head> | |
<body> | |
<label>Gamma</label> | |
<input id="slider" type="range" min="0.01" max="2" step="0.01" value="1"> | |
<label>Created #refFilter:</label> | |
<div id="container"></div> | |
<label>SVG using #refFilter:</label> | |
<svg id="gammaTarget1" viewBox="0 0 10 10" xmlns="http://www.w3.org/2000/svg"> | |
<defs> | |
<linearGradient id="exampleGradient"> | |
<stop offset="5%" stop-color="#333"></stop> | |
<stop offset="95%" stop-color="#ccc"></stop> | |
</linearGradient> | |
</defs> | |
<circle cx="5" cy="5" r="5" fill="url('#exampleGradient')" /> | |
</svg> | |
<label>IMG using #refFilter:</label> | |
<img id="gammaTarget2" src="data:image/svg+xml,%3Csvg viewBox='0 0 10 10' xmlns='http://www.w3.org/2000/svg'%3E%3Cdefs%3E%3ClinearGradient id='g'%3E%3Cstop offset='5%25' stop-color='%23333'%3E%3C/stop%3E%3Cstop offset='95%25' stop-color='%23ccc'%3E%3C/stop%3E%3C/linearGradient%3E%3C/defs%3E%3Ccircle cx='5' cy='5' r='5' fill='url(%23g)' /%3E%3C/svg%3E" /> | |
</body> | |
<script> | |
class GammaSlider { | |
constructor(element) { | |
this.value = '1.00' | |
this.filterId = 'refFilter' | |
this.createFilter() | |
this.updateRequest = null | |
element.value = this.value | |
element.addEventListener('input', (event) => this.onslide(event)) | |
} | |
onslide(event) { | |
this.value = event.target.value | |
this.updateFilter() | |
const elements = Array.from(document.querySelectorAll(`.${this.filterId}`)) | |
for ( const element of elements ) { | |
element.style.filter = '' | |
element.style.webkitFilter = '' | |
} | |
if ( !this.updateRequest ) { | |
this.updateRequest = requestAnimationFrame(() => { | |
for ( const element of elements ) { | |
element.style.filter = `url(#${this.filterId})` | |
element.style.webkitFilter = `url(#${this.filterId})` | |
} | |
this.updateRequest = null | |
}) | |
} | |
} | |
appliesTo(element) { | |
element.style.filter = `url(#${this.filterId})` | |
element.style.webkitFilter = `url(#${this.filterId})` | |
element.classList.add(this.filterId) | |
} | |
createFilter() { | |
if ( this.svg ) { | |
this.svg.remove() | |
} | |
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg') | |
svg.viewBox.baseVal.width = 10 | |
svg.viewBox.baseVal.height = 10 | |
svg.innerHTML = | |
`<filter id="${this.filterId}"> | |
<feComponentTransfer> | |
<feFuncR type="gamma" exponent="${this.value}"></feFuncR> | |
<feFuncG type="gamma" exponent="${this.value}"></feFuncG> | |
<feFuncB type="gamma" exponent="${this.value}"></feFuncB> | |
</feComponentTransfer> | |
</filter> | |
<defs> | |
<linearGradient id="localGradient"> | |
<stop offset="5%" stop-color="#333" /> | |
<stop offset="95%" stop-color="#ccc" /> | |
</linearGradient> | |
</defs> | |
<circle cx="5" cy="5" r="5" fill="url(#localGradient)" filter="url(#${this.filterId})" />` | |
this.svg = svg | |
this.filter = svg.querySelector('filter') | |
document.querySelector('#container').appendChild(svg) | |
} | |
updateFilter() { | |
this.filter.innerHTML = | |
`<feComponentTransfer> | |
<feFuncR type="gamma" exponent="${this.value}"></feFuncR> | |
<feFuncG type="gamma" exponent="${this.value}"></feFuncG> | |
<feFuncB type="gamma" exponent="${this.value}"></feFuncB> | |
</feComponentTransfer>` | |
} | |
} | |
const slider = new GammaSlider(document.querySelector('#slider')) | |
slider.appliesTo(document.querySelector('#gammaTarget1')) | |
slider.appliesTo(document.querySelector('#gammaTarget2')) | |
</script> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment