3D海洋效应与Canvas2D

1 篇文章 0 订阅
1 篇文章 0 订阅


预览效果


get2D(){
      /**
       *3D海洋效应与 Canvas2D
       * 您可以更改注释 "效果属性" 下的属性
       */
      // Init Context
      let a = this.$refs["app-container"]
      let c = document.createElement('canvas').getContext('2d')
      let d = document.createElement('canvas')
      let postctx = a.appendChild(d).getContext('2d')
      let canvas = c.canvas
      let vertices = []

      // Effect Properties
      let vertexCount = 7000
      let vertexSize = 3
      let oceanWidth = 204
      let oceanHeight = -80
      let gridSize = 32;
      let waveSize = 16;
      let perspective = 100;

      // Common variables
      let depth = (vertexCount / oceanWidth * gridSize)
      let frame = 0
      let { sin, cos, tan, PI } = Math
      if (postctx.canvas.width !== document.querySelector('.app-main').clientWidth || postctx.canvas.height !== document.querySelector('.app-main').clientHeight) {
        postctx.canvas.width = canvas.width = document.querySelector('.app-main').clientWidth
        postctx.canvas.height = canvas.height = document.querySelector('.app-main').clientHeight
      }
      // Render loop
      let loop = () => {
        let rad = sin(frame / 100) * PI / 20
        let rad2 = sin(frame / 50) * PI / 10
        frame++


        c.fillStyle = `hsl(200deg, 100%, 2%)`
        c.fillRect(0, 0, canvas.width, canvas.height)
        c.save()
        c.translate(canvas.width / 2, canvas.height / 2)

        c.beginPath()
        vertices.forEach((vertex, i) => {
          let ni = i + oceanWidth
          let x = vertex[0] - frame % (gridSize * 2)
          let z = vertex[2] - frame * 2 % gridSize + (i % 2 === 0 ? gridSize / 2 : 0)
          let wave = (cos(frame / 45 + x / 50) - sin(frame / 20 + z / 50) + sin(frame / 30 + z*x / 10000))
          let y = vertex[1] + wave * waveSize
          let a = Math.max(0, 1 - (Math.sqrt(x ** 2 + z ** 2)) / depth)
          let tx, ty, tz

          y -= oceanHeight

          // Transformation variables
          tx = x
          ty = y
          tz = z

          // Rotation Y
          tx = x * cos(rad) + z * sin(rad)
          tz = -x * sin(rad) + z * cos(rad)

          x = tx
          y = ty
          z = tz

          // Rotation Z
          tx = x * cos(rad) - y * sin(rad)
          ty = x * sin(rad) + y * cos(rad)

          x = tx;
          y = ty;
          z = tz;

          // Rotation X

          ty = y * cos(rad2) - z * sin(rad2)
          tz = y * sin(rad2) + z * cos(rad2)

          x = tx;
          y = ty;
          z = tz;

          x /= z / perspective
          y /= z / perspective



          if (a < 0.01) return
          if (z < 0) return


          c.globalAlpha = a
          c.fillStyle = `hsl(${180 + wave * 20}deg, 100%, 50%)`
          c.fillRect(x - a * vertexSize / 2, y - a * vertexSize / 2, a * vertexSize, a * vertexSize)
          c.globalAlpha = 1
        })
        c.restore()

        // Post-processing
        postctx.drawImage(canvas, 0, 0)

        postctx.globalCompositeOperation = "screen"
        postctx.filter = 'blur(16px)'
        postctx.drawImage(canvas, 0, 0)
        postctx.filter = 'blur(0)'
        postctx.globalCompositeOperation = "source-over"

        requestAnimationFrame(loop)
      }

      // Generating dots
      for (let i = 0; i < vertexCount; i++) {
        let x = i % oceanWidth
        let y = 0
        let z = i / oceanWidth >> 0
        let offset = oceanWidth / 2
        vertices.push([(-offset + x) * gridSize, y * gridSize, z * gridSize])
      }

      loop()
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值