Создание сложных форм с помощью CSS - PullRequest
6 голосов
/ 18 марта 2012

Я работаю над проектом для браузеров iphone и android, который требует, чтобы я построил термометр, похожий на термометр, который может реагировать на изменение размера браузера и легко изменять ход выполнения. Он должен быть максимально похож на дизайн. То есть ему нужны причудливые градиенты, подсветка вставки, граница.

Метр:

enter image description here

Обратите внимание на белую вставку тени и границы

Прогресс должен распространяться и на круглую часть и продолжать иметь причудливый эффект.

Я пошел вперед и получил грубый прототип, работающий (испытанный в хроме) http://jsfiddle.net/xduQ9/3/

html,
body {
  padding: 25px;
}

.circle {
  margin-left: -6px;
  width: 48px;
  height: 48px;
  border-radius: 25px 25px 25px 24px;
  border: solid rgba(178, 181, 188, 0.8) 1px;
  box-shadow: inset 1px 2px 0 #fff, inset 1px -2px 0 #fff, inset -2px 0 0 #fff, inset -2px -2px 0 #fff, inset 0 3px 0 rgba(255, 255, 255, 0.35), -20px -20px 0 #fff, 20px -20px 0 #fff, 20px 20px 0 #fff, -20px 20px 0 #fff;
}

.circle-wrap {
  overflow: hidden;
  width: 48px;
  height: 51px;
  position: absolute;
  right: 0;
}

.wrap {
  display: -webkit-box;
  width: 100%;
  position: relative;
  height: 51px;
  overflow: hidden;
}

.progress {
  position: absolute;
  z-index: 0;
  height: 100%;
  width: 70%;
  background: url("http://dl.dropbox.com/u/905197/white-stripe-diagonal.png"), -webkit-linear-gradient(top, rgba(183, 237, 21, 1) 0%, rgba(140, 186, 24, 1) 28%, rgba(78, 126, 11, 1) 65%, rgba(59, 86, 0, 1) 99%);
}

.meter.complete .progress {
  width: 100%;
  -webkit-animation: progress-slide 0.6s linear infinite;
}

@-webkit-keyframes progress-slide {
  0% {
    background-position: 0 0;
  }
  100% {
    background-position: 25px 25px;
  }
}

.progress-cover {
  position: absolute;
  top: 19px;
  width: 70%;
  height: 12px;
  border-radius: 9px 0 0 9px;
  border: solid #70901b 1px;
  border-right: 0;
  z-index: 2;
}

.top-mask {
  position: absolute;
  box-sizing: border-box;
  width: 100%;
  height: 18px;
  padding-left: 45px;
  margin-left: -45px;
  background: white;
  border-bottom: solid #b2b5bc 1px;
  border-radius: 0 0 33px 0;
  box-shadow: 1px 2px 0 #fff, 0 3px 0 rgba(255, 255, 255, 0.35);
}

.bottom-mask {
  position: absolute;
  bottom: 0;
  box-sizing: border-box;
  width: 100%;
  height: 17px;
  padding-left: 45px;
  margin-left: -45px;
  background: white;
  border-top: solid #b2b5bc 1px;
  border-radius: 0 19px 0 0;
  box-shadow: 1px -2px 0 #fff;
}

.inner {
  position: absolute;
  top: 0;
  left: 2px;
  width: 3px;
  height: 12px;
  border: solid 3px #fff;
  border-right: none;
  border-radius: 5px 0 0 5px;
}

.meter {
  position: relative;
}

.left-border {
  position: absolute;
  top: 17px;
  left: -4px;
  width: 10px;
  height: 16px;
  border-radius: 12px 0 0 12px;
  border: solid 1px #b2b5bc;
  border-right: none;
  z-index: 3;
}
<div class="meter complete">
  <!-- Remove .complete to stop animation -->
  <div class="left-border">
    <div class="inner"></div>
  </div>
  <div class="wrap">
    <div class="progress"></div>
    <div class="top-mask"></div>
    <div class="bottom-mask"></div>
    <div class="circle-wrap">
      <div class="circle"></div>
    </div>
  </div>
</div>

Техника в основном обрезает прямоугольник с полосатым зеленым фоном с несколькими делениями с закругленными углами, пока не получится желаемая форма. Затем я использую кучу теней, чтобы добавить отступы и вставку вокруг метра.

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

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

Хотя возможность изменения цвета индикатора выполнения не является обязательным требованием для реализации, я бы хотел, чтобы у решения было это свойство.

Ответы [ 2 ]

3 голосов
/ 18 марта 2012

Ваша скрипка не работает в Firefox (Aurora) или IE.

Я знаю, что вы предпочитаете не использовать изображения, но я думаю, что это будет намного чище в коде, если вы используете только изображения.

Почему?потому что вы можете создать спрайт из 3-х частей: первая часть имеет внешнюю часть метра с прозрачной частью стержня, вторая часть имеет "полосу", а третья часть просто белая, чтобы скрыть полосу и создать впечатление процентов.

Затем вы делаете простой код javascript для сокрытия процентов бара, начинающегося справа (например, если у пользователя 24 процента, тогда позиция -76px).

Я бы нарисовал план точно так, как онпоказывает полное значение и используйте z-index, чтобы поместить счетчик сверху, затем белую часть, чтобы имитировать прогресс.И большой круг в начале.

Круг в конце заполнит круглую часть (я не знаю, как там выглядит текущий измеритель тока, если у вас прямая линия, то вместо квадрата выберитекруг).

Сделал набросок в рисовании:

enter image description here

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

Если у вас есть соотношение, с которым вы хотите работать, все остальное просто.

2 голосов
/ 18 марта 2012

Вы должны быть готовы отказаться от некоторых визуальных конфет для полной кросс-браузерной совместимости, но, учитывая, что вы смотрите на рынок iPhone / Android, я бы себя одурачил и сказал: «Выбудь в порядке "

Взгляни на формы css - возможно, единственную статью о трюках css, которую я нахожу интригующей и полезной - для творческого вдохновения использования свойств css для достижения того, что ты"после.Будьте готовы к тому, что с причудливыми градиентами у вас возникнут проблемы с соответствием «стежка» между отдельными фигурами.

Смысловая разметка, вероятно, не может быть и речи, поэтому сходите с ума со всеми необходимыми элементами (нопопробуйте воспользоваться псевдоэлементами: before и: after, чтобы полностью не загрязнять HTML).Если бы это зависело от меня, я бы, вероятно, немного обманул и сделал бы наконечник термометра фиксированным, то есть всегда либо полностью заполненным, либо пустым, и сделал бы «прогресс» в деление с закругленными углами TL и BL.

Оглядываясь назад, ваш пример уже лучше, но в любом случае это скрипка :) http://jsfiddle.net/8dbjw/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...