Vue SVG - компонент. Приклад 📑


12.06.2020

Одного разу, в одному з проектів знадобилося мені створити візуальний компонент, який би зображував хід якогось процесу. Наприклад, користувач заповнює данні і цей процес розбитий на кроки. Треба якось красивенько йому показати, що зараз це крок №2 з 4. Або у відсотках і щоб візуально було ясно скільки ще йому страждати або чекати. Звісно, що і кількість "кроків" і кольори і розмір у різних місцях де буде використано цей компонент будуть різні. CSS - в даному випадку не вирішував задачу. З картинками заморочуватися не хотілося, тому вирішив спробувати SVG. Оскільки векторна графіка SVG виписується тегами проблем не повинно бути (принаймні для Vue). Далі приклад компонента (трохи спрощений від того про який я писав), який являє собою простенький SVG - компонент.

Переглянути приклад SVG компонент на Vue

Скачати приклад SVG компонент на Vue

Код самої компоненти:


Vue.component('svg-sector', {
    props:['size', 'circlecolor', 'circlefill', 'degrees', 'sectorcolor', 'sectorwidth', 'text', 'textcolor', 'textsize'],
    computed: {
      dValue: function () {
        let degrees = parseInt(this.degrees)
        let d = 'M' + this.center + ',' + this.stroke / 2
        // Arc angles
        let firstAngle = degrees > 180 ? 90 : degrees - 90
        let secondAngle = -270 + degrees - 180

        // Arcs
        let firstArc = this.getArc(firstAngle)
        let secondArc = degrees > 180 ? this.getArc(secondAngle) : ''
        d = d + ' ' + firstArc + ' ' + secondArc
        return d
      },
      circleRadius: function () {
        let radius = (this.boxSize - this.stroke) / 2
        if (isNaN(radius)) {
            return 0
        }
        else {
            return radius
        }
      },
      circleFill: function () {
        return (typeof this.circlefill !== 'undefined') ? this.circlefill: 'none'
      },
      circleColor: function () {
        return (typeof this.circlecolor !== 'undefined') ? this.circlecolor: '#DDD'
      },
      sectorColor: function () {
        return (typeof this.sectorcolor !== 'undefined') ? this.sectorcolor: '#bD2828'
      },
      textColor: function () {
        return (typeof this.textcolor !== 'undefined') ? this.textcolor: '#bD2828'
      },
      textSize: function () {
        return (typeof this.textsize !== 'undefined') ? this.textsize: '5em'
      }
    },
    data: function () {
      return {
        stroke: this.stroke,
      }
    },
    template: `
  <svg :width="size + 'px'" :height="size + 'px'" viewBox="0 0 200 200">
    <circle :stroke-width="stroke" :fill="circleFill" :stroke="circleColor" cx="100" cy="100" :r="circleRadius"></circle>
    <path :stroke-width="stroke" fill="none" :stroke="sectorColor" :d="dValue"></path>
    <text text-anchor="middle" dominant-baseline="central" x="100" y="100" :font-size="textSize" :fill="textColor" v-html="text"></text>
  </svg>
  `,
  mounted: function () {
    this.boxSize = 200
    this.stroke =  (typeof this.sectorwidth !== 'undefined') ? this.sectorwidth: 20
    this.center = this.boxSize / 2
    this.radius = this.center - this.stroke / 2
  },
  methods: {
    radians: function (degrees) {
      return degrees / 180 * Math.PI;
    },
    getArc: function (angle) {
      let x = this.center + this.radius * Math.cos(this.radians(angle));
      let y = this.center + this.radius * Math.sin(this.radians(angle));
      return 'A' + this.radius + ',' + this.radius + ' 1 0 1 ' + x + ',' + y;
    }
  }
  })

Usage:


 <svg-sector size="32" degrees="120" sectorcolor="#ff5733" sectorwidth="30" text="1" textcolor="#ff5733" textsize="7em" />

А у наступній статті я покажу як можна за допомогою Vue створювати справжні параметричні креслення у форматі SVG та зберігати їх у окремий файл. 😎

P.S. Через декілька тижнів, після того як я почав використовувати SVG формат, мені на очі потрапила стаття про Angular 8 (https://medium.com/webbdev/angular-4c42d86eaa62). В ній було написано: "Теперь SVG файлы можно будет использовать в качестве шаблонов. До сих пор в качестве шаблонов можно было использовать встроенный или внешний HTML-код.". 👎 Це ж як потрібно було накурялясити у цьому Angular-і щоб одні теги він міг, а інші ні. І як так сталося що аж до самого 8-ї версії Angular-а не можна було юзати SVG як шаблон, який вже по факту дідусь? І як добре, що я зліз Angular 2 та Angular JS та перейшов на Vue...

Отже у наступній статті за допомогою Vue ми будемо створювати параметричне креслення у форматі SVG. І я розповім Вам кому і навіщо це знадобиться.

Смотри также:

Web-dev склерозник
Коментарі:
Додати коментар
Code
* - обов'язкові поля

Архіви