search
HomeWeb Front-endH5 TutorialHTML5 canvas implements drawing program (with code)

HTML5 canvas implements drawing program (with code)

Aug 01, 2018 pm 01:49 PM
canvashtml5javascript

This article introduces to you the HTML5 canvas implementation drawing program (with code). It has certain reference value. Friends in need can refer to it. I hope it will be helpful to you.

Project Introduction

The entire project is divided into two parts

  1. Scenario
    The scenario is responsible for canvas control and event monitoring , Animation processing

  2. Elf
    Elf refers to every canvas element that can be drawn

Demo demo address

Project features

Strong scalability

sprite wizard implementation

Parent class

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. Attributes:

  • options store all drawing properties

    • fillStyle: Sets or returns the color, gradient, or pattern used to fill the painting

    • strokeStyle: Sets or returns the color, gradient, or pattern used to fill the painting Color, gradient or pattern

    • lineWidth: Set or return the current line width

    • all use the getContext("2d") object Of the native attributes, only these three attributes are listed here, and they can be expanded if necessary.

  • Can continue to expand if necessary

  1. Method:

  • The setStyle method is used to reset the properties of the current sprite

  • You can continue to expand if necessary

All sprites All inherit from the Element class.

Subclass

Subclass is the specific implementation of each elf element. Here we introduce the implementation of Circle element

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) = 3
  }
}

arc() Methods to create arcs/curves (used to create circles or partial circles)

  • x x coordinate of the center of the circle.

  • y y coordinate of the center of the circle.

  • r The radius of the circle.

  • sAngle Starting angle, in radians. (The three o'clock position of the arc's circle is 0 degrees).

  • eAngle End angle, measured in radians.

  • counterclockwise Optional. Specifies whether the plot should be drawn counterclockwise or clockwise. False = clockwise, true = counterclockwise.

Note:

  • Only two formal parameters of the constructor are required, which are the coordinates of the anchor point.

  • Other formal parameters must have default values.

The timing of calling all methods

  • We call the resize method when drawing elements on the canvas.

  • Call the moveTo method when moving an element.

  • choose will be called when the mouse is pressed to determine whether the current element is selected.

  • getOffset is called when an element is selected to determine the selected position.

  • draw drawing function, called when drawing elements onto the scene.

scene scene implementation

  1. Attribute introduction

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. Event logic

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.target.moveTo(x - offsetX, y - offsetY)
        }
      }
    })
    document.body.addEventListener('mouseup', (e) => {
      if (this.mouseState.down) {
      // 将鼠标按下状态记录为false
        this.mouseState.down = false
        if (this.state === this.stateList.drawing) {
        // 调用target的validate方法。判断他要不要被加到场景去呢
          if (this.mouseState.target.validate()) {
            this.sprites.push(this.mouseState.target)
          }
        } else if (this.state === this.stateList.moving) {
          // 什么都不做
        }
      }
    })
  }
}
  1. Method introduction

class Sence {
// 动画
  anmite() {
    requestAnimationFrame(() => {
      // 清除画布
      this.clear()
      // 将离屏canvas绘制到当前canvas上
      this.paint(this.outCanvas)
      // 绘制target
      this.mouseState.target.draw(this.ctx)
      // 鼠标是按下状态就继续执行下一帧动画
      if (this.mouseState.down) {
        this.anmite()
      }
    })
  }
  // 可以将手动的创建的精灵添加到画布中
  append(sprite) {
    this.sprites.push(sprite)
    sprite.draw(this.ctx)
  }
  // 根据ID值,从场景中删除对应元素
  remove(id) {
    this.sprites.splice(id, 1)
  }
  // clearRect清除指定区域的画布内容
  clear() {
    this.ctx.clearRect(0, 0, this.width, this.height)
  }
  // 重绘整个画布的内容
  reset() {
    this.clear()
    this.sprites.forEach(element => {
      element.draw(this.ctx)
    })
  }
  // 将离屏canvas绘制到页面的canvas画布上
  paint(canvas, x = 0, y = 0) {
    this.ctx.drawImage(canvas, x, y, this.width, this.height)
  }
  // 设置当前选中的精灵构造器
  setCurrentSprite(Element) {
    this.currentSpriteConstructor = Element
  }

Recommended related articles:

How canvas implements the code for QR code and image synthesis

HTML5 Canvas implements interactive subway line map

The above is the detailed content of HTML5 canvas implements drawing program (with code). For more information, please follow other related articles on the PHP Chinese website!

Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
H5: Key Improvements in HTML5H5: Key Improvements in HTML5Apr 28, 2025 am 12:26 AM

HTML5 brings five key improvements: 1. Semantic tags improve code clarity and SEO effects; 2. Multimedia support simplifies video and audio embedding; 3. Form enhancement simplifies verification; 4. Offline and local storage improves user experience; 5. Canvas and graphics functions enhance the visualization of web pages.

HTML5: The Standard and its Impact on Web DevelopmentHTML5: The Standard and its Impact on Web DevelopmentApr 27, 2025 am 12:12 AM

The core features of HTML5 include semantic tags, multimedia support, offline storage and local storage, and form enhancement. 1. Semantic tags such as, etc. to improve code readability and SEO effect. 2. Simplify multimedia embedding with labels. 3. Offline storage and local storage such as ApplicationCache and LocalStorage support network-free operation and data storage. 4. Form enhancement introduces new input types and verification properties to simplify processing and verification.

H5 Code Examples: Practical Applications and TutorialsH5 Code Examples: Practical Applications and TutorialsApr 25, 2025 am 12:10 AM

H5 provides a variety of new features and functions, greatly enhancing the capabilities of front-end development. 1. Multimedia support: embed media through and elements, no plug-ins are required. 2. Canvas: Use elements to dynamically render 2D graphics and animations. 3. Local storage: implement persistent data storage through localStorage and sessionStorage to improve user experience.

The Connection Between H5 and HTML5: Similarities and DifferencesThe Connection Between H5 and HTML5: Similarities and DifferencesApr 24, 2025 am 12:01 AM

H5 and HTML5 are different concepts: HTML5 is a version of HTML, containing new elements and APIs; H5 is a mobile application development framework based on HTML5. HTML5 parses and renders code through the browser, while H5 applications need to run containers and interact with native code through JavaScript.

The Building Blocks of H5 Code: Key Elements and Their PurposeThe Building Blocks of H5 Code: Key Elements and Their PurposeApr 23, 2025 am 12:09 AM

Key elements of HTML5 include,,,,,, etc., which are used to build modern web pages. 1. Define the head content, 2. Used to navigate the link, 3. Represent the content of independent articles, 4. Organize the page content, 5. Display the sidebar content, 6. Define the footer, these elements enhance the structure and functionality of the web page.

HTML5 and H5: Understanding the Common UsageHTML5 and H5: Understanding the Common UsageApr 22, 2025 am 12:01 AM

There is no difference between HTML5 and H5, which is the abbreviation of HTML5. 1.HTML5 is the fifth version of HTML, which enhances the multimedia and interactive functions of web pages. 2.H5 is often used to refer to HTML5-based mobile web pages or applications, and is suitable for various mobile devices.

HTML5: The Building Blocks of the Modern Web (H5)HTML5: The Building Blocks of the Modern Web (H5)Apr 21, 2025 am 12:05 AM

HTML5 is the latest version of the Hypertext Markup Language, standardized by W3C. HTML5 introduces new semantic tags, multimedia support and form enhancements, improving web structure, user experience and SEO effects. HTML5 introduces new semantic tags, such as, ,, etc., to make the web page structure clearer and the SEO effect better. HTML5 supports multimedia elements and no third-party plug-ins are required, improving user experience and loading speed. HTML5 enhances form functions and introduces new input types such as, etc., which improves user experience and form verification efficiency.

H5 Code: Writing Clean and Efficient HTML5H5 Code: Writing Clean and Efficient HTML5Apr 20, 2025 am 12:06 AM

How to write clean and efficient HTML5 code? The answer is to avoid common mistakes by semanticizing tags, structured code, performance optimization and avoiding common mistakes. 1. Use semantic tags such as, etc. to improve code readability and SEO effect. 2. Keep the code structured and readable, using appropriate indentation and comments. 3. Optimize performance by reducing unnecessary tags, using CDN and compressing code. 4. Avoid common mistakes, such as the tag not closed, and ensure the validity of the code.

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser is a secure browser environment for taking online exams securely. This software turns any computer into a secure workstation. It controls access to any utility and prevents students from using unauthorized resources.

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

mPDF

mPDF

mPDF is a PHP library that can generate PDF files from UTF-8 encoded HTML. The original author, Ian Back, wrote mPDF to output PDF files "on the fly" from his website and handle different languages. It is slower than original scripts like HTML2FPDF and produces larger files when using Unicode fonts, but supports CSS styles etc. and has a lot of enhancements. Supports almost all languages, including RTL (Arabic and Hebrew) and CJK (Chinese, Japanese and Korean). Supports nested block-level elements (such as P, DIV),

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Atom editor mac version download

Atom editor mac version download

The most popular open source editor