Create a coloring book in canvas: Developed an app that you can create and enjoy your own original coloring from an image.

Hey guys,

I developed an app that you can create and enjoy your own original coloring book from an image.

Look this!

You can also play coloring in this app.

The part about turning the image into a coloring book is almost the same as this artic…


This content originally appeared on DEV Community and was authored by Yuiko Ito

Hey guys,

I developed an app that you can create and enjoy your own original coloring book from an image.

Look this!

Angry

You can also play coloring in this app.

Image from Gyazo

The part about turning the image into a coloring book is almost the same as this article I wrote before.

So, in this article, I will explain how to develop this coloring functions using canvas.

DEMO→https://nurie-maker.com/
github→https://github.com/yuikoito/nurie-creator

※I'm using Nuxt.js here. Please replace it as necessary.

Draw a background image on the canvas

First, we need to prepare a canvas element and draw a background image on the canvas.

It takes a little time to draw the background image on the canvas, and I want to make sure to emit loading during that time.
Therefore, I wait here for the image to be fully loaded in Promise.

<script>
export default {
  async asyncData({ params }) {
    return {
      url: `${process.env.BASE_URL}/nurie/${params.id}`,
      image: `${process.env.AWS_IMAGE_URL}/nurie/${params.id}.jpg`,
      twitterImage: `${process.env.AWS_IMAGE_URL}/nurie/${params.id}.jpg`,
    }
  },
  data() {
    return {
      canvas: null,
      ctx: null,
      noPicture: require('@/assets/img/noPic.png'),
      overlay: true,
    }
  },
  mounted() {
    this.init()
  },
  methods: {
    async init() {
      this.canvas = this.$refs.canvas
      this.ctx = this.canvas.getContext('2d')
      const wrapper = this.$refs.wrapper
      await this.loadImage(this.image).then((res) => {
        const scale = wrapper.clientWidth / res.naturalWidth
        this.canvas.width = res.naturalWidth * scale
        this.canvas.height = res.naturalHeight * scale
        this.ctx.drawImage(res, 0, 0, this.canvas.width, this.canvas.height)
      })
      this.overlay = false
    },
    loadImage(src) {
      return new Promise((resolve) => {
        const img = new Image()
        img.src = src
        img.onload = () => resolve(img)
        img.onerror = () => {
          img.src = this.noPicture
        }
      })
    },
  }
}
</script>

Now we can draw an image on canvas.

Use Retina Canvas Support

If you look at the image drawn above, you will see that the resolution is a little rough, so we will fix that part.

Specifically, when loading an image in canvas, load it at twice the size and set the canvas style to 1/2. The actual canvas drawing size will be the same as above, but the resolution will be finer and the image will be drawn beautifully.

      await this.loadImage(this.image).then((res) => {
        this.ctx.scale(2, 2)
        const scale = wrapper.clientWidth / res.naturalWidth
        this.canvas.width = res.naturalWidth * scale * 2
        this.canvas.height = res.naturalHeight * scale * 2
        this.canvas.style.width = this.canvas.width / 2 + 'px'
        this.canvas.style.height = this.canvas.height / 2 + 'px'
        this.ctx.drawImage(res, 0, 0, this.canvas.width, this.canvas.height)
      })

Implement a drawing function.

When a user clicks on the screen, the event can be detected by mousedown on a PC, mousemove for dragging, and mouseup (or mouseout) for the timing when the dragging is finished.

<canvas
  ref="canvas"
  @mousedown.prevent="dragStart"
  @mouseup.prevent="dragEnd"
  @mouseout.prevent="dragEnd"
  @mousemove.prevent="draw"
>
</canvas>

※The lineWidth and currentColor can be changed by the user.

    dragStart() {
      this.ctx.beginPath()
      this.isDrag = true
    },
    draw(e) {
      const x = (e.clientX - this.canvas.getBoundingClientRect().left) * 2
      const y = (e.clientY - this.canvas.getBoundingClientRect().top) * 2
      if (!this.isDrag) {
        return
      }
      this.ctx.lineCap = 'round'
      this.ctx.lineJoin = 'round'
      this.ctx.lineWidth = this.lineWidth
      this.ctx.strokeStyle = this.currentColor
      if (this.lastPosition.x === null || this.lastPosition.y === null) {
        this.ctx.moveTo(x, y)
      } else {
        this.ctx.moveTo(this.lastPosition.x, this.lastPosition.y)
      }
      this.ctx.lineTo(x, y)
      this.ctx.stroke()
      this.lastPosition.x = x
      this.lastPosition.y = y
    },
    dragEnd() {
      this.ctx.closePath()
      this.isDrag = false
      this.lastPosition.x = null
      this.lastPosition.y = null
      this.isErase = false
    },

Change color of the line

I used vue-color to change color.

yarn add vue-color

Create vueColor.js under plugins.
In this case, we are using a design called Sketch, so we are only loading Sketch.

import Vue from 'vue'
import { Sketch } from 'vue-color'

Vue.component('Sketch', Sketch)

Add in nuxt.config.js.

  plugins: [{ src: '@/plugins/vueColor.js', mode: 'client' }],

Then draw this component in the page.
The drawing is fine as it is, but you will get a warning, so move it inside <client-only>.

  <client-only>
    <Sketch :value="colors" @input="updateValue"></Sketch>
  </client-only>

Set a default value for colors.
When a user change color, you will get the color by the following function.

    updateValue(e) {
      this.currentColor = e.hex
    },

This library is easy and useful!

Download the canvas

Then, we will implement a function to download the canvas when the button is clicked.

    download() {
      let link = document.createElement('a')
      link.href = this.canvas.toDataURL('image/jpeg')
      link.download = 'nurie-' + new Date().getTime() + '.jpg'
      link.click()
    },

... However, we can't download canvas at this point.

Execution of toDataURL fails due to CORS.

In fact, this time, for the background image of canvas, I was referring to the URL stored in s3 from uuid, so the error occurred due to CORS in that part.

image: `${process.env.AWS_IMAGE_URL}/nurie/${params.id}.jpg`

Since the image is loaded as shown above, the domain of the current URL and the domain of the image URL are different, causing the following error.

tainted canvases may not be exported

Then I used @nuxtjs/proxy to fix this problem.

yarn add @nuxtjs/proxy

Add nuxt.config.js.

  modules: ['@nuxtjs/dotenv', '@nuxtjs/proxy'],
  proxy: {
    '/nurie/': {
      target: AWS_IMAGE_URL,
      changeOrigin: true,
      secure: false,
    },
  },

Now, you can replace ${process.env.AWS_IMAGE_URL}/nurie/${params.id}.jpg with the URL of your site.
Change the image part to the following.

image: `${process.env.BASE_URL}/nurie/${params.id}.jpg`,

Enable to play coloring on the phone

As it is, we can't do coloring on the phone, so we will also add events for the phone.
On the phone, you can detect events with touchstart, touchmove, and touchend.

<canvas
  ref="canvas"
  @mousedown.prevent="dragStart"
  @touchstart.prevent="dragStart"
  @touchend.prevent="dragEnd"
  @mouseup.prevent="dragEnd"
  @mouseout.prevent="dragEnd"
  @mousemove.prevent="draw"
  @touchmove.prevent="spDraw"
>
</canvas>

The events that can be detected on a smartphone differ from those on a PC only for the part where the line is drawn, so adjust the following.
The point is that on a PC you can get the location of the touch by e.clientX, etc., but on a smartphone it is e.changedTouches[0].clientX. (In the case of a single finger)

    spDraw(e) {
      if (e.changedTouches.length == 1) {
        this.draw(e.changedTouches[0])
      }
    },

Finish!

That's it!

Thanks for reading.
I am very happy if you enjoy it!

??????

Please send me a message if you need.

yuiko.dev@gmail.com
https://twitter.com/yui_active

??????


This content originally appeared on DEV Community and was authored by Yuiko Ito


Print Share Comment Cite Upload Translate Updates
APA

Yuiko Ito | Sciencx (2021-08-23T18:26:30+00:00) Create a coloring book in canvas: Developed an app that you can create and enjoy your own original coloring from an image.. Retrieved from https://www.scien.cx/2021/08/23/create-a-coloring-book-in-canvas-developed-an-app-that-you-can-create-and-enjoy-your-own-original-coloring-from-an-image/

MLA
" » Create a coloring book in canvas: Developed an app that you can create and enjoy your own original coloring from an image.." Yuiko Ito | Sciencx - Monday August 23, 2021, https://www.scien.cx/2021/08/23/create-a-coloring-book-in-canvas-developed-an-app-that-you-can-create-and-enjoy-your-own-original-coloring-from-an-image/
HARVARD
Yuiko Ito | Sciencx Monday August 23, 2021 » Create a coloring book in canvas: Developed an app that you can create and enjoy your own original coloring from an image.., viewed ,<https://www.scien.cx/2021/08/23/create-a-coloring-book-in-canvas-developed-an-app-that-you-can-create-and-enjoy-your-own-original-coloring-from-an-image/>
VANCOUVER
Yuiko Ito | Sciencx - » Create a coloring book in canvas: Developed an app that you can create and enjoy your own original coloring from an image.. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2021/08/23/create-a-coloring-book-in-canvas-developed-an-app-that-you-can-create-and-enjoy-your-own-original-coloring-from-an-image/
CHICAGO
" » Create a coloring book in canvas: Developed an app that you can create and enjoy your own original coloring from an image.." Yuiko Ito | Sciencx - Accessed . https://www.scien.cx/2021/08/23/create-a-coloring-book-in-canvas-developed-an-app-that-you-can-create-and-enjoy-your-own-original-coloring-from-an-image/
IEEE
" » Create a coloring book in canvas: Developed an app that you can create and enjoy your own original coloring from an image.." Yuiko Ito | Sciencx [Online]. Available: https://www.scien.cx/2021/08/23/create-a-coloring-book-in-canvas-developed-an-app-that-you-can-create-and-enjoy-your-own-original-coloring-from-an-image/. [Accessed: ]
rf:citation
» Create a coloring book in canvas: Developed an app that you can create and enjoy your own original coloring from an image. | Yuiko Ito | Sciencx | https://www.scien.cx/2021/08/23/create-a-coloring-book-in-canvas-developed-an-app-that-you-can-create-and-enjoy-your-own-original-coloring-from-an-image/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.