zircleUI/zircleUI

View on GitHub
src/components/z-view.vue

Summary

Maintainability
Test Coverage
<template>
  <div
    class="z-shape primary"
    :class="[componentType, shape]"
    :style="responsive === true ? styles.main : zpos.main"
    style="overflow: visible;"
    @animationend="notify"
    @mouseover="$zircle.allowBackwardNavigation(true)"
    @mouseleave="$zircle.allowBackwardNavigation(false)">
    <div :id="fullView" v-if="$slots['image'] || imagePath" class="z-content">
      <img v-if="imagePath" :src="imagePath" width="100%" alt="content custom image"/>
      <slot v-if="!imagePath" name="image"></slot>
    </div>
    <section style="opacity: 0" :style="animation">
      <div class="z-outer-circle" :class="[shape]" :style="responsive === true ? styles.plate : zpos.plate"></div>
      <z-scroll v-if="scrollBarEnabled" :scrollVal.sync="scrollVal" style="overflow: visible;"/>
      <z-slider v-if="sliderEnabled" :progress='progress'/>
      <div v-if="label" class="z-label" :class="[shape, labelPos]">
        <div class="inside">
          {{ label }}
        </div>
      </div>
      <div class="z-content maincontent" ref="maincontent" :class="[shape, longContent]" @scroll.passive="scroll">
        <div ref="ztext">
          <slot></slot>
        </div>
      </div>
      <div v-if="$slots['media']" :class="[shape]" class="z-content" style="z-index: 60">
        <slot name="media"></slot>
      </div>
      <slot name="extension"></slot>
    </section>
  </div>
</template>

<script>
import ZSlider from './child-components/z-slider'
import ZScroll from './child-components/z-scroll'

export default {
  name: 'z-view',
  props: {
    distance: {
      type: Number,
      default: 0
    },
    angle: {
      type: Number,
      default: 0
    },
    size: {
      type: String,
      default: 'xxl'
    },
    circle: {
      type: [Boolean],
      default: false
    },
    square: {
      type: [Boolean],
      default: false
    },
    label: {
      type: [String, Number]
    },
    labelPos: {
      type: [String],
      default: 'bottom'
    },
    imagePath: {
      type: [String]
    },
    progress: {
      type: Number,
      default: 0
    },
    slider: {
      type: [Boolean],
      default: false
    }
  },
  components: {
    ZScroll,
    ZSlider
  },
  data () {
    return {
      componentType: this.$options.name,
      scrollVal: -45,
      zpos: {},
      isMounted: false,
      ffox: false,
      fullView: this.$zircle.getNavigationMode() === 'forward' ? this.$zircle.getCurrentViewName() : this.$zircle.getPastViewName()
    }
  },
  provide () {
    return {
      view: this.fullView
    }
  },
  computed: {
    shape () {
      if (this.square) {
        return 'is-square'
      }
      return 'is-circle'
    },
    sliderEnabled () {
      return this.slider === true && this.shape === 'is-circle'
    },
    scrollBarEnabled () {
      return this.scrollBar === true && this.shape === 'is-circle'
    },
    position () {
      return this.$zircle.calcViewPosition(this.fullView)
    },
    scrollBar () {
      let isScrollNeeded = false
      if (this.isMounted === true && this.fullView === this.$zircle.getCurrentViewName() && this.$refs.ztext.clientHeight > this.$zircle.getComponentWidth(this.size)) {
        isScrollNeeded = true
      }
      return isScrollNeeded
    },
    responsive () {
      return this.fullView === this.$zircle.getCurrentViewName()
    },
    styles () {
      const width = this.$zircle.getComponentWidth(this.size)
      return {
        main: {
          width: width + 'px',
          height: width + 'px',
          margin: -width / 2 + 'px 0 0 ' + -width / 2 + 'px',
          transform: 'translate3d(' + this.position.X + 'px, ' + this.position.Y + 'px, 0px) scale(' + this.position.scalei + ')'
        },
        plate: {
          width: width + 74 + 'px',
          height: width + 74 + 'px',
          margin: -((width + 74) / 2) + 'px 0 0 ' + -((width + 74) / 2) + 'px'
        }
      }
    },
    animation () {
      if (this.fullView === this.$zircle.getCurrentViewName() && this.$zircle.getNavigationMode() === 'forward') {
        return 'opacity: 1; transition: opacity 1000ms linear;'
      } else if (this.fullView === this.$zircle.getCurrentViewName() && this.$zircle.getNavigationMode() !== 'forward') {
        return 'opacity: 1;'
      }
      return 'opacity: 0; transition: opacity 500ms linear;'
    },
    longContent () {
      return {
        'overflow-square': this.scrollBar === true && this.shape === 'is-square'
      }
    }
  },
  methods: {
    notify () {
      if (this.$zircle.getHistoryLength() === 1) this.$zircle.setNavigationMode('iddle')
    },
    scroll () {
      if (this.scrollBar === true) {
        const container = this.$refs.maincontent
        this.scrollVal = -45 + ((container.scrollTop * 100 / (container.scrollHeight - container.clientHeight)) * 86 / 100)
      }
    }
  },
  watch: {
    responsive (isResponsive) {
      if (isResponsive) {
        this.zpos = this.styles
      }
    },
    scrollVal () {
      if (this.scrollBar === true) {
        const container = this.$refs.maincontent
        container.scrollTop = ((45 + this.scrollVal) * 100 / 86) * (container.scrollHeight - container.clientHeight) / 100
      }
    }
  },
  mounted () {
    this.zpos = this.styles
    const vm = this
    setTimeout(function () {
      vm.isMounted = true
    }, 1000)
  }
}
</script>