Use canvas in vue to achieve the effect of tapered gradient-mobile terminal

Use canvas in vue to achieve the effect of tapered gradient-mobile terminal

Canvas achieves tapered gradient

Thanks to the great god LeaVerou

Originally there is a background:conic-gradient in css that can be implemented, but the compatibility is extremely poor. I originally used it in the project, and there was no problem with the computer test. The effect came out, but once it was packaged on the mobile phone, it was scrapped. I found a lot For information, LeaVerou provides a shim library. Polyfill is a development term. In Web development, the exact meaning of a polyfill shim library is: the code used to implement native APIs that the browser does not support. It is now extended as a compatible library that implements certain functions that the browser does not support.

<script src="//cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<script src="//leaverou.github.io/conic-gradient/conic-gradient.js"></script>
 

But at the beginning, it was obvious that the results of my mobile project could be achieved. This week, I discovered that the previously processed effects suddenly failed, which hurts.

So I thought of canvas, let s learn by myself and see how to fill the hole

Not much to say, just go to the code

In the component canvas.vue file:

<template>
<div class="canvasBox">
    <x-header
      :left-options="{showBack:true,backText: ''}"
      :right-options="{showMore:true}"
      @on-click-more="showMenus = true"
      >
      {{titleName}}
    </x-header>
    <div class="testBox">
      <div class="test">
          <canvas id="canvas" width="300" height="300" style="border-radius: 50%">
          </canvas>
      </div>
    </div>

</div>
</template>
<script>
import { XHeader } from 'vux'
export default {
  components: {
    XHeader
  },
  data () {
    return {
      titleName: this.$route.params.name,
      colorObj: {
       // 
        radianPI: Math.PI * 2,
       // 
        radianPiRadian: 30,
       // 
        ballArr: [],
       // 255
        colorScope: 255,
       // 
        num: 0
      }
    }
  },
  computed: {
    bStart () {
      return this.colorObj.radianPI * (this.colorObj.radianPiRadian/360) + (this.colorObj.radianPI * (60/360)/255) * (this.colorObj.num - 1)
     //return this.colorObj.radianPI * (30/360) * (this.colorObj.radianPiRadian - 1)
    },
    bEnd () {
      return this.colorObj.radianPI * (this.colorObj.radianPiRadian/360) + (this.colorObj.radianPI * (60/360)/255) * this.colorObj.num
    },
    rgbNum () {
     //`rgb(0,255,${this.rgbNumUp})`
      let c = null
      if (this.colorObj.radianPiRadian === 30) {
       // -- rgb(0,255,0)--(0,255,255)
        c = `rgb(0,255,${parseInt(255/(this.colorObj.colorScope - 1) * (this.colorObj.num - 1))})`
      } else if (this.colorObj.radianPiRadian === 90) {
       // -- rgb(0,255,255)--(0,0,255)
        c = `rgb(0,${parseInt(255 - (255/(this.colorObj.colorScope - 1) * (this.colorObj.num - 1)))},255)`
      } else if (this.colorObj.radianPiRadian === 150) {
       // -- rgb(0,0,255)--(255,0,255)
        c = `rgb(${parseInt(255/(this.colorObj.colorScope - 1) * (this.colorObj.num - 1))},0,255)`
      } else if (this.colorObj.radianPiRadian === 210) {
       // -- rgb(255,0,255)--(255,0,0)
        c = `rgb(255,0,${parseInt(255 - (255/(this.colorObj.colorScope - 1) * (this.colorObj.num - 1)))})`
      } else if (this.colorObj.radianPiRadian === 270) {
       // -- rgb(255,0,0)--(255,255,0)
        c = `rgb(255,${parseInt(255/(this.colorObj.colorScope - 1) * (this.colorObj.num - 1))},0)`
      } else if (this.colorObj.radianPiRadian === 330) {
       // -- rgb(255,255,0)--(0,255,0)
        c = `rgb(${parseInt(255 - (255/(this.colorObj.colorScope - 1) * (this.colorObj.num - 1)))},255,0)`
      }
      return c
    }
  },
  methods: {
    constructionAperture () {
      function Ball (roundObj) {
        this.x = roundObj.x
        this.y = roundObj.y
        this.r = roundObj.r
        this.borderStart = roundObj.borderStart
        this.borderEnd = roundObj.borderEnd
        this.direction = roundObj.direction
        this.lineW = roundObj.lineW
        this.color = roundObj.color
      }
      Ball.prototype.render = function () {
        let myCanvas = document.querySelector('canvas')
        myCanvas.style.width = `100%`
        myCanvas.style.height = `100%`
        let ctx = myCanvas.getContext('2d')
        ctx.beginPath()
        ctx.arc(this.x, this.y, this.r, this.borderStart, this.borderEnd, this.direction)
        ctx.lineWidth = this.lineW
        ctx.strokeStyle = this.color
        ctx.stroke()
      }
      for (let k = 0; k < 6; k++) {
        this.colorObj.radianPiRadian = 30 + (60 * k)
        this.colorObj.num = 0
        this.repeatRender()
        for (let i = 0; i < this.colorObj.ballArr.length; i++) {
          new Ball(this.colorObj.ballArr[i]).render()
        }
      }
    },
    repeatRender () {
      for (let i = 0; i < this.colorObj.colorScope; i++) {
        this.colorObj.num++
        this.colorObj.roundObj = {
          x: 150,
          y: 150,
          r: 100,
          borderStart: this.bStart,
          borderEnd: this.bEnd,
          direction: false,
          lineW: 100,
          color: this.rgbNum
        }
        this.colorObj.ballArr.push(this.colorObj.roundObj)
      }
    }
  },
  mounted () {
   //html rem 
    this.setHtmlFontToRem.setRootFont(640, document.querySelector('html'))
   //
    this.constructionAperture()
  }
}

</script>
<style lang="scss" scoped>
.testBox{
  width: 100%;
  height: 100%;

  .test{
    width: 3rem;
    height: 3rem;
    margin: auto;
    margin-top: 1rem;
    border: 1px solid #333;
  }
}

</style>

 

Adapted setHtmlFontToRem.js file:


let getWinWH = () => {
  let offsetWid = null
  let offsetHei = null
  if (/(Android)/i.test(navigator.userAgent)) {// Android 
    offsetWid = screen.width
    offsetHei = screen.height
  } else if (/(iPhone|iPad|iPod|iOS)/i.test(navigator.userAgent)) {// 
    offsetWid = document.documentElement.clientWidth
    offsetHei = document.documentElement.clientHeight
  } else {
    offsetWid = document.documentElement.clientWidth
    offsetHei = document.documentElement.clientHeight
  }
  return {
    offsetWid,
    offsetHei
  }
}
let setRootFont = (pageW, HtmlDom) => {
 // 
 //console.log(pageW)
 //console.log(HtmlDom)
 // 
  let pageWidth = pageW || 640
 // 100 
  let rootFontSize = 100
  HtmlDom.style.fontSize = `${getWinWH().offsetWid/pageWidth * rootFontSize}px`
  window.onresize = function () {
    HtmlDom.style.fontSize = `${getWinWH().offsetWid/pageWidth * rootFontSize}px`
  }
 //console.log(getWinWH().offsetWid);
 //console.log(getWinWH().offsetHei);
 //console.log(HtmlDom.style.fontSize);
}
let setRootHtmlFont = { setRootFont }
export default setRootHtmlFont
 

In main.js:

//setHtmlFontToRem.js 
import setHtmlFontToRem from '@/assets/js/setHtmlFontToRem'
//Vue 
Vue.prototype.setHtmlFontToRem = setHtmlFontToRem
 

Effect picture:

Note: If there are similarities, please include more. Writing on May 19, 2019