多层三角函数实现坚果首页效果

Posted seeyoumiter

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多层三角函数实现坚果首页效果相关的知识,希望对你有一定的参考价值。

<!DOCTYPE html5>
<html lang="en">
<head>
    <meta http-equiv="content-Type" content="text/html; charset=utf-8">
    <title>多层三角函数实现坚果首页效果</title>
    <style type="text/css">
        html,
        body {
          padding: 0;
          margin: 0;
          width: 100%;
          height: 100%;
          overflow: hidden;
        }

        canvas {
          width: 100%;
          height: 100%;
        }
    </style>
</head>
<body>
    <script type="text/javascript">
        function lerp (value1, value2, amount) {
          amount = amount < 0 ? 0 : amount
          amount = amount > 1 ? 1 : amount
          return value1 + (value2 - value1) * amount
        }

        const canvas = {
          init () {
            this.ele = document.createElement('canvas')
            document.body.appendChild(this.ele)
            this.resize()
            window.addEventListener('resize', () => this.resize(), false)
            this.ctx = this.ele.getContext('2d')
            return this.ctx
          },
          onResize (callback) {
            this.resizeCallback = callback
          },
          resize () {
            this.width = this.ele.width = window.innerWidth * 2
            this.height = this.ele.height = window.innerHeight * 2
            this.ele.style.width = this.ele.width * 0.5 + 'px'
            this.ele.style.height = this.ele.height * 0.5  + 'px'
            this.ctx = this.ele.getContext('2d')
            this.ctx.scale(2, 2)
            this.resizeCallback && this.resizeCallback()
          },
          run (callback) {
            requestAnimationFrame(() => {
              this.run(callback)
            })
            callback(this.ctx)
          }
        }

        const ctx = canvas.init()

        let objects = []

        class Nut {
          constructor ({x, y, width, height, color}) {
            this.x = x
            this.y = y
            this.width = width
            this.curHeight = height
            this.color = color
            this.targetHeight = height
          }
          update (height) {
            this.targetHeight = height
          }
          draw () {
            this.curHeight = lerp(this.curHeight, this.targetHeight, 0.1)
            ctx.beginPath()
            ctx.fillStyle = this.color
            ctx.rect(this.x, this.y - this.curHeight, this.width, this.curHeight)
            ctx.fill()
            ctx.closePath()
          }
        }

        class SineNuts {
          constructor () {
            this.total = 7
            this.colors = ['#FE615C', '#FFB66F', '#FFDA6C', '#E2F68B', '#8CF6F3', '#99B4F3', '#BEA1E8']
            this.padding = 10
            this.nuts = []
            const perWidth = window.innerWidth / this.total - this.padding
            for (let i = 0; i < this.total; i += 1) {
              // space-around
              const x = this.padding * (i + 1) + i * perWidth - this.padding * 0.5
              const y = window.innerHeight
              this.nuts.push(new Nut({
                x,
                y,
                width: perWidth,
                height: 0,
                color: this.colors[i]
              }))
            }
          }
          drawNuts (t) {
            const minHeight = 80
            const perWidth = window.innerWidth / this.total - this.padding
            for (let i = 0; i < this.total; i +=1) {
              const x = this.padding * (i + 1) + i * perWidth - this.padding * 0.5
              const nutX = x + perWidth * 0.5
              let height = Math.sin((nutX - mouse.x) * Math.PI / window.innerWidth + Math.PI * 0.5) * window.innerHeight * 0.85
              height = Math.max(height, minHeight)
              this.nuts[i].update(height)
              this.nuts[i].draw()
            }
            ctx.save()
            ctx.restore()
          }
          draw (t) {
            ctx.fillStyle = 'red'
            this.drawNuts(t)
            ctx.restore()
          }
        }

        const init = () => {
          objects = []
          objects.push(new SineNuts())
        }

        document.addEventListener('click', () => {
          init()
        })

        init()

        let mouse = {
          x: window.innerWidth * 0.5,
          y: window.innerHeight * 0.5
        }

        window.addEventListener('mousemove', (event) => {
          mouse.x = event.pageX
          mouse.y = event.pageY
        })

        let tick = 0
        canvas.run(ctx => {
          ctx.clearRect(0, 0, canvas.width, canvas.height)
          tick += 0.03
          objects.forEach(obj => {
            obj.draw(tick)    
          })
        })

        canvas.onResize(() => {
          init()
        })

    </script>
</body>
</html>

技术图片

以上是关于多层三角函数实现坚果首页效果的主要内容,如果未能解决你的问题,请参考以下文章

仿高德地图首页效果,简单代码实现

仿高德地图首页效果,简单代码实现

仿高德地图首页效果,简单代码实现

仿高德地图首页效果,简单代码实现

前端css综合案例1-7:新闻页面五彩导航产品模块快报模块学成在线首页CSS三角土豆案例

半糖iOS版首页实现与基本原理揭秘