ScalableΒ  Β  Β ue graphics for the modern web

πŸ˜‰

Dima Vishnevetsky

Most of you used SVG before!

%

We all know that we can use SVG for scalable icons

We can also animate them and still be able to control all the styling

Some of you used SVG for other stuff besides Icons

We all know we can use SVG for graphics and illustrations

Who used SVG for anything else?

Using SVG for illustrations and icons only scratches the surface of this format’s potential on the web

About me

Dima Vishnevetsky

πŸ‘¨β€πŸ’» Front End Architect

πŸ’š VueJS Israel community leader

πŸ’Ό Consultant

πŸ“ UX / UI Designer

πŸ–Ό Media Developer Expert @ Cloudinary

πŸ‘¨β€πŸ« #HackathonMentor

πŸŽ“ Lecturer

πŸ—£ International Tech speaker

The first place we encounter SVG in relation to Vue is directly in the documentation

Thanks, Sarah Drasner for that nice example

Vue documentation suggest using SVG Icon Systems

<template>
  <svg
    @click="startScissors"
    xmlns="http://www.w3.org/2000/svg"
    viewBox="0 0 100 100"
    width="100"
    height="100"
    aria-labelledby="scissors"
    role="presentation"
  >
    <title
      id="scissors"
      lang="en"
    >Scissors Animated Icon</title>
    <path
      id="bk"
      fill="#fff"
      d="M0 0h100v100H0z"/>
    <g ref="leftscissor">
      <path d="M..."/>
      ...
    </g>
    <g ref="rightscissor">
      <path d="M..."/>
      ...
    </g>
  </svg>
</template>

We can copy the SVG code directly inside our templates

Of course, we don't like to do it manually, we have tools to help us

Vue-svg-loader

<template>
  <nav>
    <a href="https://github.com/vuejs/vue">
      <VueLogo />
      Vue
    </a>
    <a href="https://github.com/svg/svgo">
      <SVGOLogo />
      SVGO
    </a>
    <a href="https://github.com/webpack/webpack">
      <WebpackLogo />
      webpack
    </a>
  </nav>
</template>
<script>
import VueLogo from './public/vue.svg';
import SVGOLogo from './public/svgo.svg';
import WebpackLogo from './public/webpack.svg';
 
export default {
  name: 'Example',
  components: {
    VueLogo,
    SVGOLogo,
    WebpackLogo,
  },
};
</script>

Using SVG as a Vue component feels so natural

Why I love SVG + Vue?

  • Vue supports SVG out of the box
    Β 
  • SVG, like HTML, is XML-based, so we can apply Vue's reactivity system to SVG and make it interactive in the same easy and convenient way as we do with HTML templates

SVG and Vue make the perfect match

Is this a talk not about the common knowledge on how to use SVG?

Import SVG with webpack

Use SVG sprites with

<symbol> and <use>

Wait a minute

const webpack = require('webpack');

module.exports = {
  entry: './src/index.js',
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        use: ['babel-loader'],
      },
      {
        test: /\.svg$/,
        use: [
          {
            loader: 'svg-url-loader',
            options: {
              limit: 10000,
            },
          },
        ],
      },
    ],
  },
  ...
};
<svg viewBox="0 0 100 100" class="icon shape">
  <use xlink:href="#shape"></use>
</svg>

In this talk we will focus on the What

I don't think that most of the Front End Developers are as comfortable with SVG as they should be

Developers (and I'm guilty of this myself) will in most cases build stuff using HTML and CSS instead of drawing it in a much simple and easy way with SVG

Everything done with SVG can be created using HTML & CSS

YES

SVG is one of the most powerful technologies available on the web

πŸ’ͺ

πŸ’ͺ

Make money πŸ€‘ from SVG

WHAT

Can we do with SVG?

Show emotions with SVG animations

3D with SVG

πŸ‘‰

Build design systems

  <mochi-box shiba="anko" mood="cheeky" 
    left-eye="open" right-eye="laugh"
    left-ear="flat" right-ear="middle"> 
    <h2>あんこ</h2>
    <h3>
      <a target="_blank" href="#">Sweet Bean</a>
    </h3>
    <p class="shop uemachi" title="uemachi">γ†γˆγΎγ‘ε›£ε­</p>
  </mochi-box>
.anko {
  .outline { stroke: #3c2012; }
  .fur { fill: #603d1e; }
  .fur2 { fill: #fad4af; }
  .inner { fill: #fad4af; }
  .eye { fill: #3c2012; }
}

.MochiShiba {
  &.blush {
    #cheeks { visibility: visible }
  }
  &.content {
    [id^=mouth] { visibility: hidden; }
  }
  &.happy {
    [id^=mouth] { visibility: hidden; }
    #mouth2 { visibility: visible; }
  }
  &.excited {
    [id^=mouth] { visibility: hidden; }
    #mouth3 { visibility: visible; }
  }
}
Vue.component( "MochiShiba", {
  
  template: `
    <div class="MochiShiba /" :class="styleClass">
      <svg class="shiba" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="152" height="174" viewBox="0 0 152 174">
        <title>Mochi Shiba</title>
        .
        .
        .
      </svg>
    </div>
  `,
  props: {
    size: { type: String, default: "medium" },
    shiba: { type: String, default: "okaka" },
    mood: { type: String, default: "" },
    leftEye: { type: String, default: "open" },
    rightEye: { type: String, default: "open" },
    leftEar: { type: String, default: "up" },
    rightEar: { type: String, default: "flat" },
    blush: { type: Boolean, default: false }
  },
  computed: {
    ears: function() {
      let l = "l4";
      let r = "r4";
      if ( this.leftEar === "up" ) { l = "l1"; }
      else if ( this.leftEar === "down" ) { l = "l3"; }
      else if ( this.leftEar === "flat" ) { l = "l2"; }
      if ( this.rightEar === "up" ) { r = "r1"; }
      else if ( this.rightEar === "down" ) { r = "r3"; }
      else if ( this.rightEar === "flat" ) { r = "r2"; }
      return `/ ears ${l} ${r}`;
    },
    eyes: function() {
      if ( this.leftEye === this.rightEye ) {
        return `/ eyes ${this.leftEye}`;
      } else {
        return `/ eyes l${this.leftEye} r${this.rightEye}`;
      }
    },
    cheeks: function() {
      return this.blush ? "/ blush" : "";
    },
    styleClass: function() {
      return `${this.size} / ${this.mood} ${this.eyes} ${this.ears} ${this.cheeks}`;
    }
  },
  methods: {},
});

Micro Interactions

Non standard UI elements

Logos

Animated logos

Media queries

media queries embed within the SVG file, work from the SVGs viewport size.

Text effects

ART

ART

Loaders

Line drawing

Filters & effects

Interactive Infographics

React to mouse events based on shapes

Β Marcin

Be creative with background image

Be creative with favicons

<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>πŸ”₯</text></svg>">

Browsers started supporting SVG for favicons

Be creative

Websites

Tools

Vue.js + GSAP = πŸ”₯

Whats next?

SVG + VR

Why use SVG?

Resolution independent and future-proof

πŸ“

File Size

πŸ‹οΈβ€β™‚οΈ

Multicolor - More CSS control than any other method

🌈

Animatable and Scriptable

πŸŽ₯

Browser support

πŸ“Ί

Better accessibility and SEO

πŸ”

Semantically correct - SVG is an image (not drawing stuff with div/span)

πŸ–Ό

Ease of use - Easy to create and manage using apps and build tools

🍼

It's a syntax - you can read it, you can change it

πŸ“–

Key takeaway

When you solving any issue, ask yourself why not use SVG?

πŸ”‘

Thank you

Dima Vishnevetsky

@dimshik100

www.dimshik.com

Scalable Vue Graphics for the modern web - JS VidCon 2020

By Dima Vishnevetsky

Scalable Vue Graphics for the modern web - JS VidCon 2020

Slides for my talk about SVG and Vue for the JS VidCon 2020 conference

  • 1,274