-
Notifications
You must be signed in to change notification settings - Fork 0
/
letterming.js
94 lines (81 loc) · 2.38 KB
/
letterming.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
/* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/ for more details.
*/
/**
* Letterming 0.1.0
*
* Inspired on the original Lettering.js jQuery plugin
* https://github.com/davatron5000/Lettering.js
*/
export default class Letterming {
constructor(element, method) {
this.element = element
this.methods = this.splitMethods()
if (method && this.methods[method]) {
this.methods[method]()
} else if (method === 'letters' || ! method) {
this.methods.init()
} else {
throw Error('Method ' + method + ' does not exist on Letterming')
}
}
splitMethods() {
return {
init: () => {
return this.inject('char', '')
},
words: () => {
return this.inject('word', /\s/g)
},
lines: () => {
return this.inject('line', /\n/g)
}
};
}
inject(classname, splitter) {
// base64 of string 'newLineMark' used
// to avoid losing `<br>` tags inside `element`
const nl = 'bmV3TGluZU1hcmsK'
const re = new RegExp(nl, 'g')
let text = this.element.textContent
// fix duplicated spacing chars
text = text.trim()
.replace(/\ +/g, ' ')
.replace(/\s*\n\s*/g, '\n')
// mark new line positions
if (splitter !== '') {
text = text.replace(/\n/g, nl + '\n')
}
let split = []
if (!splitter) {
split = [...text]
split = split.map(c => c === ' ' ? ' ' : c);
} else {
split = text.split(splitter)
}
// fix char count on the classname
let indexOffset = 1
split.forEach(function(element, index, fragment) {
if (!splitter && element === '\n') {
indexOffset--
fragment[index] = '<br>'
return
}
let joiner = ''
if (splitter) {
if (element.indexOf(nl) >= 0) {
element = element.replace(nl, '')
joiner = '<br> '
} else {
joiner = ' '
}
}
fragment[index] = `<span class="${classname+(index+indexOffset)}" aria-hidden="true">${element}</span>${joiner}`
});
this.element.setAttribute('aria-label', text.replace(re, ' '))
this.element.innerHTML = split.join('');
}
}