网站建设中canvas效果------会跳舞的机器人

html5 canvas小人跳舞动画特效 立即下载

效果预览

效果预览

创建robot类

  1. 机器人构造函数

constructor(color, light, size, x, y, struct) {
  this.x = x;
  this.points = [];
  this.links = [];
  this.frame = 0;
  this.dir = 1;
  this.size = size;
  this.color = Math.round(color);
  this.light = light;
  for (const p of struct.points) {
    this.points.push(new Robot.Point(size * p.x + x, size * p.y + y, p.f))
  }
  for (const link of struct.links) {
    const p0 = this.points[link.p0];
    const p1 = this.points[link.p1];
    const dx = p0.x - p1.x;
    const dy = p0.y - p1.y;
    this.links.push(new Robot.Link(this, p0, p1, Math.sqrt(dx * dx + dy * dy), link.size * size / 3, link.lum, link.force, link.disk))
  }
}
  1. 更新帧动画

update() {
  if (++this.frame % 20 === 0) this.dir = -this.dir;
  if (dancerDrag && this === dancerDrag && this.size < 16 && this.frame > 600) {
    dancerDrag = null;
    dancers.push(new Robot(this.color, this.light * 1.25, this.size * 2, pointer.x, pointer.y - 100 * this.size * 2, struct));
    dancers.sort(function(d0, d1) {
      return d0.size - d1.size
    })
  }
  for (const link of this.links) {
    const p0 = link.p0;
    const p1 = link.p1;
    const dx = p0.x - p1.x;
    const dy = p0.y - p1.y;
    const dist = Math.sqrt(dx * dx + dy * dy);
    if (dist) {
      const tw = p0.w + p1.w;
      const r1 = p1.w / tw;
      const r0 = p0.w / tw;
      const dz = (link.distance - dist) * link.force;
      const sx = dx / dist * dz;
      const sy = dy / dist * dz;
      p1.x -= sx * r0;
      p1.y -= sy * r0;
      p0.x += sx * r1;
      p0.y += sy * r1
    }
  }
  for (const point of this.points) {
    if (this === dancerDrag && point === pointDrag) {
      point.x += (pointer.x - point.x) * 0.1;
      point.y += (pointer.y - point.y) * 0.1
    }
    if (this !== dancerDrag) {
      point.fn && point.fn(16 * Math.sqrt(this.size), this.dir)
    }
    point.vx = point.x - point.px;
    point.vy = point.y - point.py;
    point.px = point.x;
    point.py = point.y;
    point.vx *= 0.995;
    point.vy *= 0.995;
    point.x += point.vx;
    point.y += point.vy + 0.01
  }
  for (const link of this.links) {
    const p1 = link.p1;
    if (p1.y > canvas.height * ground - link.size * 0.5) {
      p1.y = canvas.height * ground - link.size * 0.5;
      p1.x -= p1.vx;
      p1.vx = 0;
      p1.vy = 0
    }
  }
  this.points[3].x += (this.x - this.points[3].x) * 0.001
}
  1. 画布上绘制

draw() {
  for (const link of this.links) {
    if (link.size) {
      const dx = link.p1.x - link.p0.x;
      const dy = link.p1.y - link.p0.y;
      const a = Math.atan2(dy, dx);
      const d = Math.sqrt(dx * dx + dy * dy);
      ctx.save();
      ctx.translate(link.p0.x + link.size * 0.25, link.p0.y + link.size * 0.25);
      ctx.rotate(a);
      ctx.drawImage(link.shadow, -link.size * 0.5, -link.size * 0.5, d + link.size, link.size);
      ctx.restore();
      ctx.save();
      ctx.translate(link.p0.x, link.p0.y);
      ctx.rotate(a);
      ctx.drawImage(link.image, -link.size * 0.5, -link.size * 0.5, d + link.size, link.size);
      ctx.restore()
    }
  }
}

robot 关节

Robot.Link = class Link {
  constructor(parent, p0, p1, dist, size, light, force, disk) {
    function stroke(color, axis) {
      const image = document.createElement("canvas");
      image.width = dist + size;
      image.height = size;
      const ict = image.getContext("2d");
      ict.beginPath();
      ict.lineCap = "round";
      ict.lineWidth = size;
      ict.strokeStyle = color;
      if (disk) {
        ict.arc(size * 0.5 + dist, size * 0.5, size * 0.5, 0, 2 * Math.PI);
        ict.fillStyle = color;
        ict.fill()
      } else {
        ict.moveTo(size * 0.5, size * 0.5);
        ict.lineTo(size * 0.5 + dist, size * 0.5);
        ict.stroke()
      }
      if (axis) {
        const s = size / 10;
        ict.fillStyle = "#000";
        ict.fillRect(size * 0.5 - s, size * 0.5 - s, s * 2, s * 2);
        ict.fillRect(size * 0.5 - s + dist, size * 0.5 - s, s * 2, s * 2)
      }
      return image
    }
    this.p0 = p0;
    this.p1 = p1;
    this.distance = dist;
    this.size = size;
    this.light = light || 1.0;
    this.force = force || 0.5;
    this.image = stroke("hsl(" + parent.color + " ,30%, " + parent.light * this.light + "%)", true);
    this.shadow = stroke("rgba(0,0,0,0.5)")
  }
};

robot 位置

Robot.Point = class Point {
  constructor(x, y, fn, w) {
    this.x = x;
    this.y = y;
    this.w = w || 0.5;
    this.fn = fn || null;
    this.px = x;
    this.py = y;
    this.vx = 0.0;
    this.vy = 0.0
  }
};

画布基本配置

const canvas = {
  init() {
    this.elem = document.querySelector("canvas");
    this.resize();
    window.addEventListener("resize", () => this.resize(), false);
    return this.elem.getContext("2d")
  },
  resize() {
    this.width = this.elem.width = this.elem.offsetWidth;
    this.height = this.elem.height = this.elem.offsetHeight;
    ground = this.height > 500 ? 0.85 : 1.0;
    for (let i = 0; i < dancers.length; i++) {
      dancers[i].x = (i + 2) * canvas.width / 9
    }
  }
};

鼠标操作robot

const pointer = {
  init(canvas) {
    this.x = 0;
    this.y = 0;
    window.addEventListener("mousemove", e => this.move(e), false);
    canvas.elem.addEventListener("touchmove", e => this.move(e), false);
    window.addEventListener("mousedown", e => this.down(e), false);
    window.addEventListener("touchstart", e => this.down(e), false);
    window.addEventListener("mouseup", e => this.up(e), false);
    window.addEventListener("touchend", e => this.up(e), false)
  },
  down(e) {
    this.move(e);
    for (const dancer of dancers) {
      for (const point of dancer.points) {
        const dx = pointer.x - point.x;
        const dy = pointer.y - point.y;
        const d = Math.sqrt(dx * dx + dy * dy);
        if (d < 60) {
          dancerDrag = dancer;
          pointDrag = point;
          dancer.frame = 0
        }
      }
    }
  },
  up(e) {
    dancerDrag = null
  },
  move(e) {
    let touchMode = e.targetTouches,
    pointer;
    if (touchMode) {
      e.preventDefault();
      pointer = touchMode[0]
    } else pointer = e;
    this.x = pointer.clientX;
    this.y = pointer.clientY
  }
}

准备工作

const dancers = [];
let ground = 1.0;
const ctx = canvas.init();
pointer.init(canvas);
let dancerDrag = null;
let pointDrag = null;
const run = () => {
  requestAnimationFrame(run);// 浏览器下次重绘之前,调用run函数
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  ctx.fillStyle = "#222";
  ctx.fillRect(0, 0, canvas.width, canvas.height * 0.15);
  ctx.fillRect(0, canvas.height * 0.85, canvas.width, canvas.height * 0.15);
  for(const dancer of dancers){
    dancer.update();
    dancer.draw()
  }
};

初始化位置

const struct = {
  points: [{
    x: 0,
    y: -4,
    f(s, d) {
      this.y -= 0.01 * s
    }
  },
  {
    x: 0,
    y: -16,
    f(s, d) {
      this.y -= 0.02 * s * d
    }
  },
  {
    x: 0,
    y: 12,
    f(s, d) {
      this.y += 0.02 * s * d
    }
  },
  {
    x: -12,
    y: 0
  },
  {
    x: 12,
    y: 0
  },
  {
    x: -3,
    y: 34,
    f(s, d) {
      if (d > 0) {
        this.x += 0.01 * s;
        this.y -= 0.015 * s
      } else {
        this.y += 0.02 * s
      }
    }
  },
  {
    x: 3,
    y: 34,
    f(s, d) {
      if (d > 0) {
        this.y += 0.02 * s
      } else {
        this.x -= 0.01 * s;
        this.y -= 0.015 * s
      }
    }
  },
  {
    x: -28,
    y: 0,
    f(s, d) {
      this.x += this.vx * 0.035;
      this.y -= 0.001 * s
    }
  },
  {
    x: 28,
    y: 0,
    f(s, d) {
      this.x += this.vx * 0.035;
      this.y -= 0.001 * s
    }
  },
  {
    x: -3,
    y: 64,
    f(s, d) {
      this.y += 0.015 * s;
      if (d > 0) {
        this.y -= 0.01 * s
      } else {
        this.y += 0.05 * s
      }
    }
  },
  {
    x: 3,
    y: 64,
    f(s, d) {
      this.y += 0.015 * s;
      if (d > 0) {
        this.y += 0.05 * s
      } else {
        this.y -= 0.01 * s
      }
    }
  }],
  links: [{
    p0: 3,
    p1: 7,
    size: 12,
    lum: 0.5
  },
  {
    p0: 1,
    p1: 3,
    size: 24,
    lum: 0.5
  },
  {
    p0: 1,
    p1: 0,
    size: 60,
    lum: 0.5,
    disk: 1
  },
  {
    p0: 5,
    p1: 9,
    size: 16,
    lum: 0.5
  },
  {
    p0: 2,
    p1: 5,
    size: 32,
    lum: 0.5
  },
  {
    p0: 1,
    p1: 2,
    size: 50,
    lum: 1
  },
  {
    p0: 6,
    p1: 10,
    size: 16,
    lum: 1.5
  },
  {
    p0: 2,
    p1: 6,
    size: 32,
    lum: 1.5
  },
  {
    p0: 4,
    p1: 8,
    size: 12,
    lum: 1.5
  },
  {
    p0: 1,
    p1: 4,
    size: 24,
    lum: 1.5
  }]
};
for (let i = 0; i < 6; i++) {
  dancers.push(new Robot(i * 360 / 7, 80, (window.location.href.indexOf("fullcpgrid") > -1) ? 3 : 4, (i + 2) * canvas.width / 9, canvas.height * ground - 300, struct))
}

run()

完整代码见robot-dancer

HTML5 Canvas机器人跳舞动画特效.zip HTML5 Canvas机器人跳舞动画特效是一款机器人跳舞效果,如果加上背景音乐,就可以完美展现canvas的强大动画效果。 立即下载

相关推荐

舞蹈机器人 源程序

完整的舞蹈机器人源代码并带有详细的解释,以及资料包 完整的舞蹈机器人源代码并带有详细的解释,以及资料包 完整的舞蹈机器人源代码并带有详细的解释,以及资料包 完整的舞蹈机器人源代码并带有详细的解释,以及资料包

使用canvas绘制机器人

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>机器人</title> <style> body{margin: 0;overflow: hidden;} #canvas{background: antiquewhite;} </style> </he.

caoxinjian423的博客 1316

使用Canvas类绘制android机器人

使用Canvas类绘制android机器人

使用canvas画一个机器人(任意想象)

首先,我们绘制了机器人的身体(一个矩形),然后绘制了头部(一个圆形),接着是眼睛(两个小圆形),最后是手臂和腿(矩形)。在HTML5的Canvas上绘制一个机器人涉及到一些基本的绘图技术,包括绘制圆形、矩形、线条等。以下是一个简单的示例,用于绘制一个简易的机器人形象。请注意,这只是一个非常基础的示例,你可以根据自己的创意和绘图技巧来扩展和完善这个机器人的形象。// 绘制机器人的身体。// 绘制机器人的眼睛。// 绘制机器人的手臂。// 绘制机器人的头。// 绘制机器人的腿。

王铁柱666的博客 543

CSS3+SVG实现的机器人(外星人)情侣漫步森林动画场景效果源码.zip

CSS3+SVG实现的机器人(外星人)情侣漫步森林动画场景效果源码

HTML5 Canvas机器人跳舞动画特效特效代码

HTML5 Canvas机器人跳舞动画特效是一款机器人跳舞效果,如果加上背景音乐,就可以完美展现canvas的强大动画效果。

2024年前端最新QQ机器人制作教程,超详细

由于篇幅限制,pdf文档的详解资料太全面,细节内容实在太多啦,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】但是这也有一个坏处,就是不可编程修改,功能已经固定了,十分适合新手!!皮小孩的个人主页由于篇幅限制,pdf文档的详解资料太全面,细节内容实在太多啦,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

weixin_41978174的博客 606

Day2 十分钟带你解决逆向中对称加密算法 (RC4)

在密码学中,RC4(来自Rivest Cipher 4的缩写)是一种串流加密算法,密钥长度可变。他加密解密使用相同的密钥,因此也被称为“流加密算法”。RC4由伪随机数生成器和异或运算组成。RC4的密钥长度可变,范围是[1,255]。RC4一个字节一个字节地加解密。给定一个密钥,伪随机数生成器接受密钥并产生一个S盒。S盒用来加密数据,而且在加密过程中S盒会变化。由于异或运算的对合性,RC4加密解密使用同一套算法。

m0_73779708的博客 1289

期待已久的 AI 演示动画制作终于来了!

期待已久的 AI 演示动画制作终于来了!

余璜的技术博客 1059

储能逆变器动态无功补偿:从原理到算法实现

本文深入解析了储能逆变器动态无功补偿的核心原理与算法实现。通过四象限运行与解耦控制技术,储能逆变器可在充放电的同时,快速、精准地调节无功功率,有效提升电网电能质量与功率因数。文章详细阐述了从相位调节、容量限制到PI控制算法的完整技术路径,并结合工程实践,探讨了其在光伏/储能系统中的协同控制策略与进阶应用价值。

weixin_29216353的博客 207

BIOS硬件监控实战:如何手动读取IT8738芯片的温度与风扇数据(附代码)

本文深入探讨了如何绕过操作系统和HWMonitor等监控软件,直接通过寄存器级操作读取IT8738超级I/O芯片的硬件监控数据。文章提供了从动态定位EC空间、构建底层读写函数到解码传感器寄存器映射的完整实战指南,并附有C语言代码示例,帮助开发者理解BIOS硬件监控的底层原理,适用于定制硬件开发与故障诊断。

weixin_29192211的博客 109

使用canvas完成帧动画(方向键控制行走的小人)

&lt;!DOCTYPE html&gt; &lt;html lang="en"&gt; &lt;head&gt; &lt;meta charset="UTF-8"&gt; &lt;title&gt;Title&lt;/title&gt; &lt;style&gt; canvas { bord

qq_32849999的博客 3349

300个fpga练手项目推荐

• 按键设置BPM,LED和蜂鸣器同步打拍(支持4/4、3/4拍)• 例:先实现DDR3控制器(基础),再构建视频处理流水线(集成)◦ 驱动小型e-Paper显示日期/时间(SPI接口,静态刷新)◦ 音频输入经FFT后,用LED柱状显示频率能量(8频段简化)◦ 通过HC-05模块接收手机指令,控制电机方向(前进/后退)• 随机点亮LED,用按钮响应,数码管显示反应时间(毫秒级)• 8个LED旋转闪烁,按钮停止后显示中奖编号(带减速动画)• 用4方向按键输入手势(如→→←↑),正确后点亮绿色LED。

qq_62784677的博客 7641

前端画canvas得在线网站

在线制作Canvas图像的网站有很多,例如: Piximake: https://www.piximake.com/ Canva: https://www.canva.com/ Adobe Spark: https://spark.adobe.com/ Desygner: https://www.desygner.com/cn/ PicMonkey: https://www.picmonkey....

weixin_35750953的博客 3901

镜头像差之五——场曲

什么是场曲? 场曲[curvature of field] 物面上所有的点经过系统后,最佳焦点位置不在同一平面上,若这些像点所成的面为曲面,则称为系统有场曲。 与物高二次方、入射光瞳口径一次方成正比的像差。若仅存在场曲,则所有物平面上的点都有相应的像点,但分布在一个球面上;若采用弯成此种形状的底片,则可获得处处清晰的像。此时在理想像平面上,像点呈现为圆斑。 第一张图是最简单也是最容易理解的场曲,也就是对焦点锐利,其余部分逐渐松散,但实际上大多现代镜头的场曲都呈现为图二的形态:对焦点与边缘锐度.

camerall 1万+

【经验&技巧】DDR仿真中的挑战与解决方案

由于DDR的数据总线具备双向数据传输功能,需要对读写模式进行独立仿真环境的创建,并且分为连续和突发模式,再加之有单端和差分信号、有数据总线和地址总线,需要在数据传输过程中额外注意串扰的影响,并选择合适的驱动和负载以找寻设计裕量与串扰强度之间的平衡,因此,实际操作步骤和分析过程还是较为繁琐耗时的,需要设计者具有足够的耐心。

一只豌豆象的博客 1643

HTML5的<canvas>实用网站

1,SketchPad Sketchpad 是个优秀的 HTML5 应用,帮助我们创建有用的绘图应用,使用JS和canvas元素。Sketchpad 的绘图工具具有丰富的功能。 http://mugtug.com/sketchpad/ 2,Canvas Color Cycling 具有下雨、下雪、海浪、烟雾的效果。 http://www.effectgames.com/demos...

WALK ON 1795

Unity-Mirror网络框架-从入门到精通之MultipleMatches示例

Multiple Matches 示例主要讲述了如何在使用 Mirror 网路框架时管理多个游戏匹配。以及如何设置一个能够同时支持多个游戏会话的系统,使玩家能够加入他们所选择的比赛,而不是强制他们加入一个单一的匹配。

TxNet 964

web前端网页设计必备的六个宝藏网站(非常值得收藏)

各式各样的高质量海报让你眼花缭乱,甚至还有各种字体设计,只有你想不到的,没有你找不到的。网站提供多种便捷操作:复制 SVG code、复制 React 组件、复制 Vue 组件、下载 PNG、下载 SVG,无论是设计师还是开发者,使用起来都非常方便。,内容丰富且精美,只有你想不到的,没有你找不到的。当你想找点配色灵感时,点进本网站,滑动鼠标可展示随机颜色,可展示不同的配色供你选择。网址:https://www.pexels.com/zh-cn/,可以找到你想要的图片以及视频素材来满足你的设计需求。...

qq_3200628753的博客 7972

ARFoundation系列讲解 - 24 锚点

一、添加平面检测和平面可视化 请参考 ARFounnation快速入门-08平面检测 案例 二、添加射线检测 1.在AR Session Origin 组件上添加ARRaycastManager 脚本

a451319296的博客 4877

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

HTML5canvas作品网站,HTML5 Canvas

HTML5的Canvas元素是一个强大的绘图元素,利用他可以绘制出你想要的形状,下面是几个简单的Canvas应用代码。functionDrawSj(){varmyCanvas1=document.getElementById("myCanvas");varaffiche=document.getElementById("affiche");vardraw=myCanvas1....

weixin_35775446的博客 739

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

HTML5 Canvas实现会跳舞的时间动画

【代码】HTML5 Canvas实现会跳舞的时间动画。

学习智者的博客 291

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

【强烈推荐】28个让你直呼哇塞的Canvas库

Canvas技术的诞生可谓是让绘图技术如虎添翼,本文将推荐一系列等方面的库,希望助你在Canvas绘图时寻得一把趁手的利器。同时,愣锤也将Canvas的相关资源进行的收录整理分类,更多的资源请关注,项目地址。目前该库持续维护中,已收录大约200+的Canvas库,以及等资源。

zhy810302的专栏 2970

Canvas:网页上的画布

想象力比知识更重要,因为知识是有限的,而想象力概括着世界的一切,推动着进步,并且是知识进化的源泉。

chaosweet的博客 2213

canvas入门

最近在做自己网站首页的的时候,总想加一些酷炫的效果展示在首页,顺便接触一点新东西,想来想去,最后还是学习了canvas,这里写个博客算是记录自己这几天的学习成果,方便以后遗忘时查看。 canvas是什么? 点击这里了解什么是canvas 餐前酒(分享一些运用了canvas的网站): http://i-remember.fr/en/ https://www.html5tricks.com/ 看了这些...

thankYou_2018的博客 371
上一篇: webpack适用场景及构建项目
下一篇: 网页特效之可变颜色的字体
海阳盼
博客等级 码龄11年 11粉丝 22原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值