2016-10-11 3 views
4

Я пытаюсь создать эффект прогресса, при котором цвет заполняет границу объекта DOM (или, возможно, фон). Прикрепленное изображение должно дать вам лучшее представление о том, для чего я собираюсь. Я получил текущий результат, добавив объект с сплошным цветом фона над серыми линиями и установив его высоту. У этого объекта есть mix-blend-mode: color-burn;, поэтому он только окрашивает серые линии под ним.Частично заполнить границу формы цветом

Это работает нормально, но разрушает сглаживание вокруг круга, а также произведенный цвет непредсказуем (изменяется в зависимости от цвета линий).

Я считаю, что должен быть лучший способ достичь этого, возможно, с элементом холста. Может ли кто-нибудь указать мне в правильном направлении, пожалуйста?

Заранее благодарен!

Example

+1

Что о создании двух дублирующих див, установите верхнюю версию color'd над скрытым и отрегулировать высоту соответственно. –

+0

Ах да, я понимаю, что вы говорите.Я сделаю это! –

+0

Градиент? background: linear-gradient (внизу, # 7db9e8 50%, # 1e5799 50%); –

ответ

4

Это должно быть возможно сделать с Canvas и возможно даже с самим CSS, играя с несколькими элементами и т.д., но я определенно рекомендовал бы использовать SVG. SVG предлагает множество преимуществ с точки зрения того, насколько легко он кодирует, поддерживает и также обеспечивает гибкие результаты (в отличие от Canvas, который имеет тенденцию к пикселизации при масштабировании).

Ниже приведены компоненты:

  • rect элемент, который имеет такой же размер, как родитель svg и имеет linear-gradient заливку. Градиент имеет два цвета: один - базовый (светло-серый), а другой - прогресс (голубой-иш).
  • A mask, который применяется к элементу rect. Маска имеет path, которая представляет собой ни что иное, как линию и круг. Когда mask применяется к rect, только этот path будет отображаться через фактический фон (или заполнение) rect, остальная часть области будет замаскирована другой rect, которая добавляется внутри mask.
  • mask также имеет элемент text, чтобы показать значение прогресса.
  • linear-gradient имеет stop offset, установленный таким образом, чтобы он был равен прогрессу. Изменяя offset, мы всегда можем убедиться, что path показывает заполнение хода только для необходимой длины и базы (светло-серый) для остальных.

window.onload = function() { 
 
    var progress = document.querySelector('#progress'), 
 
    base = document.querySelector('#base'), 
 
    prgText = document.querySelector('#prg-text'), 
 
    prgInput = document.querySelector('#prg-input'); 
 
    prgInput.addEventListener('change', function() { 
 
    prgText.textContent = this.value + '%'; 
 
    progress.setAttribute('offset', this.value + '%'); 
 
    base.setAttribute('offset', this.value + '%'); 
 
    }); 
 
}
svg { 
 
    width: 200px; 
 
    height: 300px; 
 
} 
 
path { 
 
    stroke-width: 4; 
 
} 
 
#rect { 
 
    fill: url(#grad); 
 
    mask: url(#path); 
 
} 
 

 
/* just for demo */ 
 
.controls { 
 
    position: absolute; 
 
    top: 0; 
 
    right: 0; 
 
    height: 100px; 
 
    line-height: 100px; 
 
    border: 1px solid; 
 
} 
 
.controls * { 
 
    vertical-align: middle; 
 
} 
 

 
body { 
 
    background-image: radial-gradient(circle, #3F9CBA 0%, #153346 100%); 
 
}
<svg viewBox='0 0 200 300' id='shape-container'> 
 
    <linearGradient id='grad' gradientTransform='rotate(90 0 0)'> 
 
    <stop offset='50%' stop-color='rgb(0,218,235)' id='progress' /> 
 
    <stop offset='50%' stop-color='rgb(238,238,238)' id='base' /> 
 
    </linearGradient> 
 
    <mask id='path' maskUnits='userSpaceOnUse' x='0' y='0' width='200' height='300'> 
 
    <rect x='0' y='0' width='200' height='300' fill='black' /> 
 
    <path d='M100,0 100,100 A50,50 0 0,0 100,200 L100,300 M100,200 A50,50 0 1,0 100,100' stroke='white' /> 
 
    <text id='prg-text' x='100' y='155' font-size='20' text-anchor='middle' fill='white'>50%</text> 
 
    </mask> 
 
    <rect id='rect' x='0' y='0' width='200' height='300' /> 
 
</svg> 
 

 
<!-- just for demo --> 
 
<div class='controls'> 
 
    <label>Set Progress:</label> 
 
    <input type='range' id='prg-input' min='0' max='100' value='50' /> 
 
</div>


Если вы новичок в SVG вы можете обратиться к MDN Docs (ссылки приводится ниже) для получения дополнительной информации об элементах, их атрибутов и значений.

+1

Это звучит очень многообещающе! Спасибо, что нашли время, чтобы объяснить. –

+0

Добро пожаловать @BenGuest. Рад был помочь. Я также добавляю тег SVG к вопросу. Надеюсь, у тебя не будет никаких проблем! – Harry

+1

Все в порядке со мной @ Харри! Еще раз спасибо :) –

Смежные вопросы