将 Minecraft 颜色代码翻译成 HTML
Translating Minecraft Color Codes into HTML
最近,我正在尝试将 Minecraft MOTD 转换为 Plain HTML。 Minecraft MOTD 是基本文本,用 Minecraft 颜色代码表示颜色变化。
示例:“§d§l枢纽§8:§6§oO_O §a§l[变异星期一]”
翻译:<span style='color:pink'><b>The Nexus</b></span><span style='color:gray'>:</span>...
等等...所以基本上,有颜色代码,可以改变文本的颜色,还有格式代码,可以改变文本的格式。
现在,因为 Minecraft 颜色代码没有说明颜色代码在哪里结束,所以我不知道如何将其转换为 HTML。
我做到了一半,将所有颜色代码替换为 </span><span style='color:newcolor'>
并将所有格式代码替换为 </var><var style='text-decoration:blah'>
但是这没有用,因为当你在格式代码之前有一个颜色代码时,它会变成 <span></var><var></span>
。
所以问题是,我该怎么做?查找颜色代码的结束位置等等。
Minecraft 的颜色代码可在此处获得:http://ess.khhq.net/mc/
由于我的代码太大,我把它发布在 JSFiddle 上。
到目前为止我的代码:https://jsfiddle.net/thwe0yek/1/(第一个很好,第二个搞砸了..)
这是一种方法。
这是如何工作的简要说明:
- 它在字符串中查找所有代码,并使用与其匹配的正则表达式(参见
parseStyle
函数的第一行)
- 它将这些代码在字符串中的位置的索引推入一个数组,并用双
\x00
(空字符)替换每个代码,以处理后面部分的代码重复字符串(参见第一个 for
循环)。
- 它根据一个代码的开头和另一个代码的开头将字符串分成多个部分,这样每个部分都可以根据自己的规则单独设置样式。
- 同样在第二个循环中,字符串被发送到
applyCode
函数,该函数在 styleMap
的帮助下应用给它的代码(通过数组)。此函数为给定的每个字符串创建一个 span
元素。如果找到 k
规则,它还会应用 obfuscate
函数。
obfuscate
函数接受一个字符串,获取它的长度,并为字符串中的每个字符生成一个随机字符。它在一个时间间隔内逐个字符执行此操作。它选择的字符范围可以通过更改 replaceRand
函数中的 randInt
值来修改。
- 最后,脚本 returns 一个具有两个属性的对象:一个是
parsed
其中 returns 一个 DOM 元素与 'obfuscators' 运行,另一个是raw
,其中returns跨度元素为HTML字符串(只是parsed
的内部HTML)。
调用mineParse(string)
即可使用,例如:
var result = mineParse('§6Hello');
document.body.appendChild(result.parsed);
现在支持将换行符转换为 <br>
标记、§r
重置代码以及以任意顺序应用多个代码。
不过,我确信脚本可以进一步简化。另外,我确定它有错误,你可以随意修改它。
http://jsfiddle.net/fku9gsax/12/
(function () {
'use strict';
var currId = 0,
obfuscators = {},
alreadyParsed = [],
styleMap = {
'§0': 'color:#000000',
'§1': 'color:#0000AA',
'§2': 'color:#00AA00',
'§3': 'color:#00AAAA',
'§4': 'color:#AA0000',
'§5': 'color:#AA00AA',
'§6': 'color:#FFAA00',
'§7': 'color:#AAAAAA',
'§8': 'color:#555555',
'§9': 'color:#5555FF',
'§a': 'color:#55FF55',
'§b': 'color:#55FFFF',
'§c': 'color:#FF5555',
'§d': 'color:#FF55FF',
'§e': 'color:#FFFF55',
'§f': 'color:#FFFFFF',
'§l': 'font-weight:bold',
'§m': 'text-decoration:line-through',
'§n': 'text-decoration:underline',
'§o': 'font-style:italic'
};
function obfuscate(elem, string) {
var multiMagic,
currNode,
listLen,
nodeI;
function randInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
function replaceRand(string, i) {
var randChar = String.fromCharCode(randInt(64, 95));
return string.substr(0, i) + randChar + string.substr(i + 1, string.length);
}
function initMagic(el, str) {
var i = 0,
obsStr = str || el.innerHTML,
strLen = obsStr.length;
if(!strLen) return;
obfuscators[currId].push(
window.setInterval(function () {
if (i >= strLen) i = 0;
obsStr = replaceRand(obsStr, i);
el.innerHTML = obsStr;
i++;
}, 0)
);
}
if (string.indexOf('<br>') > -1) {
elem.innerHTML = string;
listLen = elem.childNodes.length;
for (nodeI = 0; nodeI < listLen; nodeI++) {
currNode = elem.childNodes[nodeI];
if (currNode.nodeType === 3) {
multiMagic = document.createElement('span');
multiMagic.innerHTML = currNode.nodeValue;
elem.replaceChild(multiMagic, currNode);
initMagic(multiMagic);
}
}
} else {
initMagic(elem, string);
}
}
function applyCode(string, codes) {
var elem = document.createElement('span'),
obfuscated = false;
string = string.replace(/\x00/g, '');
codes.forEach(function (code) {
elem.style.cssText += styleMap[code] + ';';
if (code === '§k') {
obfuscate(elem, string);
obfuscated = true;
}
});
if (!obfuscated) elem.innerHTML = string;
return elem;
}
function parseStyle(string) {
var finalPre = document.createElement('pre'),
codes = string.match(/§.{1}/g) || [],
codesLen = codes.length,
indexes = [],
indexDelta,
apply = [],
strSlice,
i;
if (!obfuscators[currId]) obfuscators[currId] = [];
string = string.replace(/\n|\n/g, '<br>');
for (i = 0; i < codesLen; i++) {
indexes.push(string.indexOf(codes[i]));
string = string.replace(codes[i], '\x00\x00');
}
if (indexes[0] !== 0) {
finalPre.appendChild(applyCode(string.substring(0, indexes[0]), []));
}
for (i = 0; i < codesLen; i++) {
indexDelta = indexes[i + 1] - indexes[i];
if (indexDelta === 2) {
while (indexDelta === 2) {
apply.push(codes[i]);
i++;
indexDelta = indexes[i + 1] - indexes[i];
}
apply.push(codes[i]);
} else {
apply.push(codes[i]);
}
if (apply.lastIndexOf('§r') > -1) {
apply = apply.slice(apply.lastIndexOf('§r') + 1);
}
strSlice = string.substring(indexes[i], indexes[i + 1]);
finalPre.appendChild(applyCode(strSlice, apply));
}
return finalPre;
}
function clearObfuscators(id) {
obfuscators[id].forEach(function (interval) {
clearInterval(interval);
});
alreadyParsed[id] = [];
obfuscators[id] = [];
}
window.mineParse = function initParser(input) {
var parsed,
i = currId;
if (i > 0) {
while (i--) {
if (alreadyParsed[i].nodeType) {
if (!document.contains(alreadyParsed[i])) {
clearObfuscators(i);
}
}
}
}
parsed = parseStyle(input);
alreadyParsed.push(parsed);
currId++;
return {
parsed: parsed,
raw: parsed.innerHTML
};
};
}());
@media (max-width: 850px) {
div#inBetween {
width: 100%;
box-sizing: border-box;
padding: 0.05em;
}
#inBetween:before {
display: inline-block;
font-family:'FontAwesome';
content:"\f107";
animation: bounceDown 2s infinite;
}
}
@media (min-width: 850px) {
#inBetween:before {
display: inline-block;
font-family:'FontAwesome';
content:"\f105";
animation: bounceRight 2s infinite;
}
}
html, body {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
}
button::-moz-focus-inner {
border: 0;
}
body {
text-align: center;
background: #050A0E;
font-family:'Open Sans', sans-serif;
overflow-x: hidden;
}
#mainContainer {
padding: 5em 0 5em 0;
}
h1 {
font-weight: bold;
color: #5EB4E7;
text-shadow: 0 0 50px #5EB4E7;
padding: 1em;
margin: 0;
animation: fadeIn 2s ease-in-out;
}
#inputContainer, #outputContainer {
display: inline-block;
padding: 1em;
width: 20em;
height: 21em;
background: #152E3D;
box-shadow: 0 0 4px #5EB4E7;
vertical-align: middle;
animation: scaleIn 1s ease-in-out;
}
#inBetween {
display: inline-block;
vertical-align: middle;
color: #5EB4E7;
font-size: 4em;
padding: 0.5em;
animation: scaleIn 1s ease-in-out;
}
#outputContainer {
display: inline-block;
padding: 1em;
vertical-align: top;
border-radius: 0 5px 5px 0;
}
#inputContainer {
border-radius: 5px 0 0 5px;
}
#input {
box-sizing: border-box;
padding: 1em;
width: 20em;
max-width: 20em;
height: 20em;
max-height: 20em;
}
#output {
background: rgba(255, 255, 255, 0.97);
text-align: left;
animation: bounceInRight 1s;
}
#output pre {
margin-top: 0;
padding: 1em;
border: 4px solid #050A0E;
overflow: auto;
max-height: 20em;
animation: bounceInRight 0.5s;
}
#input, #parse, #parse:active, #parse:focus {
padding: 1em;
width: 20em;
background: #050A0E;
color: #5EB4E7;
outline: 0;
outline-style: none;
outline-width: 0;
box-shadow: none;
border: none;
}
#parse {
transition: all 225ms ease-in-out;
border-radius: 0 0 5px 5px;
}
#parse:hover {
color: rgba(255, 255, 255, 0.8);
background: #5EB4E7;
cursor: pointer;
box-shadow: 0 0 25px #5EB4E7;
}
.containerLabel {
position: relative;
top: -0.5em;
left: -1.5em;
color: #5EB4E7;
text-align: left;
margin-left: 1.5em;
font-size: 80%;
font-weight: bold;
opacity: 0.85;
margin-bottom: 0.25em;
text-shadow: 0 0 40px #5EB4E7;
}
.bounceInRight {
animation: bounceInRight 1s;
}
@keyframes bounceRight {
0%, 20%, 50%, 80%, 100% {
transform: translateX(0);
}
40% {
transform: translateX(-10px);
}
60% {
transform: translateX(-5px);
}
}
@keyframes bounceDown {
0%, 20%, 50%, 80%, 100% {
transform: translateY(0);
}
40% {
transform: translateY(-10px);
}
60% {
transform: translateY(-5px);
}
}
@keyframes bounceInRight {
0% {
opacity: 0;
transform: translateX(2000px);
}
60% {
opacity: 1;
transform: translateX(-30px);
}
80% {
transform: translateX(10px);
}
100% {
transform: translateX(0);
}
}
@keyframes flipInY {
0% {
transform: perspective(400px) rotateY(90deg);
opacity: 0;
}
40% {
transform: perspective(400px) rotateY(-10deg);
}
70% {
transform: perspective(400px) rotateY(10deg);
}
100% {
transform: perspective(400px) rotateY(0deg);
opacity: 1;
}
}
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1
}
}
@keyframes scaleIn {
0% {
transform: scale(0);
}
80% {
transform: scale(1.05);
}
100% {
transform: scale(1);
}
}
<link rel="stylesheet" href="style/style.css">
<script src="js/mine-parse.js"></script>
<link href='http://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div id="mainContainer">
<h1> <i class="fa fa-code"></i> MineParse </h1>
<div id="inputContainer">
<div class="containerLabel">
<i class="fa fa-pencil-square"></i>
Input
</div>
<textarea id="input">
§nMinecraft Formatting
§r§00 §11 §22 §33
§44 §55 §66 §77
§88 §99 §aa §bb
§cc §dd §ee §ff
§r§0k §kMinecraft
§rl §lMinecraft
§rm §mMinecraft
§rn §nMinecraft
§ro §oMinecraft
§rr §rMinecraft
</textarea>
<button id="parse">
<i class="fa fa-angle-right"></i>
Parse
</button>
</div>
<div id="inBetween"></div>
<div id="outputContainer">
<div class="containerLabel">
<i class="fa fa-eye"></i>
Output <span id="parseTime"></span>
</div>
<div id="output"></div>
</div>
<script>
(function () {
'use strict';
var input = document.getElementById('input'),
output = document.getElementById('output'),
parseBtn = document.getElementById('parse'),
parseTime = document.getElementById('parseTime'),
outputContainer = document.getElementById('outputContainer'),
scrollInterval;
parseBtn.onclick = function () {
var scrollY = window.pageYOffset,
outputY = outputContainer.offsetTop,
parseStart = Date.now(),
result = mineParse(input.value);
parseTime.innerHTML = '~ ' + ((Date.now() - parseStart) / 1000) + ' seconds';
clearInterval(scrollInterval);
output.innerHTML = '';
if (window.innerWidth < 850) {
scrollInterval = setInterval(function () {
scrollY += 5;
window.scrollTo(0, scrollY);
if (scrollY >= outputY) {
window.scrollTo(0, outputY);
clearInterval(scrollInterval);
}
}, 0);
}
output.appendChild(result.parsed);
};
}());
</script>
最近,我正在尝试将 Minecraft MOTD 转换为 Plain HTML。 Minecraft MOTD 是基本文本,用 Minecraft 颜色代码表示颜色变化。
示例:“§d§l枢纽§8:§6§oO_O §a§l[变异星期一]”
翻译:<span style='color:pink'><b>The Nexus</b></span><span style='color:gray'>:</span>...
等等...所以基本上,有颜色代码,可以改变文本的颜色,还有格式代码,可以改变文本的格式。
现在,因为 Minecraft 颜色代码没有说明颜色代码在哪里结束,所以我不知道如何将其转换为 HTML。
我做到了一半,将所有颜色代码替换为 </span><span style='color:newcolor'>
并将所有格式代码替换为 </var><var style='text-decoration:blah'>
但是这没有用,因为当你在格式代码之前有一个颜色代码时,它会变成 <span></var><var></span>
。
所以问题是,我该怎么做?查找颜色代码的结束位置等等。
Minecraft 的颜色代码可在此处获得:http://ess.khhq.net/mc/
由于我的代码太大,我把它发布在 JSFiddle 上。
到目前为止我的代码:https://jsfiddle.net/thwe0yek/1/(第一个很好,第二个搞砸了..)
这是一种方法。
这是如何工作的简要说明:
- 它在字符串中查找所有代码,并使用与其匹配的正则表达式(参见
parseStyle
函数的第一行) - 它将这些代码在字符串中的位置的索引推入一个数组,并用双
\x00
(空字符)替换每个代码,以处理后面部分的代码重复字符串(参见第一个for
循环)。 - 它根据一个代码的开头和另一个代码的开头将字符串分成多个部分,这样每个部分都可以根据自己的规则单独设置样式。
- 同样在第二个循环中,字符串被发送到
applyCode
函数,该函数在styleMap
的帮助下应用给它的代码(通过数组)。此函数为给定的每个字符串创建一个span
元素。如果找到k
规则,它还会应用obfuscate
函数。 obfuscate
函数接受一个字符串,获取它的长度,并为字符串中的每个字符生成一个随机字符。它在一个时间间隔内逐个字符执行此操作。它选择的字符范围可以通过更改replaceRand
函数中的randInt
值来修改。- 最后,脚本 returns 一个具有两个属性的对象:一个是
parsed
其中 returns 一个 DOM 元素与 'obfuscators' 运行,另一个是raw
,其中returns跨度元素为HTML字符串(只是parsed
的内部HTML)。
调用mineParse(string)
即可使用,例如:
var result = mineParse('§6Hello');
document.body.appendChild(result.parsed);
现在支持将换行符转换为 <br>
标记、§r
重置代码以及以任意顺序应用多个代码。
不过,我确信脚本可以进一步简化。另外,我确定它有错误,你可以随意修改它。
http://jsfiddle.net/fku9gsax/12/
(function () {
'use strict';
var currId = 0,
obfuscators = {},
alreadyParsed = [],
styleMap = {
'§0': 'color:#000000',
'§1': 'color:#0000AA',
'§2': 'color:#00AA00',
'§3': 'color:#00AAAA',
'§4': 'color:#AA0000',
'§5': 'color:#AA00AA',
'§6': 'color:#FFAA00',
'§7': 'color:#AAAAAA',
'§8': 'color:#555555',
'§9': 'color:#5555FF',
'§a': 'color:#55FF55',
'§b': 'color:#55FFFF',
'§c': 'color:#FF5555',
'§d': 'color:#FF55FF',
'§e': 'color:#FFFF55',
'§f': 'color:#FFFFFF',
'§l': 'font-weight:bold',
'§m': 'text-decoration:line-through',
'§n': 'text-decoration:underline',
'§o': 'font-style:italic'
};
function obfuscate(elem, string) {
var multiMagic,
currNode,
listLen,
nodeI;
function randInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
function replaceRand(string, i) {
var randChar = String.fromCharCode(randInt(64, 95));
return string.substr(0, i) + randChar + string.substr(i + 1, string.length);
}
function initMagic(el, str) {
var i = 0,
obsStr = str || el.innerHTML,
strLen = obsStr.length;
if(!strLen) return;
obfuscators[currId].push(
window.setInterval(function () {
if (i >= strLen) i = 0;
obsStr = replaceRand(obsStr, i);
el.innerHTML = obsStr;
i++;
}, 0)
);
}
if (string.indexOf('<br>') > -1) {
elem.innerHTML = string;
listLen = elem.childNodes.length;
for (nodeI = 0; nodeI < listLen; nodeI++) {
currNode = elem.childNodes[nodeI];
if (currNode.nodeType === 3) {
multiMagic = document.createElement('span');
multiMagic.innerHTML = currNode.nodeValue;
elem.replaceChild(multiMagic, currNode);
initMagic(multiMagic);
}
}
} else {
initMagic(elem, string);
}
}
function applyCode(string, codes) {
var elem = document.createElement('span'),
obfuscated = false;
string = string.replace(/\x00/g, '');
codes.forEach(function (code) {
elem.style.cssText += styleMap[code] + ';';
if (code === '§k') {
obfuscate(elem, string);
obfuscated = true;
}
});
if (!obfuscated) elem.innerHTML = string;
return elem;
}
function parseStyle(string) {
var finalPre = document.createElement('pre'),
codes = string.match(/§.{1}/g) || [],
codesLen = codes.length,
indexes = [],
indexDelta,
apply = [],
strSlice,
i;
if (!obfuscators[currId]) obfuscators[currId] = [];
string = string.replace(/\n|\n/g, '<br>');
for (i = 0; i < codesLen; i++) {
indexes.push(string.indexOf(codes[i]));
string = string.replace(codes[i], '\x00\x00');
}
if (indexes[0] !== 0) {
finalPre.appendChild(applyCode(string.substring(0, indexes[0]), []));
}
for (i = 0; i < codesLen; i++) {
indexDelta = indexes[i + 1] - indexes[i];
if (indexDelta === 2) {
while (indexDelta === 2) {
apply.push(codes[i]);
i++;
indexDelta = indexes[i + 1] - indexes[i];
}
apply.push(codes[i]);
} else {
apply.push(codes[i]);
}
if (apply.lastIndexOf('§r') > -1) {
apply = apply.slice(apply.lastIndexOf('§r') + 1);
}
strSlice = string.substring(indexes[i], indexes[i + 1]);
finalPre.appendChild(applyCode(strSlice, apply));
}
return finalPre;
}
function clearObfuscators(id) {
obfuscators[id].forEach(function (interval) {
clearInterval(interval);
});
alreadyParsed[id] = [];
obfuscators[id] = [];
}
window.mineParse = function initParser(input) {
var parsed,
i = currId;
if (i > 0) {
while (i--) {
if (alreadyParsed[i].nodeType) {
if (!document.contains(alreadyParsed[i])) {
clearObfuscators(i);
}
}
}
}
parsed = parseStyle(input);
alreadyParsed.push(parsed);
currId++;
return {
parsed: parsed,
raw: parsed.innerHTML
};
};
}());
@media (max-width: 850px) {
div#inBetween {
width: 100%;
box-sizing: border-box;
padding: 0.05em;
}
#inBetween:before {
display: inline-block;
font-family:'FontAwesome';
content:"\f107";
animation: bounceDown 2s infinite;
}
}
@media (min-width: 850px) {
#inBetween:before {
display: inline-block;
font-family:'FontAwesome';
content:"\f105";
animation: bounceRight 2s infinite;
}
}
html, body {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
}
button::-moz-focus-inner {
border: 0;
}
body {
text-align: center;
background: #050A0E;
font-family:'Open Sans', sans-serif;
overflow-x: hidden;
}
#mainContainer {
padding: 5em 0 5em 0;
}
h1 {
font-weight: bold;
color: #5EB4E7;
text-shadow: 0 0 50px #5EB4E7;
padding: 1em;
margin: 0;
animation: fadeIn 2s ease-in-out;
}
#inputContainer, #outputContainer {
display: inline-block;
padding: 1em;
width: 20em;
height: 21em;
background: #152E3D;
box-shadow: 0 0 4px #5EB4E7;
vertical-align: middle;
animation: scaleIn 1s ease-in-out;
}
#inBetween {
display: inline-block;
vertical-align: middle;
color: #5EB4E7;
font-size: 4em;
padding: 0.5em;
animation: scaleIn 1s ease-in-out;
}
#outputContainer {
display: inline-block;
padding: 1em;
vertical-align: top;
border-radius: 0 5px 5px 0;
}
#inputContainer {
border-radius: 5px 0 0 5px;
}
#input {
box-sizing: border-box;
padding: 1em;
width: 20em;
max-width: 20em;
height: 20em;
max-height: 20em;
}
#output {
background: rgba(255, 255, 255, 0.97);
text-align: left;
animation: bounceInRight 1s;
}
#output pre {
margin-top: 0;
padding: 1em;
border: 4px solid #050A0E;
overflow: auto;
max-height: 20em;
animation: bounceInRight 0.5s;
}
#input, #parse, #parse:active, #parse:focus {
padding: 1em;
width: 20em;
background: #050A0E;
color: #5EB4E7;
outline: 0;
outline-style: none;
outline-width: 0;
box-shadow: none;
border: none;
}
#parse {
transition: all 225ms ease-in-out;
border-radius: 0 0 5px 5px;
}
#parse:hover {
color: rgba(255, 255, 255, 0.8);
background: #5EB4E7;
cursor: pointer;
box-shadow: 0 0 25px #5EB4E7;
}
.containerLabel {
position: relative;
top: -0.5em;
left: -1.5em;
color: #5EB4E7;
text-align: left;
margin-left: 1.5em;
font-size: 80%;
font-weight: bold;
opacity: 0.85;
margin-bottom: 0.25em;
text-shadow: 0 0 40px #5EB4E7;
}
.bounceInRight {
animation: bounceInRight 1s;
}
@keyframes bounceRight {
0%, 20%, 50%, 80%, 100% {
transform: translateX(0);
}
40% {
transform: translateX(-10px);
}
60% {
transform: translateX(-5px);
}
}
@keyframes bounceDown {
0%, 20%, 50%, 80%, 100% {
transform: translateY(0);
}
40% {
transform: translateY(-10px);
}
60% {
transform: translateY(-5px);
}
}
@keyframes bounceInRight {
0% {
opacity: 0;
transform: translateX(2000px);
}
60% {
opacity: 1;
transform: translateX(-30px);
}
80% {
transform: translateX(10px);
}
100% {
transform: translateX(0);
}
}
@keyframes flipInY {
0% {
transform: perspective(400px) rotateY(90deg);
opacity: 0;
}
40% {
transform: perspective(400px) rotateY(-10deg);
}
70% {
transform: perspective(400px) rotateY(10deg);
}
100% {
transform: perspective(400px) rotateY(0deg);
opacity: 1;
}
}
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1
}
}
@keyframes scaleIn {
0% {
transform: scale(0);
}
80% {
transform: scale(1.05);
}
100% {
transform: scale(1);
}
}
<link rel="stylesheet" href="style/style.css">
<script src="js/mine-parse.js"></script>
<link href='http://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div id="mainContainer">
<h1> <i class="fa fa-code"></i> MineParse </h1>
<div id="inputContainer">
<div class="containerLabel">
<i class="fa fa-pencil-square"></i>
Input
</div>
<textarea id="input">
§nMinecraft Formatting
§r§00 §11 §22 §33
§44 §55 §66 §77
§88 §99 §aa §bb
§cc §dd §ee §ff
§r§0k §kMinecraft
§rl §lMinecraft
§rm §mMinecraft
§rn §nMinecraft
§ro §oMinecraft
§rr §rMinecraft
</textarea>
<button id="parse">
<i class="fa fa-angle-right"></i>
Parse
</button>
</div>
<div id="inBetween"></div>
<div id="outputContainer">
<div class="containerLabel">
<i class="fa fa-eye"></i>
Output <span id="parseTime"></span>
</div>
<div id="output"></div>
</div>
<script>
(function () {
'use strict';
var input = document.getElementById('input'),
output = document.getElementById('output'),
parseBtn = document.getElementById('parse'),
parseTime = document.getElementById('parseTime'),
outputContainer = document.getElementById('outputContainer'),
scrollInterval;
parseBtn.onclick = function () {
var scrollY = window.pageYOffset,
outputY = outputContainer.offsetTop,
parseStart = Date.now(),
result = mineParse(input.value);
parseTime.innerHTML = '~ ' + ((Date.now() - parseStart) / 1000) + ' seconds';
clearInterval(scrollInterval);
output.innerHTML = '';
if (window.innerWidth < 850) {
scrollInterval = setInterval(function () {
scrollY += 5;
window.scrollTo(0, scrollY);
if (scrollY >= outputY) {
window.scrollTo(0, outputY);
clearInterval(scrollInterval);
}
}, 0);
}
output.appendChild(result.parsed);
};
}());
</script>