Есть ли способ изменить цвет текста "на полпути" через персонажа на веб-странице?

Одна вещь, которую я видел в некоторых приложениях для настольных компьютеров, - это возможность изменять цвет текста при изменении фона - эффективно иметь несколько цветов для одного символа. Я видел это чаще всего с индикаторами выполнения, отображающими процент внутри панели. Как правило, более темный цвет фона будет использоваться в качестве цвета индикатора выполнения, и по мере того, как он прогрессирует, темный цвет недостаточно контрастирует с темным текстом, поэтому цвет текста изменяется, как только панель перекрывается с текстом. Это изображение должно объяснить, что я имею в виду:

Progress Bars

Как вы можете видеть, текст черный, когда он равен 0% - когда нет темного фона. Когда фоновое изображение полностью прогрессирует до 100%, текст полностью белый. Но в середине, как вы можете видеть на 50%, текст наполовину черный/наполовину белый, и в этом примере он фактически разбивается на символ "0".

Есть ли способ сделать это вообще на веб-странице? CSS, изображения, JQuery, в противном случае? (Предпочтительно, не Flash или апплет Java, хотя - мне действительно интересно, возможно ли решение на основе HTML.) Спасибо!

Ответ 1

Я заставлю вас начать:

  • Создайте два "шага прогресса" с одинаковым размером (div s). Установите их размер на полную ширину, если они будут на 100%.
  • Установите один бар на черный текст с белым фоном, а другой на желтый текст с синим фоном, как показано в приведенном выше примере.
  • Установите желтую/синюю полосу в родительском div и увеличивайте ширину родителя при каждом процентном увеличении. Поместите родителя над черной/белой полосой.
  • Также при каждом увеличении обновите метки обоих индикаторов выполнения, чтобы представить процент.

Это будет симулировать тот же эффект без необходимости вручную рисовать половину символа. Это будет сложно в CSS, потому что вам придется позиционировать один над другим.

Преимущество этого в том, что вы можете легко отображать наполовину окрашенные символы. Однако уже есть индикатор выполнения jQuery, который вы можете использовать.

Ответ 2

Это действительно интересно. Вот ваш индикатор прогресса. Работает отлично в IE5.5 + и Safari 5 (браузеры, которые я тестировал).

Использует системные цвета.: D

Визуализация здесь

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Progress</title>
    <meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
    <style type="text/css">
.progressbar, .progressbar strong {
    display:block;
    height:1.2em
}
.progressbar, .progressbar em {
    width:10em
}
.progressbar strong, .progressbar em {
    position:absolute;
    top:0;
    left:0
}
.progressbar {
    font:status-bar;
    color:windowtext;
    background:window;
    border:1px solid windowframe;
    text-align:center;
    position:relative
}
.progressbar strong {
    background:highlight;
    width:0;
    font-weight:normal;
    overflow:hidden
}
.progressbar em {
    color:highlighttext;
    font-style:normal
}
    </style>
    <script type="text/javascript">
function progress(bar) {
    var text1 = bar.getElementsByTagName('span')[0];
    var overlay = bar.getElementsByTagName('strong')[0];
    var text2 = bar.getElementsByTagName('em')[0];
    var value = parseInt(bar.getAttribute('progress'), 10);
    value += 1;
    overlay.style.width = value / 10 + 'em';
    text1.innerHTML = text2.innerHTML = value + '%';
    bar.setAttribute('progress', value);
    if (value < 100)
        setTimeout(function() { progress(bar) }, 20);
}
window.onload = function() {
    var span = document.getElementsByTagName('span');
    for (var i = 0; i < span.length; i++) {
        if (span[i].className == 'progressbar') {
            span[i].setAttribute('progress', 0);
            var el1 = document.createElement('span');
            el1.innerHTML = '0%';
            span[i].appendChild(el1);
            el1 = document.createElement('strong');
            var el2 = document.createElement('em');
            el2.innerHTML = '0%';
            el1.appendChild(el2);
            span[i].appendChild(el1);
            progress(span[i]);
        }
    }
}
    </script>
</head>
<body>
    <p><span class="progressbar"></span></p>
</body>
</html>

Обратите внимание, что я использовал setAttribute для присвоения значения индикатору выполнения с использованием имени настраиваемого атрибута.


Изменение script для реального прогресса

Приведенный выше пример - это только фиктивный индикатор выполнения, потому что он использует таймер для увеличения значения. Чтобы добиться реального прогресса, вам нужно немного изменить script. Вы можете изменить функцию progress так, чтобы она добавила значение к текущему значению, или вы можете сделать это так, чтобы оно устанавливало значение. Второй подход - это то, что вы хотите использовать.

function add(bar, value) {
    bar = document.getElementById(bar);
    value = parseInt(bar.getAttribute('progress'), 10) + value;
    value = value > 100 ? 100 : value < 0 ? 0 : value;
    var text1 = bar.getElementsByTagName('span')[0];
    var overlay = bar.getElementsByTagName('strong')[0];
    var text2 = bar.getElementsByTagName('em')[0];
    overlay.style.width = value / 10 + 'em';
    text1.innerHTML = text2.innerHTML = value + '%';
    bar.setAttribute('progress', value);
}
function set(bar, value) {
    value = value > 100 ? 100 : value < 0 ? 0 : value;
    bar = document.getElementById(bar);
    var text1 = bar.getElementsByTagName('span')[0];
    var overlay = bar.getElementsByTagName('strong')[0];
    var text2 = bar.getElementsByTagName('em')[0];
    overlay.style.width = value / 10 + 'em';
    text1.innerHTML = text2.innerHTML = value + '%';
}

Вы можете оставить value = value > 100 ? 100 : value < 0 ? 0 : value, если вы убедитесь, что значение, переданное функции, находится в диапазоне от 0 до 100.

Протестируйте его здесь


Edit:

Я изменил innerText на innerHTML, чтобы он работал в Firefox. Я не знал об этом. Я также изменил в CSS display:inline-block на display:block. Я знаю, что у вас больше не может быть индикатор выполнения, но это заставляет его работать в Netscape 9.

Ответ 3

Здесь другая реализация: http://jsfiddle.net/3rcav4s4/.

HTML:

<div class = "progressBar">
    <div class = "background">0%</div>
    <div class = "container">
        <div class = "foreground">0%</div>
    </div>
</div>
<button>Play</button>

CSS

*:not(button) {
    padding: 0;
    margin: 0;
    border: 0;
    box-sizing: border-box;
}

body {
    padding: 10px;
}

.progressBar {
    width: 150px;
    height: 15px;
    border: 1px solid #000;
    position: relative;
    margin-bottom: 5px;
}

.progressBar .background,
.progressBar .foreground {
    width: 150px;
    height: 13px;
    font: normal 10px/13px Sans-Serif;
    text-align: center;
}

.progressBar .container {
    position: absolute;
    top: 0;
    left: 0;
    width: 0%;
    overflow: hidden;
}

.progressBar .foreground {
    background-color: navy;
    color: yellow;
}

JS/jQuery:

$(function() {
    $("button").click(function() {
        var start = 0;
        var interval = setInterval(function() {
            if(start >= 100) clearInterval(interval);
            $(".progressBar").find(".background, .foreground")
                             .text(start + "%")
                             .end()
                             .find(".container")
                             .css("width", start++ + "%");
        }, 10);    
    });
});