Jaxel's 2018 Scoreboard

  • Thread starter
  • Admin
  • #1

Jaxel

Administrator
In one of my tutorial videos, I showed off the scoreboard I had been using since 2018:


Since doing this tutorial video, I have actually created a new scoreboard that I use for my weekly tournaments. That means I am no longer using the 2018 scoreboard that I showed in my tutorials. Because of that, I've decided to release the code I used in my 2018 scoreboards to the public, for free. Keep in mind, that this code is not very clean. I created this scoreboard before this website even existed, so the code is a bit hackey because it was designed for the older (offline) version of Scoreboard Assistant. It also uses a third-party font called "Ubuntu Condensed" that you will have to download to your computer.

Package CSS:
Code:
:root
{
    --body-width: 1600px;
    --border-width: 4px;
    --slant-width: 30px;
    --flex-height: 50px;
    
    --event-width: 640px;
    --game-width: 320px;
    --match-width: 240px;
    --player-width: 610px;
    --score-width: 90px;
    
    --font-family: 'Ubuntu Condensed';
    --font-shadow: 1px 1px 0 var(--border-color), 1px -1px 0 var(--border-color),
                    -1px 1px 0 var(--border-color), -1px -1px 0 var(--border-color),
                    2px 2px 0 var(--border-color), 2px -2px 0 var(--border-color),
                    -2px 2px 0 var(--border-color), -2px -2px 0 var(--border-color);
    
    --font-xsmall: 20px;
    --font-small: 30px;
    --font-medium: 40px;
    --font-large: 50px;
    
    --fast-speed: 0.25s;
    --slow-speed: 0.50s;
    --xslow-speed: 1.00s;
}

body
{
    position: relative;
    margin: 0 auto;
    width: var(--body-width);
    color: var(--font-color);
    font-family: var(--font-family);
    font-weight: bold;
    text-align: center;
    overflow: hidden;
}

.xslow { transition: all var(--xslow-speed) ease-out; }
.slow { transition: all var(--slow-speed) ease-out; }
.fast { transition: all var(--fast-speed) ease-in; }

.colorB { background: var(--border-color); }
.color1 { background: var(--main-color1); }
.color2 { background: var(--main-color2); }
.color3 { background: var(--main-color3); }

.xsmall { font-size: var(--font-xsmall); text-transform: uppercase; }
.small { font-size: var(--font-small); text-transform: uppercase; }
.medium { font-size: var(--font-medium); text-transform: uppercase; }
.large { font-size: var(--font-large); text-transform: uppercase; }




.toprow.hidden { margin-top: calc(0px - var(--flex-height)); }
.toprow > div { border-bottom: var(--border-width) solid var(--border-color); }

.botrow { position: absolute; bottom: 0; left: 0; right: 0; }
.botrow.hidden { margin-bottom: calc(0px - var(--flex-height)); }
.botrow > div { border-top: var(--border-width) solid var(--border-color); }

.flexbox
{
    display: flex;
    height: var(--flex-height);
    justify-content: center;
}
.flexitem
{
    min-width: calc(var(--slant-width) + var(--border-width));
    position: relative;
}
.flexitem.hidden { width: 0 !important; }

.divider
{
    margin: 0 calc(0px - var(--slant-width));
    width: calc(var(--slant-width) + var(--border-width));
}

.topL { -webkit-clip-path: polygon(0% 0%, calc(100% - var(--slant-width)) 0%, 100% 100%, var(--slant-width) 100%); }
.topR { -webkit-clip-path: polygon(var(--slant-width) 0%, 100% 0%, calc(100% - var(--slant-width)) 100%, 0% 100%); }
.topC { -webkit-clip-path: polygon(0% 0%, 100% 0%, calc(100% - var(--slant-width)) 100%, var(--slant-width) 100%); }
.botL { -webkit-clip-path: polygon(var(--slant-width) 0%, 100% 0%, calc(100% - var(--slant-width)) 100%, 0% 100%); }
.botR { -webkit-clip-path: polygon(0% 0%, calc(100% - var(--slant-width)) 0%, 100% 100%, var(--slant-width) 100%); }
.botC { -webkit-clip-path: polygon(var(--slant-width) 0%, calc(100% - var(--slant-width)) 0%, 100% 100%, 0% 100%); }

tags { color: #999999; }
text
{
    line-height: calc(var(--flex-height) - var(--border-width));
    overflow: hidden;
    text-overflow: ellipsis;
    text-shadow: var(--font-shadow);
    white-space: nowrap;
}
text.hidden { opacity: 0 !important; padding: 0 !important; }




.xsmall icon { margin-bottom: -4px; height: 22px; width: 22px; }
.small icon { margin-bottom: -5px; height: 32px; width: 32px; }
.medium icon { margin-bottom: -2px; height: 32px; width: 32px; }
.large icon { margin-bottom: -3px; height: 46px; width: 46px; }
icon { display: inline-block; background-position: center; background-size: 100%; }

icon.i8WR { background-image: url('http://data.8wr.io/sba/1/icons/8WR.png'); }
icon.iCHL { background-image: url('http://data.8wr.io/sba/1/icons/CHL.png'); }
icon.iINS { background-image: url('http://data.8wr.io/sba/1/icons/INS.png'); }
icon.iFB { background-image: url('http://data.8wr.io/sba/1/icons/FB.png'); }
icon.iSGG { background-image: url('http://data.8wr.io/sba/1/icons/SGG.png'); }
icon.iTW { background-image: url('http://data.8wr.io/sba/1/icons/TW.png'); }
icon.iTWC { background-image: url('http://data.8wr.io/sba/1/icons/TWC.png'); }
icon.iYT { background-image: url('http://data.8wr.io/sba/1/icons/YT.png'); }

team.t8WR { background-image: url('http://data.8wr.io/sba/1/teams/8WR.png'); }
team.tCLG { background-image: url('http://data.8wr.io/sba/1/teams/CLG.png'); }
team.tFOX { background-image: url('http://data.8wr.io/sba/1/teams/FOX.png'); }
team.tNRG { background-image: url('http://data.8wr.io/sba/1/teams/NRG.png'); }
team.tTSM { background-image: url('http://data.8wr.io/sba/1/teams/TSM.png'); }
Package JS:
Code:
document.addEventListener("DOMContentLoaded", function()
{
    var styles = getComputedStyle(document.documentElement);
    
    inSpeed = String(styles.getPropertyValue('--slow-speed')).trim();
    inSpeed = inSpeed.replace('s', '');
    inSpeed = inSpeed * 1000;
    outSpeed = inSpeed / 2;
});

function parseText(txt)
{
    if (txt == null || txt == '') { return ''; }
    txt = txt.trim();
    
    txt = txt.replace(/</g, "&lt;").replace(/>/g, "&gt;");
    txt = txt.replace(/\&/g, "&amp;").replace(/\s/g, "&nbsp;");
    
    var regex = /\{\{([\w\.]+?)\}\}/g;
    var match = regex.exec(txt);
    
    while (match != null)
    {
        match[1] = match[1].replace('.', ' ');
        txt = txt.replace(match[0], "<icon class=\"i"+match[1]+"\"></icon>");
        match = regex.exec(txt);
    }
    
    return txt.trim();
}

function elemsHide(elem)
{
    return function (next)
    {
        $(elem).addClass('fast hidden');
        next();
    };
}

function elemsShow(elem)
{
    return function (next)
    {
        $(elem).removeClass('fast hidden');
        next();
    };
}

function elemsUpdate()
{
    return function (next)
    {
        for (var prop in newData)
        {
            $('#'+prop+' text').html(newData[prop]);
        }
        next();
    };
}
Page HTML:
Code:
<div class="flexbox botrow hidden slow">
    <div class="flexitem botL colorB divider"></div>

    <div class="flexitem botC color2 xsmall game" id="gg">
        <text>&nbsp;</text>
    </div>

    <div class="flexitem botR colorB divider"></div>
</div>

<div class="flexbox toprow hidden slow">
    <div class="flexitem topL colorB divider"></div>

    <div class="flexitem topL color3 medium score score1 slow hidden" id="s1">
        <text class="slow hidden">&nbsp;</text>
    </div>

    <div class="flexitem topL colorB divider"></div>

    <div class="flexitem topL color2 medium player player1 xslow hidden" id="p1">
        <text class="slow hidden">&nbsp;</text>
        <team class="slow hidden"></team>
    </div>

    <div class="flexitem topL colorB divider"></div>

    <div class="flexitem topC color1 xsmall round" id="rr">
        <text>&nbsp;</text>
    </div>

    <div class="flexitem topR colorB divider"></div>

    <div class="flexitem topR color2 medium player player2 xslow hidden" id="p2">
        <text class="slow hidden">&nbsp;</text>
        <team class="slow hidden"></team>
    </div>

    <div class="flexitem topR colorB divider"></div>

    <div class="flexitem topR color3 medium score score2 slow hidden" id="s2">
        <text class="slow hidden">&nbsp;</text>
    </div>

    <div class="flexitem topR colorB divider"></div>
</div>
Page CSS:
Code:
.game
{
    min-width: calc(var(--slant-width) * 2);
    width: var(--game-width);
}

.round
{
    min-width: calc(var(--slant-width) * 2);
    width: var(--match-width);
}

.player { width: var(--player-width); }
.player1 { text-align: right; }
.player2 { text-align: left; }
.player text { padding: 0 calc(var(--slant-width) + 10px); }

.score { width: var(--score-width); }
.score text { padding: 0 var(--slant-width); }

.player team
{
    position: absolute;
    top: 0;
    
    height: var(--flex-height);
    width: 150px;
}
.player1 team { left: 30px; }
.player2 team { right: 30px; }
Page JS:
Code:
var versus_1 = docData['versus_1'].split('||');
    versus_2 = docData['versus_2'].split('||');
    round_1 = docData['round_1'].split('||');
    game_1 = docData['game_1'].split('||');

newData = {
    't1': {},
    't2': {},
    'p1': parseText(versus_1[0]),
    'p2': parseText(versus_2[0]),
    's1': docData['versus_1s'],
    's2': docData['versus_2s'],
    'rr': parseText(round_1[1]),
    'gg': parseText(game_1[1]),
};

if (versus_1[1] != undefined)
{
    newData['p1'] = '<tags>' + parseText(versus_1[1]) + '</tags> ' + newData['p1'];
    newData['t1'] = parseText(versus_1[1]).split('&nbsp;');
}

if (versus_2[1] != undefined)
{
    newData['p2'] = '<tags>' + parseText(versus_2[1]) + '</tags> ' + newData['p2'];
    newData['t2'] = parseText(versus_2[1]).split('&nbsp;');
}

if ($('#gg text').html() != newData['gg'])
{
    $('.game')
        .queue(elemsHide('.botrow')).delay(outSpeed)
        .queue(elemsUpdate()).delay(inSpeed * 4)
        .queue(elemsShow('.botrow')).delay(inSpeed);
}

if ($('#rr text').html() != newData['rr'])
{
    $('body')
        .queue(elemsHide('.score text')).delay(outSpeed)
        .queue(elemsHide('.score')).delay(outSpeed)
        .queue(elemsHide('.player text')).delay(outSpeed)
        .queue(elemsHide('.player')).delay(outSpeed)
        .queue(elemsHide('.toprow')).delay(outSpeed)
        .queue(elemsUpdate()).queue(teamsUpdate()).delay(inSpeed * 2)
        .queue(elemsShow('.toprow')).delay(inSpeed * 2)
        .queue(elemsShow('.player')).delay(inSpeed * 2)
        .queue(elemsShow('.player text')).delay(inSpeed)
        .queue(elemsShow('.score')).delay(inSpeed)
        .queue(elemsShow('.score text')).delay(inSpeed);
}
else if ($('#p1 text').html() != newData['p1'] || $('#p2 text').html() != newData['p2'])
{
    $('body')
        .queue(elemsHide('.score text')).delay(outSpeed)
        .queue(elemsHide('.score')).delay(outSpeed)
        .queue(elemsHide('.player text')).delay(outSpeed)
        .queue(elemsHide('.player')).delay(outSpeed)
        .queue(elemsUpdate()).queue(teamsUpdate()).delay(inSpeed * 2)
        .queue(elemsShow('.player')).delay(inSpeed * 2)
        .queue(elemsShow('.player text')).delay(inSpeed)
        .queue(elemsShow('.score')).delay(inSpeed)
        .queue(elemsShow('.score text')).delay(inSpeed);
}
else if ($('#s1 text').html() != newData['s1'] || $('#s2 text').html() != newData['s2'])
{
    $('body')
        .queue(elemsHide('.score text')).delay(outSpeed)
        .queue(elemsHide('.score')).delay(outSpeed)
        .queue(elemsUpdate()).delay(inSpeed * 4)
        .queue(elemsShow('.score')).delay(inSpeed)
        .queue(elemsShow('.score text')).delay(inSpeed);
}

function teamsUpdate()
{
    return function (next)
    {
        var int1, int2, cnt1 = 0, cnt2 = 0;
    
        clearInterval(int1);
        $('#p1 team').removeClass().addClass('t'+newData.t1[0]);

        if (newData.t1.length > 1)
        {
            int1 = setInterval(function()
            {
                cnt1 = (cnt1 >= newData.t1.length-1) ? 0 : (cnt1+1);
                $('#p1 team').removeClass().addClass('xslow t'+newData.t1[cnt1]);
            }, 15000);
        }

        clearInterval(int2);
        $('#p2 team').removeClass().addClass('t'+newData.t2[0]);

        if (newData.t2.length > 1)
        {
            int2 = setInterval(function()
            {
                cnt2 = (cnt2 >= newData.t2.length-1) ? 0 : (cnt2+1);
                $('#p2 team').removeClass().addClass('xslow t'+newData.t2[cnt2]);
            }, 15000);
        }
        
        next();
    };
}
And if you're interested in what my 2019 scoreboard looks like: