# canvas

# cross origin

Read images of another domain and draw on the canvas.q

# Draw SVG

export class DrawSvgScript {
  /**
   * constructor.
   *
   * @param target
   * @param url
   */
  constructor(target, url) {
    this.target = target
    this.url = url
    this.img = new Image()

    return this
  }

  /**
   * init
   * load image
   */
  init() {
    const cb = () => this.onLoad()
    this.img.crossOrigin = 'Anonymous'
    this.img.addEventListener('load', cb, false)
    //
    this.img.src = this.url
  }

  /**
   * callback
   * create canvas
   */
  onLoad() {
    const canvas = document.createElement('canvas')
    const context = canvas.getContext('2d')

    canvas.width = this.target.offsetWidth // this.img.width
    canvas.height = this.target.offsetHeight // this.img.height

    // 100% * aTargetWidth / aWindowW
    const w = (this.target.offsetWidth * 300) / 800
    const h = (this.target.offsetWidth * 79) / 800
    const x = this.target.offsetWidth / 2 + w / -2
    const y = this.target.offsetHeight / 2 + h / -2

    context.drawImage(this.img, x, y, w, h)
    this.target.appendChild(canvas)
  }
}

export default DrawSvgScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

# Draw line

import { globalColor } from '@assets/js/core/color'
import math from '@/components/math'

export class DrawLine {
  private canvas: HTMLCanvasElement
  private ctx: CanvasRenderingContext2D | null

  /**
   * constructor.
   *
   * @param canvas
   */
  constructor(canvas: HTMLCanvasElement) {
    this.canvas = canvas
    this.ctx = canvas.getContext('2d')

    return this
  }

  /**
   * init
   * setting canvas
   */
  init() {
    const { width, height } = this.canvas.getBoundingClientRect()
    this.canvas.width = width
    this.canvas.height = height

    this.render()
  }

  /**
   * rendering
   */
  render() {
    this.drawLine(
      this.canvas.width / 2,
      this.canvas.height / 2,
      this.canvas.width / 2 + math.randomInt(50, 200),
      this.canvas.height / 2 + math.randomInt(50, 200),
      globalColor.sub[2],
    )
    this.drawLine(
      this.canvas.width / 2,
      this.canvas.height / 2,
      this.canvas.width / 2 + math.randomInt(50, 200),
      this.canvas.height / 2 + math.randomInt(50, 200),
      globalColor.primary,
    )
  }

  /**
   * drawing line
   * @param x1 - start X
   * @param y1 - start Y
   * @param x2 - end X
   * @param y2 - end Y
   * @param [color] - stroke color
   * @param [width=1] - stroke width
   */
  drawLine(
    x1: number,
    y1: number,
    x2: number,
    y2: number,
    color?: string,
    width = 1,
  ) {
    if (!this.ctx) return
    // set color
    if (color) this.ctx.strokeStyle = color
    // set line width
    this.ctx.lineWidth = width
    // begin path
    this.ctx.beginPath()
    // start path pos
    this.ctx.moveTo(x1, y1)
    // set points
    this.ctx.lineTo(x2, y2)
    // close path
    this.ctx.closePath()
    // drew stroke
    this.ctx.stroke()
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85

# Draw polygon

import { globalColor } from '@assets/js/core/color'
import math from '@/components/math'

export class DrawRect {
  private canvas: HTMLCanvasElement
  private ctx: CanvasRenderingContext2D | null
  private size: { w: number; h: number }

  /**
   * constructor.
   *
   * @param canvas
   */
  constructor(canvas: HTMLCanvasElement) {
    this.canvas = canvas
    this.ctx = canvas.getContext('2d')

    this.size = {
      w: 0,
      h: 0,
    }

    return this
  }

  /**
   * init
   * setting canvas
   */
  init() {
    const { width, height } = this.canvas.getBoundingClientRect()
    this.canvas.width = width
    this.canvas.height = height
    this.size.w = width
    this.size.h = height

    this.render()
  }

  /**
   * rendering
   */
  render() {
    // point count
    const count = math.randomInt(4, 8)
    // point positions
    const points = [] as number[]
    // create points
    for (let i = 0; i < count; ++i) {
      points.push(math.random(0, this.size.w), math.random(0, this.size.h))
    }
    // draw method
    this.drawPolygon(points, globalColor.sub[2])
  }

  /**
   * draw polygon
   * @param points {number[]} - points array
   * @param color {string} - polygon color
   */
  drawPolygon(points: number[], color?: string) {
    if (!this.ctx) return
    // has points
    if (Array.isArray(points) !== true || points.length < 4) return
    // set color
    if (color) this.ctx.fillStyle = color
    // begin path
    this.ctx.beginPath()
    // start path pos
    this.ctx.moveTo(points[0], points[1])
    // set points
    for (let i = 2; i < points.length; i += 2) {
      this.ctx.lineTo(points[i], points[i + 1])
    }
    // close path
    this.ctx.closePath()
    // drew stroke
    // this.ctx.stroke()
    // drew fill
    this.ctx.fill()
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82

# Draw Circle

ctx.arc(x, y, radius, startRadian, endRadian)

TIP

360 = Math.PI * 2

import { globalColor } from '@assets/js/core/color'
import math from '@/components/math'

export class DrawCircle {
  private canvas: HTMLCanvasElement
  private ctx: CanvasRenderingContext2D | null
  private size: { w: number; h: number }

  /**
   * constructor.
   *
   * @param canvas - canvas DOM
   */
  constructor(canvas: HTMLCanvasElement) {
    this.canvas = canvas
    this.ctx = canvas.getContext('2d')

    this.size = {
      w: 0,
      h: 0,
    }

    return this
  }

  /**
   * init
   * setting canvas
   */
  init() {
    const { width, height } = this.canvas.getBoundingClientRect()
    this.canvas.width = width
    this.canvas.height = height
    this.size.w = width
    this.size.h = height

    this.render()
  }

  /**
   * rendering
   */
  render() {
    const start = Math.PI * math.random(0, 2)
    const end = Math.PI * math.random(0, 2)

    this.drawCircle(
      this.size.w / 2,
      this.size.h / 2,
      this.size.w / 4,
      start,
      end,
      globalColor.sub[2],
    )
  }

  /**
   * draw circle
   * @param x - center position X
   * @param y - center position Y
   * @param radius - radius
   * @param startRadian - start position
   * @param endRadian - end position
   * @param [color] - color
   */
  drawCircle(
    x: number,
    y: number,
    radius: number,
    startRadian: number,
    endRadian: number,
    color: string,
  ) {
    if (!this.ctx) return
    // set color
    if (color) this.ctx.fillStyle = color
    // begin path
    this.ctx.beginPath()
    // set position
    this.ctx.moveTo(x, y)
    // create circle
    this.ctx.arc(x, y, radius, startRadian, endRadian)
    // close path
    this.ctx.closePath()
    // drew fill
    this.ctx.fill()
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88

# Draw Text

import { globalColor } from '@assets/js/core/color'

export class DrawText {
  private canvas: HTMLCanvasElement
  private ctx: CanvasRenderingContext2D | null
  private size: { w: number; h: number }

  /**
   * constructor.
   *
   * @param canvas
   */
  constructor(canvas: HTMLCanvasElement) {
    this.canvas = canvas
    this.ctx = canvas.getContext('2d')

    this.size = {
      w: 0,
      h: 0,
    }

    return this
  }

  /**
   * init
   * setting canvas
   */
  init() {
    const { width, height } = this.canvas.getBoundingClientRect()
    this.canvas.width = width
    this.canvas.height = height
    this.size.w = width
    this.size.h = height

    this.render()
  }

  /**
   * rendering
   */
  render() {
    // draw method
    this.drawText('laboobal', 60, globalColor.primary)
  }

  /**
   * draw text
   * @param text {string} - string to draw
   * @param fontSize {number} - font size
   * @param color {string} - text color
   */
  drawText(text, fontSize: number, color?: string) {
    if (!this.ctx) return
    // text font style
    // style size family
    this.ctx.font = `bold ${fontSize}px Helvetica Neue`
    // text baseline
    // "alphabetic" | "bottom" | "hanging" | "ideographic" | "middle" | "top"
    this.ctx.textBaseline = 'middle'
    // text align
    // "center" | "end" | "left" | "right" | "start"
    this.ctx.textAlign = 'center'
    // set color
    if (color) this.ctx.fillStyle = color
    // draw - center
    this.ctx.fillText(text, this.size.w / 2, (this.size.h - fontSize) / 2)
    // only stroke
    // this.ctx.strokeText(text, this.size.w / 2, (this.size.h - fontSize) / 2)
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71

# Draw Shadow

import { globalColor } from '@assets/js/core/color'
import math from '@/components/math'

export class DrawShadow {
  private canvas: HTMLCanvasElement
  private ctx: CanvasRenderingContext2D | null

  /**
   * constructor.
   *
   * @param canvas
   */
  constructor(canvas: HTMLCanvasElement) {
    this.canvas = canvas
    this.ctx = canvas.getContext('2d')

    return this
  }

  /**
   * init
   * setting canvas
   */
  init() {
    const { width, height } = this.canvas.getBoundingClientRect()
    this.canvas.width = width
    this.canvas.height = height

    this.render()
  }

  /**
   * rendering
   */
  render() {
    this.addShadow(8, '#000000', -15, 15)

    this.drawLine(
      this.canvas.width / 2,
      this.canvas.height / 2,
      this.canvas.width / 2 + math.randomInt(50, 200),
      this.canvas.height / 2 + math.randomInt(50, 200),
      globalColor.sub[2],
    )
    this.drawLine(
      this.canvas.width / 2,
      this.canvas.height / 2,
      this.canvas.width / 2 + math.randomInt(50, 200),
      this.canvas.height / 2 + math.randomInt(50, 200),
      globalColor.primary,
    )
  }

  /**
   * drawing line
   * @param x1 - start X
   * @param y1 - start Y
   * @param x2 - end X
   * @param y2 - end Y
   * @param [color] - stroke color
   * @param [width=1] - stroke width
   */
  drawLine(
    x1: number,
    y1: number,
    x2: number,
    y2: number,
    color?: string,
    width = 1,
  ) {
    if (!this.ctx) return
    // set color
    if (color) this.ctx.strokeStyle = color
    // set line width
    this.ctx.lineWidth = width
    // begin path
    this.ctx.beginPath()
    // start path pos
    this.ctx.moveTo(x1, y1)
    // set points
    this.ctx.lineTo(x2, y2)
    // close path
    this.ctx.closePath()
    // drew stroke
    this.ctx.stroke()
  }

  /**
   * add shadow (all contents)
   *
   * @param blur {number} blur
   * @param color {string} color
   * @param x {number} offset x
   * @param y {number} offset y
   */
  addShadow(blur: number, color: string, x: number, y: number) {
    if (!this.ctx) return

    // set shadow blue
    this.ctx.shadowBlur = blur
    // set shadow color
    this.ctx.shadowColor = color
    // set shadow offset
    this.ctx.shadowOffsetX = x
    this.ctx.shadowOffsetY = y
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107

# Draw Gradient

  1. create gradient -> createLinearGradient(x1, y1, x2, y2) or createRadialGradient(x1, y1, r1, x2, y2, r2))
  2. create color stops -> addColorStop(offset, 'color name) / offset 0~1
  3. draw rect -> fillRect(x, y, width, height)
import { globalColor } from '@assets/js/core/color'

export class DrawGradient {
  private canvas: HTMLCanvasElement
  private ctx: CanvasRenderingContext2D | null

  /**
   * constructor.
   *
   * @param canvas
   */
  constructor(canvas: HTMLCanvasElement) {
    this.canvas = canvas
    this.ctx = canvas.getContext('2d')

    return this
  }

  /**
   * init
   * setting canvas
   */
  init() {
    const { width, height } = this.canvas.getBoundingClientRect()
    this.canvas.width = width
    this.canvas.height = height

    this.render()
  }

  /**
   * rendering
   */
  render() {
    if (!this.ctx) return

    // create linearGradient area
    const linearGradient = this.ctx.createLinearGradient(
      0,
      0,
      (this.canvas.width / 4) * 2,
      (this.canvas.width / 4) * 2,
    )
    // set color stops
    globalColor.gradient.sky.forEach((color, index, arr) => {
      // offset 0 ~ 1
      const offset = (index + 1) / arr.length
      linearGradient.addColorStop(offset, color)
    })

    // draw rect
    this.drawRect(
      0,
      0,
      this.canvas.width / 4,
      this.canvas.width / 4,
      linearGradient,
    )
    this.drawRect(
      this.canvas.width / 4,
      this.canvas.width / 4,
      this.canvas.width / 4,
      this.canvas.width / 4,
      linearGradient,
    )

    // create radial gradient area
    const radialGradient = this.ctx.createRadialGradient(
      (this.canvas.width / 4) * 3,
      this.canvas.width / 4,
      0,
      (this.canvas.width / 4) * 3,
      this.canvas.width / 4,
      this.canvas.width / 4,
    )

    // set color stops
    globalColor.gradient.scene.forEach((color, index, arr) => {
      // offset 0 ~ 1
      const offset = (index + 1) / arr.length
      radialGradient.addColorStop(offset, color)
    })

    // draw rect
    this.drawRect(
      (this.canvas.width / 4) * 2,
      0,
      this.canvas.width / 4,
      this.canvas.width / 4,
      radialGradient,
    )
    this.drawRect(
      (this.canvas.width / 4) * 3,
      this.canvas.width / 4,
      this.canvas.width / 4,
      this.canvas.width / 4,
      radialGradient,
    )
  }

  /**
   * draw polygon
   * @param x {number}
   * @param y {number}
   * @param width {number}
   * @param height {number}
   * @param color {CanvasGradient}
   */
  drawRect(
    x: number,
    y: number,
    width: number,
    height: number,
    color: CanvasGradient,
  ) {
    if (!this.ctx) return

    this.ctx.fillStyle = color
    this.ctx.fillRect(x, y, width, height)
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121

# Alpha Blending / CompositeOperation

import { globalColor } from '@assets/js/core/color'
import math from '@/components/math'

export class AlphaBlending {
  private canvas: HTMLCanvasElement
  private ctx: CanvasRenderingContext2D | null

  /**
   * constructor.
   *
   * @param canvas
   */
  constructor(canvas: HTMLCanvasElement) {
    this.canvas = canvas
    this.ctx = canvas.getContext('2d')

    return this
  }

  /**
   * init
   * setting canvas
   */
  init() {
    const { width, height } = this.canvas.getBoundingClientRect()
    this.canvas.width = width
    this.canvas.height = height

    this.render()
  }

  /**
   * rendering
   */
  render(blend = 'source-over') {
    if (!this.ctx) return

    // reset alpha
    this.ctx.globalAlpha = 1.0
    // reset canvas
    this.drawRect(0, 0, this.canvas.width, this.canvas.height, '#ffffff')

    // set CompositeOperation (blend mode)
    this.ctx.globalCompositeOperation = blend
    // set alpha
    this.ctx.globalAlpha = 0.5

    for (let i = 50; i > 0; i--) {
      this.drawLine(
        math.randomInt(0, this.canvas.width),
        math.randomInt(0, this.canvas.height),
        math.randomInt(0, this.canvas.width),
        math.randomInt(0, this.canvas.height),
        globalColor.sub[2],
        math.randomInt(0, 15),
      )
      this.drawLine(
        math.randomInt(0, this.canvas.width),
        math.randomInt(0, this.canvas.height),
        math.randomInt(0, this.canvas.width),
        math.randomInt(0, this.canvas.height),
        globalColor.primary,
        math.randomInt(0, 5),
      )
    }
  }

  /**
   * drawing line
   * @param x1 - start X
   * @param y1 - start Y
   * @param x2 - end X
   * @param y2 - end Y
   * @param [color] - stroke color
   * @param [width=1] - stroke width
   */
  drawLine(
    x1: number,
    y1: number,
    x2: number,
    y2: number,
    color?: string,
    width = 1,
  ) {
    if (!this.ctx) return
    // set color
    if (color) this.ctx.strokeStyle = color
    // set line width
    this.ctx.lineWidth = width
    // begin path
    this.ctx.beginPath()
    // start path pos
    this.ctx.moveTo(x1, y1)
    // set points
    this.ctx.lineTo(x2, y2)
    // close path
    this.ctx.closePath()
    // draw stroke
    this.ctx.stroke()
  }

  /**
   * 矩形を描画する
   * @param  x {number}
   * @param  y {number}
   * @param  width {number}
   * @param  height {number}
   * @param  color {string}
   */
  drawRect(
    x: number,
    y: number,
    width: number,
    height: number,
    color = '#ffffff',
  ) {
    if (!this.ctx) return

    this.ctx.fillStyle = color

    this.ctx.fillRect(x, y, width, height)
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
Last Updated: 1/31/2021, 1:02:43 PM