 
          
        
        After first try using canvastext, I use span elements to make mini love text animation.
(function(){function k(a,l,m){var n=0,o,p,q,r,s,t;while(!m)o=a[n++],o?o.c&&o["c"][0]=="p"&&(m=n):m=n-1;for(p=l;p<m;p++){q=a[p];if(q.t)q["t"]!="\n"?q.txt||(t=b[g](i[h]("span")),q.txt=t,t.textContent=q.t,t[f]("style","font:"+c+"px 'Helvetica';color:"+e)):q.txt||(q.txt=b[g](i[h]("br")));else if(j[q.c[0]](q)){r;for(s=m+1;s<a.length;s++){t=a[s];if(t.c&&t["c"][0]=="p"){r=s+1;break}}r||(r=a.length),m=r}}d=setTimeout(function(){k(a,l,m)},99)}var a="\n<p2><f90>I<p1><cred>♥<p1><c#000>J<p1>S<p2><f10>1k<p1>\nX<p1>D ",c,d,e="#000",f="setAttribute",g="appendChild",h="createElement",i=document,j={f:function(a){c=parseInt(a.c.slice(1))},c:function(a){e=a.c.slice(1)},p:function(a){if(!a.p){var b=(new Date).getTime();if(!a.i)a.i=b;else if(b>a.i+parseFloat(a.c.slice(1))*1e3)return a.p=!0}}};b[f]("style","text-align:center");var l=[],m="<",n="",o,p,q;for(p=0;p<a.length;p++)q=a[p],q==m||p==a.length-1?(m=="<"?(o={t:n},m=">"):(o={c:n},m="<"),n!=""&&l.push(o),n=""):q=="\n"?(n!=""&&l.push({t:n}),l.push({t:q}),n=""):n+=q;k(l,0)})();KGZ1bmN0aW9uKCl7ZnVuY3Rpb24gayhhLGwsbSl7dmFyIG49MCxvLHAscSxyLHMsdDt3aGlsZSghbSlvPWFbbisrXSxvP28uYyYmb1siYyJdWzBdPT0icCImJihtPW4pOm09bi0xO2ZvcihwPWw7cDxtO3ArKyl7cT1hW3BdO2lmKHEudClxWyJ0Il0hPSJcbiI/cS50eHR8fCh0PWJbZ10oaVtoXSgic3BhbiIpKSxxLnR4dD10LHQudGV4dENvbnRlbnQ9cS50LHRbZl0oInN0eWxlIiwiZm9udDoiK2MrInB4ICdIZWx2ZXRpY2EnO2NvbG9yOiIrZSkpOnEudHh0fHwocS50eHQ9YltnXShpW2hdKCJiciIpKSk7ZWxzZSBpZihqW3EuY1swXV0ocSkpe3I7Zm9yKHM9bSsxO3M8YS5sZW5ndGg7cysrKXt0PWFbc107aWYodC5jJiZ0WyJjIl1bMF09PSJwIil7cj1zKzE7YnJlYWt9fXJ8fChyPWEubGVuZ3RoKSxtPXJ9fWQ9c2V0VGltZW91dChmdW5jdGlvbigpe2soYSxsLG0pfSw5OSl9dmFyIGE9IlxuPHAyPjxmOTA+STxwMT48Y3JlZD7imaU8cDE+PGMjMDAwPko8cDE+UzxwMj48ZjEwPjFrPHAxPlxuWDxwMT5EICIsYyxkLGU9IiMwMDAiLGY9InNldEF0dHJpYnV0ZSIsZz0iYXBwZW5kQ2hpbGQiLGg9ImNyZWF0ZUVsZW1lbnQiLGk9ZG9jdW1lbnQsaj17ZjpmdW5jdGlvbihhKXtjPXBhcnNlSW50KGEuYy5zbGljZSgxKSl9LGM6ZnVuY3Rpb24oYSl7ZT1hLmMuc2xpY2UoMSl9LHA6ZnVuY3Rpb24oYSl7aWYoIWEucCl7dmFyIGI9KG5ldyBEYXRlKS5nZXRUaW1lKCk7aWYoIWEuaSlhLmk9YjtlbHNlIGlmKGI+YS5pK3BhcnNlRmxvYXQoYS5jLnNsaWNlKDEpKSoxZTMpcmV0dXJuIGEucD0hMH19fTtiW2ZdKCJzdHlsZSIsInRleHQtYWxpZ246Y2VudGVyIik7dmFyIGw9W10sbT0iPCIsbj0iIixvLHAscTtmb3IocD0wO3A8YS5sZW5ndGg7cCsrKXE9YVtwXSxxPT1tfHxwPT1hLmxlbmd0aC0xPyhtPT0iPCI/KG89e3Q6bn0sbT0iPiIpOihvPXtjOm59LG09IjwiKSxuIT0iIiYmbC5wdXNoKG8pLG49IiIpOnE9PSJcbiI/KG4hPSIiJiZsLnB1c2goe3Q6bn0pLGwucHVzaCh7dDpxfSksbj0iIik6bis9cTtrKGwsMCl9KSgpOw==(function(){
  // Demo sting
  var text = "\n<p2><f90>I<p1><cred>♥<p1><c#000>J<p1>S<p2><f10>1k<p1>\nX<p1>D ";
  var fontsize;
  var timeout;
  var fontcolor = '#000';
  // farming bytes
  var sa = "setAttribute";
  var ac = "appendChild";
  var ce = "createElement";
  var docu = document;
  var cmds = {
    // Font size
    f:function(params) {
      fontsize = parseInt(params.c.slice(1));
    },
    // Color
    c:function(params) {
      fontcolor = params.c.slice(1);
    },
    // Pause
    p:function(token) {
      if(!token.p) {
        var time = new Date().getTime();
        if(!token.i) {
          token.i = time;
        } else {
          if(time>(token.i+parseFloat(token.c.slice(1))*1000)) {
            return token.p = true;
          }
        }
      }
    }
  }
  function render(commands,ini,end) {
    var index = 0, ele, i, node, new_end, ii, tmp;
    // Find first pause
    while(!end) {
      ele = commands[index++];
      if(ele) {
        if((ele["c"])&&(ele["c"][0]=="p"))
          end = index;
      } else {
        end = index-1;
      }
    }
    for(i=ini;i<end;i++) {
      node = commands[i];
      if(node.t) {
        if((node['t']!="\n")) {
          if(!node.txt) {
            tmp = b[ac](docu[ce]('span'));
            node.txt = tmp
            tmp.textContent = node.t;
            tmp[sa]("style", "font:" + fontsize + "px 'Helvetica';color:"+fontcolor);
          }
        } else {
          if(!node.txt) {
             node.txt = b[ac](docu[ce]('br'));
          }
        }
      } else {
        if(cmds[node['c'][0]](node)) {
          new_end;
          for(ii=end+1;ii<commands.length;ii++) {
            tmp = commands[ii];
            if((tmp["c"])&&(tmp["c"][0]=="p")) {
              new_end = ii+1;
              break;
            }
          }
          if(!new_end) {
            new_end = commands.length;
          }
          end = new_end;
        }
      }
    }
    timeout = setTimeout(function() {
      render(commands,ini,end);
    },99);
  }
  // Align body
  b[sa]("style", "text-align:center");
  
  // Process string data
  // function parse(text) 20 bytes
  var ret = [], finding = "<", current = "",to_insert,i,ele;
  for(i=0;i<text.length;i++) {
    ele = text[i];
    if(ele == finding || i==text.length-1) {
      if(finding == "<") {
        to_insert = {t:current};
        finding = ">";
      } else {
        to_insert = {c:current};
        finding = "<";
      }
      if(current != "") {
        ret.push(to_insert);
      }
      current = "";
    } else {
      if(ele=="\n"){
        if(current != "") {
          ret.push({t:current});
        }
        ret.push({t:ele});
        current = "";
      } else {
        current += ele;
      }
    }
  }
  // GO!!
  render(ret,0);
})();