Beyond HTML with Vue

Eduardo

San Martin Morote

Vue core team

Vue.js Meetup Paris

Author of VueFire 2, VuexFire, VueMotion, ...

Consultant / Developer / Trainer

ย 

GitHub icon

Data Providers

<Motion tag="g" :values="selectedValues">
  <template slot-scope="values">
    <g v-for="(y, i) in values" class="bars">
      <rect
        :x="i * 10 + 20"
        :y="getMax - y * 10"
        width="10"
        :height="y * 10"
      />
    </g>
  </template>
</Motion>

State Animations with Springs

Original demo from @sar

<Promised :promise="promise">
  <h1 slot="pending">Loading</h1>
  <h1 slot="then" slot-scope="data">
    Success: {{ data }}
  </h1>
  <h1 slot="catch" slot-scope="error">
    Error: {{ error.message }}
  </h1>
</Promised>

Declarative Promises

export default {
  name: 'Promised',
  props: {
    promise: Promise
  },

  data () {
    return {
      resolved: false,
      data: null,
      error: null
    }
  },

  render (h) {
    if (this.error) {
      return this.$scopedSlots.catch(this.error)
    } else if (this.resolved) {
      return this.$scopedSlots.then(this.data)
    } else {
      return this.$slots.pending[0]
    }
  },

  watch: {
    promise: {
      handler (promise) {
        if (!promise) return
        this.resolved = false
        this.error = null
        promise
          .then(data => {
            if (this.promise === promise) {
              this.resolved = true
              this.data = data
            }
          })
          .catch(err => {
            if (this.promise === promise) this.error = err
          })
      },
      immediate: true
    }
  }
}

Vue-Promised.js

๐Ÿ“š Existing libs

Sounds &

Music

Declarative Sound

<Motion :value="desiredRate">
  <Sound
    slot-scope="{ value }"
    source="sandstorm.mp3"
    :rate="value"
  />
</Motion>

Canvas

WebGL

Declarative Three.js Scene

<Renderer :width="width" :height="height">
  <Scene>
    <Camera :position="camPos"/>
    <AmbientLight/>
    <SpotLight :position="lightPosition"/>
    <Cube
      v-for="cube in cubes"
      :key="cube.id"
      :position="cube.position"
    />
    <Ground/>
  </Scene>
</Renderer>

Scene.js

import { Scene } from 'three'
export default {
  inject: ['renderer'],
  provide () {
    this.scene = new Scene()
    return {
      scene: this.scene
    }
  },
  mounted () {
    this.renderer.scene = this.scene
  },
  render (h) {
    return h('div', this.$slots.default)
  }
}

Cube.js

import { BoxGeometry, MeshPhongMaterial, Mesh } from 'three'

export default {
  inject: ['scene'],
  mounted () {
    this.geometry = new BoxGeometry(1, 1, 1)
    this.material = new MeshPhongMaterial({
      color: 0xff0000,
      shininess: 150,
      specular: 0x222222
    })
    this.obj = new Mesh(this.geometry, this.material)
    this.obj.castShadow = true
    this.obj.receiveShadow = true
    this.scene.add(this.obj)
  },
  beforeDestroy () {
    this.scene.remove(this.obj)
  }
}

๐Ÿ•บDancing Cubes

<Motion v-for="(cube, i) in cubes"
  :values="cube" :key="i"
>
  <Cube
    slot-scope="cube"
    :rotation="rotation"
    :scale="cubeScale"
    :position="cube.position"
    :color="cube.color"
  />
</Motion>

Making it reactive

  • Add props (position, rotation)
  • Watch them to change mesh
  • Repeat with other entities

๐Ÿ“š Existing libs

Thanks! ๐Ÿ––

GitHub icon

Beyond Html with Vue

By Eduardo San Martin Morote

Beyond Html with Vue

8m Lighting talk about building non html components

  • 2,919