前端动画---sad man 源码

本文介绍了一个使用HTML5 Canvas API实现的简单动画案例,演示了如何通过JavaScript动态绘制一位悲伤的小人,包括头部、身体、脚部及其阴影,并通过数学函数使动画更加生动。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原文链接:源码(https://codepen.io/HelKyle/pen/Mqgpvb)

html,
body{
   padding:0;
   margin:0;
   width:100%;
   height:100%;
   overflow:hidden;
}

canvas{
   width:100%;
   height:100%;
   background:#f1513b;
}
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 SadMan{
    drawHead(t){
       ctx.save()
       ctx.beginPath()
       ctx.translate(0,Math.sin(t) * 4)
       ctx.arc(80,-35,35,0,2*Math.PI)
       ctx.fill()
       ctx.closePath()
       ctx.restore()
    }
    drawBody(t){
       ctx.beginPath()
       ctx.save()
       ctx.rotate(Math.sin(t) * Math.PI/180* -1)
       ctx.translate(0,Math.sin(t) * 4)
       ctx.scale(0.5,0.5)
       const body= new Path2D('M125,284 L1,284 CO.33333333,94.6666667 35,0 105,0 C115.666667,4 122.333333,20.6666667 125,50 L125,284 Z')
       ctx.fill(body)
       ctx.restore()
       ctx.closePath()
    }
    drawFeet(t){
       t = t /2
       ctx.save()
       ctx.scale(0.5,0.5)
       ctx.translate(0,460)
       const foot = new Path2D('M23,0 C67,0 80,16 80,22 C80,26 78.6666667,28 76,28 C29.3333333,28 6,28 6,28 C6,28 -1.34111707e-14,30 0,17 C1.42108547e-14,4 10,1.9505735e-16 13,0 C16,0 13,0 23,0 Z')
    
       ctx.save()
       ctx.translate(Math.cos(t) * -50, Math.sin(t) > 0 ? Math.sin(t) * -35 : 0)
       if (t < Math.PI) {
          ctx.rotate(Math.sin(t) * Math.PI / 180 * -5)
       }
       ctx.fill(foot)
       ctx.restore()

       ctx.save()
       ctx.translate(Math.cos(t + Math.PI) * -50, Math.sin(t + Math.PI) > 0 ? Math.sin(t + Math.PI) * -35 : 0)
       if (t > Math.PI) {
         ctx.rotate(Math.sin(t + Math.PI) * Math.PI / 180 * -5)
       }
       ctx.fill(foot)
       ctx.restore()

       ctx.restore()
     }
     drawShadow (t) {
       ctx.beginPath()
       ctx.save()
       ctx.scale(0.5, 0.5)
       ctx.translate(45, 490)
       ctx.fillStyle = 'rgba(0, 0, 0, 0.1)'
       ctx.ellipse(0, 0, 120 + Math.sin(t) * 10, 8, 0, 0, 2 * Math.PI)
       ctx.fill()
       ctx.restore()
       ctx.closePath()
     }
     draw (t) {
        t = t % Math.PI * 2
        ctx.fillStyle = 'white'
        ctx.save()
        ctx.translate(window.innerWidth * 0.5 - 140, window.innerHeight * 0.5 - 80)
        this.drawShadow(t)
        this.drawHead(t)
        this.drawBody(t)
        this.drawFeet(t)
        ctx.restore()
     }
  }

  const init = () => {
  objects = []
  objects.push(new SadMan())
  // objects.push(new Feet())
}

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

init()

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()
})

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值