bounty
Crazy SVG odometer effect library
Demo
Usage
bounty.default({ el: '.js-bounty', value: '£42,000,000' });
Usage
bounty.default({
el: '.js-bounty',
value: '£42,000,000',
lineHeight: 1.35,
letterSpacing: 1,
animationDelay: 100,
letterAnimationDelay: 100
});
Customized by CSS
.js-bounty {
font-size: 60px;
font-family: Roboto;
fill: #fff;
text-shadow: 1px 1px 5px rgba(0, 0, 0, 0.5);
}
Customized by CSS
Why SVG?
Why SVG?
-
I ❤️ using SVG scalable beautiful vectors
-
SVG Filters can be applied to HTML nodes as well*
-
Masks clipping, gradients
-
Easily customizable fill, stroke
-
Drawings shapes, lines
-
Great control over views and elements
* Still lack of support custom filters in many browsers
How it's made
Clip Region
More Rotation
Motion Blur
Gradient Mask
Implementation
-
Selection Module DOM manipulation
-
Transition Module
-
Core
Selection Module
Strongly inspired by D3.js syntax and helpers
d3.select("body")
.selectAll("p")
.data([4, 8, 15, 16, 23, 42])
.enter().append("p")
.text(function(d) { return "I’m number " + d + "!"; });
Selection Module
Function Bind Syntax
obj::func
// is equivalent to:
func.bind(obj)
obj::func(val)
// is equivalent to:
func.call(obj, val)
::obj.func(val)
// is equivalent to:
func.call(obj, val)
Selection Module
Function Bind Syntax
// Function Bind Syntax
::console.log
//is equivalent to:
console.log.bind(console)
Method extraction
Selection Module
Function Bind Syntax
Virtual method
const {
map,
forEach
} = Array.prototype;
// Function Bind Syntax
getPlayers()
::map(x => x.stop())
::forEach(x => log(x));
const {
map,
forEach
} = Array.prototype;
// ES2015
let _ = getPlayers();
_ = map.call(_, x => x.stop());
_ = forEach.call(_, x => log(x));
Selection Module
Implementation
export default function (value) {
this.textContent = value;
return this;
}
text
Selection Module
Implementation
export default function (name, value) {
this.setAttribute(name, value);
return this;
}
attr
Selection Module
Implementation
export default function (name, value, priority = '') {
this.style.setProperty(name, value, priority);
return this;
}
style
Selection Module
Results
const setViewBox = (svg, width, height) => svg
::attr('width', width)
::attr('height', height)
::attr('viewBox', `0 0 ${width} ${height}`)
::style('overflow', 'hidden');
selection usage
Filters
Implementation
const motionBlur = (defs, id) => defs::append('filter')
::attr('id', `motionFilter-${id}`)
::attr('width', '300%')
::attr('x', '-100%')
::append('feGaussianBlur')
::attr('class', 'blurValues')
::attr('in', 'SourceGraphic')
::attr('stdDeviation', '0 0');
Motion Blur
Filters
Results
<filter id="motionFilter-1-1475053429366"
width="300%"
x="-100%">
<feGaussianBlur class="blurValues"
in="SourceGraphic"
stdDeviation="0 0">
</feGaussianBlur>
</filter>
Motion Blur Markup
Issues
Font Loading API only present in Chrome and FF
CSS Text Shadow on SVG nodes safari, IE
Filters clipping area all
Optimizations
chars.forEach(char => {
// Read
const { width } = char.node.getBBox();
char.offset.x = canvasWidth;
canvasWidth += width + letterSpacing;
// Write
char.node::attr('transform', `translate(${char.offset.x}, ${char.offset.y})`);
});
Before
Optimizations
chars.forEach(char => {
// Read
const { width } = char.node.getBBox();
char.offset.x = canvasWidth;
canvasWidth += width + letterSpacing;
});
chars.forEach(char => {
// Write
char.node::attr('transform', `translate(${char.offset.x}, ${char.offset.y})`);
});
After
bounty
By coderitual
bounty
- 13,895