aboutsummaryrefslogtreecommitdiffstats
path: root/root/blog/aspect_ratios/interactive/_base: text$moonscript -> table.moon
blob: 419eef059836e296867f0bd5fadd25509a08229e (plain)
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
import div from require 'mmm.dom'

if MODE ~= 'CLIENT'
  class Dummy
    render: =>
      div 'Interactive Example not available with Server-Side rendering', style:
        position: 'relative'
        resize: 'horizontal'
        overflow: 'hidden'

        width: '480px'
        height: '270px'
        'min-width': '270px'
        'max-width': '100%'

        margin: 'auto'
        padding: '10px'
        boxSizing: 'border-box'
        background: 'var(--gray-bright)'

  return {
    UIDemo: Dummy
    Example: Dummy
  }

import CanvasApp from require 'mmm.canvasapp'

class UIDemo extends CanvasApp
  width: nil
  height: nil
  new: () =>
    super!

    @canvas.width = nil
    @canvas.height = nil
    @canvas.style.width = '100%'
    @canvas.style.height = '100%'
    @canvas.style.border = '2px solid var(--gray-dark)'

    @node = div @canvas, style: {
      position: 'relative'
      resize: 'horizontal'
      overflow: 'hidden'

      width: '480px'
      height: '270px'
      minWidth: '270px'
      maxWidth: '100%'

      margin: 'auto'
      padding: '10px'
      boxSizing: 'border-box'
    }

  -- match size of current parent element and return it (for interactive resizing in the demo)
  updateSize: =>
    { :clientWidth, :clientHeight } = @canvas.parentElement
    @canvas.width, @canvas.height = clientWidth, clientHeight
    @canvas.width, @canvas.height

  -- set up a coordinate system such that the virtual viewport
  -- of size (w, h) is centered on (0,0) and fills the canvas
  -- returns remaining margins on the two axes
  fit: (w, h) =>
    width, height = @updateSize!
    @ctx\translate width/2, height/2

    -- maximum scale without cropping either axis
    scale = math.min (width/w), (height/h)
    @ctx\scale scale, scale

    -- calculate remaining space on x/y axis
    rx = (width/scale) - w
    ry = (height/scale) - h

    -- margins are half of the remaining space
    rx / 2, ry / 2

  strokeRect: (cx, cy, w, h) =>
    lw = @ctx.lineWidth / 2
    @ctx\strokeRect cx - w/2 + lw, cy - h/2 + lw,
                    w - 2*lw,      h - 2*lw,

class Box
  new: (@cx, @cy, @w, @h) =>

  rect: =>
    @cx, @cy, @w, @h

class Example extends UIDemo
  click: =>
    if @naive
      @naive = false
    else
      if @show_boxes
        @naive = true
      @show_boxes = not @show_boxes

  text: (box, text, align='center', my=.5) =>
    mx = .1
    @ctx.textAlign = align

    if align == 'left'
      @ctx\fillText text, box.cx + mx - box.w/2, box.cy + my
    else if align == 'center'
      @ctx\fillText text, box.cx,                box.cy + my
    if align == 'right'
      @ctx\fillText text, box.cx - mx + box.w/2, box.cy + my

{
  :UIDemo
  :Example
  :Box
}