• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com专业计算机教程网站
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • html/xhtml
  • html5
  • CSS
  • XML/XSLT
  • Dreamweaver教程
  • Frontpage教程
  • 心得技巧
  • bootstrap
  • vue
  • AngularJS
  • HBuilder教程
  • css3
  • 浏览器兼容
  • div/css
  • 网页编辑器
  • axure
您的位置:首页 > 网页设计 >html5 > HTML5 canvas实现画图程序(附代码)

HTML5 canvas实现画图程序(附代码)

作者:匿名 字体:[增加 减小] 来源:互联网 时间:2018-12-03

本文主要包含javascript,html5,canvas等相关知识,匿名希望在学习及工作中可以帮助到您
这篇文章给大家介绍的内容是关于HTML5 canvas实现画图程序(附代码),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

项目简介

整个项目分为两大部分

  1. 场景
    场景负责canvas控制,事件监听,动画处理

  2. 精灵
    精灵则指的是每一种可以绘制的canvas元素

Demo演示地址

项目特点

可扩展性强

sprite精灵实现

父类

class Element {
  constructor(options = {
    fillStyle: 'rgba(0,0,0,0)',
    lineWidth: 1,
    strokeStyle: 'rgba(0,0,0,255)'
  }) {
    this.options = options
  }
  setStyle(options){
    this.options =  Object.assign(this.options. options)
  }
}
  1. 属性:

  • options中存储了所有的绘图属性

    • fillStyle:设置或返回用于填充绘画的颜色、渐变或模式

    • strokeStyle:设置或返回用于笔触的颜色、渐变或模式

    • lineWidth:设置或返回当前的线条宽度

    • 使用的都是getContext("2d")对象的原生属性,此处只列出了这三种属性,需要的话还可以继续扩充。

  • 有需要可以继续扩充

  1. 方法:

  • setStyle方法用于重新设置当前精灵的属性

  • 有需要可以继续扩充

所有的精灵都继承Element类。

子类

子类就是每一种精灵元素的具体实现,这里我们介绍一遍Circle元素的实现

class Circle extends Element {
  // 定位点的坐标(这块就是圆心),半径,配置对象
  constructor(x, y, r = 0, options) {
    // 调用父类的构造函数
    super(options)
    this.x = x
    this.y = y
    this.r = r
  }
  // 改变元素大小
  resize(x, y) {
    this.r = Math.sqrt((this.x - x) ** 2 + (this.y - y) ** 2)
  }
  // 移动元素到新位置,接收两个参数,新的元素位置
  moveTo(x, y) {
    this.x = x
    this.y = y
  }
  // 判断点是否在元素中,接收两个参数,点的坐标
  choose(x, y) {
    return ((x - this.x) ** 2 + (y - this.y) ** 2) < (this.r ** 2)
  }
  // 偏移,计算点和元素定位点的相对偏移量(ofsetX, offsetY)
  getOffset(x, y) {
    return {
      x: x - this.x,
      y: y - this.y
    }
  }
  // 绘制元素实现,接收一个ctx对象,将当前元素绘制到指定画布上
  draw(ctx) {
    // 取到绘制所需属性
    let {
      fillStyle,
      strokeStyle,
      lineWidth
    } = this.options
    // 开始绘制beginPath() 方法开始一条路径,或重置当前的路径
    ctx.beginPath()
    // 设置属性
    ctx.fillStyle = fillStyle
    ctx.strokeStyle = strokeStyle
    ctx.lineWidth = lineWidth
    // 画圆
    ctx.arc(this.x, this.y, this.r, 0, 2 * Math.PI)
    // 填充颜色
    ctx.stroke()
    ctx.fill()
    // 绘制完成
  }
  // 验证函数,判断当前元素是否满足指定条件,此处用来检验是否将元素添加到场景中。
  validate() {
    return this.r >= 3
  }
}

arc() 方法创建弧/曲线(用于创建圆或部分圆)

  • x 圆的中心的 x 坐标。

  • y 圆的中心的 y 坐标。

  • r 圆的半径。

  • sAngle 起始角,以弧度计。(弧的圆形的三点钟位置是 0 度)。

  • eAngle 结束角,以弧度计。

  • counterclockwise 可选。规定应该逆时针还是顺时针绘图。False = 顺时针,true = 逆时针。

注意事项:

  • 构造函数的形参只有两个是必须的,就是定位点的坐标。

  • 其它的形参都必须有默认值。

所有方法的调用时机

  • 我们在画布上绘制元素的时候回调用resize方法。

  • 移动元素的时候调用moveTo方法。

  • choose会在鼠标按下时调用,判断当前元素是否被选中。

  • getOffset选中元素时调用,判断选中位置。

  • draw绘制函数,绘制元素到场景上时调用。

scene场景的实现

  1. 属性介绍

class Sence {
  constructor(id, options = {
    width: 600,
    height: 400
  }) {
    // 画布属性
    this.canvas = document.querySelector('#' + id)
    this.canvas.width = options.width
    this.canvas.height = options.height
    this.width = options.width
    this.height = options.height
    // 绘图的对象
    this.ctx = this.canvas.getContext('2d')
    // 离屏canvas
    this.outCanvas = document.createElement('canvas')
    this.outCanvas.width = this.width
    this.outCanvas.height = this.height
    this.outCtx = this.outCanvas.getContext('2d')
    // 画布状态
    this.stateList = {
      drawing: 'drawing',
      moving: 'moving'
    }
    this.state = this.stateList.drawing
    // 鼠标状态
    this.mouseState = {
    // 记录鼠标按下时的偏移量
      offsetX: 0,
      offsetY: 0,
      down: false, //记录鼠标当前状态是否按下
      target: null //当前操作的目标元素
    }
    // 当前选中的精灵构造器
    this.currentSpriteConstructor = null
    // 存储精灵
    let sprites = []
    this.sprites = sprites
    /* .... */
  }
}
  1. 事件逻辑

class Sence {
  constructor(id, options = {
    width: 600,
    height: 400
  }) {
  /* ... */
  // 监听事件
    this.canvas.addEventListener('contextmenu', (e) => {
      console.log(e)
    })
    // 鼠标按下时的处理逻辑
    this.canvas.addEventListener('mousedown', (e) => {
    // 只有左键按下时才会处理鼠标事件
      if (e.button === 0) {
      // 鼠标的位置
        let x = e.offsetX
        let y = e.offsetY
        // 记录鼠标是否按下
        this.mouseState.down = true
        // 创建一个临时target
        // 记录目标元素
        let target = null
        if (this.state === this.stateList.drawing) {
        // 判断当前有没有精灵构造器,有的话就构造一个对应的精灵元素
          if (this.currentSpriteConstructor) {
            target = new this.currentSpriteConstructor(x, y)
          }
        } else if (this.state === this.stateList.moving) {
          let sprites = this.sprites
          // 遍历所有的精灵,调用他们的choose方法,判断有没有被选中
          for (let i = sprites.length - 1; i >= 0; i--) {
            if (sprites[i].choose(x, y)) {
              target = sprites[i]
              break;
            }
          }
          
          // 如果选中的话就调用target的getOffset方法,获取偏移量
          if (target) {
            let offset = target.getOffset(x, y)
            this.mouseState.offsetX = offset.x
            this.mouseState.offsetY = offset.y
          }
        }
        // 存储当前目标元素
        this.mouseState.target = target
        // 在离屏canvas保存除目标元素外的所有元素
        let ctx = this.outCtx
        // 清空离屏canvas
        ctx.clearRect(0, 0, this.width, this.height)
        // 将目标元素外的所有的元素绘制到离屏canvas中
        this.sprites.forEach(item => {
          if (item !== target) {
            item.draw(ctx)
          }
        })
        if(target){
            // 开始动画
            this.anmite()
        }
      }
    })
    this.canvas.addEventListener('mousemove', (e) => {
    //  如果鼠标按下且有目标元素,才执行下面的代码
      if (this.mouseState.down && this.mouseState.target) {
        let x = e.offsetX
        let y = e.offsetY
        if (this.state === this.stateList.drawing) {
        // 调用当前target的resize方法,改变大小
          this.mouseState.target.resize(x, y)
        } else if (this.state === this.stateList.moving) {
        // 取到存储的偏移量
          let {
            offsetX, offsetY
          } = this.mouseState
          // 调用moveTo方法将target移动到新的位置
          this.mouseState.
  


 

您可能想查找下面的文章:

  • 用html5的canvas和JavaScript创建一个绘图程序的简单实例
  • Javascript 高级手势使用介绍
  • svg和css3实现环形渐变进度条的代码示例
  • 用exfe.js和canvas解决移动端 IOS 拍照上传图片翻转问题(附代码)
  • Canvas跨域的解决方案介绍
  • canvas实现图片涂鸦功能(附代码)
  • 用canvas实现简单的下雪效果(附代码)
  • HTML5中一些可以优化的细节介绍
  • HTML5 WebSQL四种基本操作的介绍
  • HTML5和原生app如何进行交互?

相关文章

  • 2018-12-03新增HTML5的八类INPUT输入
  • 2017-08-06html5基础教程常用技巧整理
  • 2018-12-03HTML5 Canvas实现交互式地铁线路图
  • 2017-08-06HTML5不支持标签和新增标签详解
  • 2018-12-03利用Canvas模仿百度贴吧客户端loading小球的方法
  • 2018-12-03移动端H5页面端怎样除去input输入框的默认样式
  • 2018-12-03David Lanham 新 iOS 遊戲 “Hatch” 的官網視頻中,最後小寵物從畫面跑進網頁的效果是如何實現的?
  • 2018-12-03HTML5存储方式小结
  • 2017-08-06用html5绘制折线图的实例代码
  • 2018-12-03看某前端设计书上说,在 base.css 里先定义一些基础样式然后在 html 里面加上相应的 class,这样是否和语义化相矛盾?

文章分类

  • html/xhtml
  • html5
  • CSS
  • XML/XSLT
  • Dreamweaver教程
  • Frontpage教程
  • 心得技巧
  • bootstrap
  • vue
  • AngularJS
  • HBuilder教程
  • css3
  • 浏览器兼容
  • div/css
  • 网页编辑器
  • axure

最近更新的内容

    • HTML5 对各个标签的定义与规定:meta
    • canvas游戏开发学习之八:组合
    • 拖放 API 实现拖放排序
    • 18个HTML5和JavaScript游戏引擎库
    • 详解HTML5头部meta标签的功能
    • html5 canvas实现简单的双缓冲
    • 网页中的电话号码如何实现一键直呼效果_附示例_html5教程技巧
    • H5响应式网站建设要注意的方面?
    • HTML5游戏开发开源库件lufylegend1.4.1发布
    • HTML5 canvas基本绘图之绘制线段

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有