JSON based painter based on SDL2 and Cario.
requires "https://github.com/Quamolit/json-paint.nim#v0.1.0"
import json_paint
initCanvas("title", 400, 400)
# it also takes an optional RgbaColor as background
renderCanvas({
"type": "group",
"children": [] # see specs for currently supported shapes
})
takeCanvasEvents(proc(event: JsonNode) =
if event.kind == JObject:
if event["type"].getStr == "quit":
quit 0
echo "event: ", event
)
hslToRgb(0,0,10,1)
Try in dev:
nimble t
Find example in tests/demo.nim
.
JSON described in CoffeeScript.
This library uses HSL/HSLA colors:
[360,100,100]
[360,100,100,1]
- Group
type: 'group'
position: [1, 1],
children: []
- Text
type: 'text'
text: 'DEMO'
position: [1, 1]
'font-size': 14
'font-face': 'Arial'
'font-weight': 'normal',
color: Color
align: "center" # 'left' | 'center' | 'right'
- Arc
type: 'arc'
position: [1, 1]
radius: 1
'from-angle': 0
'to-angle': 2*PI # 0 ~ 2*PI
'negative?': false
'stroke-color': Color
'line-width': 1
'fill-color': Color
- Operations
type: 'ops'
position: [1, 1]
ops: [
['stroke'],
['fill'],
['stroke-preserve'],
['fill-preserve'],
['line-width', 1],
['source-rgb', Color], # which is actually using HSL colors
['hsl', Color], # alias for 'source-rgb'
['move-to', [1, 1]],
['line-to', [1, 1]],
['relative-line-to', [1, 1]],
['curve-to', [1, 2], [3, 4], [5, 6]],
['relative-curve-to', [1, 2], [3, 4], [5, 6]],
['arc', [1, 2], 1, [0, 6.28], false],
['new-path'],
['close-path'],
]
- Polyline
type: 'polyline'
position: [1, 1]
stops: [
[2, 2], [3, 3], [4, 4]
]
'stroke-color': Color
'line-width': 1
'line-join': 'round' # 'round' | 'milter' | 'bevel'
'fill-color': Color
'skip-first?': false
- Touch Area
type: 'touch-area'
path: ["a", 1] # JSON
action: Action # JSON
data: Data # JSON
position: [1, 1]
radius: 20
'fill-color': Color
'stroke-color': Color
'line-width': 1
'rect?': true # enabled rect mode
dx: 24 # half of rect width
dy: 8 # half of rect height
- Key Listener
type: 'key-listener'
path: ['a', 2] # JSON
action: Action # JSON
data: Data # JSON
key: 'a'
type: 'mouse-move'
x: 1
y: 1
path: [] # data, defined in "touch-area"
action: Action # data, defined in "touch-area"
data: Data # data, defined in "touch-area"
type: 'key-down'
sym: 97
repeat: false
scancode: "SDL_SCANCODE_D"
name: 'a'
type: 'key-up'
sym: 97
repeat: false
scancode: "SDL_SCANCODE_D"
name: 'a'
type: 'text-input',
text: 'a'
type: 'quit'
type: 'mouse-down'
clicks: 1
path: [] # data, defined in "touch-area"
action: Action # data, defined in "touch-area"
data: Data # data, defined in "touch-area"
x: 100
y: 100
type: 'mouse-up'
clicks: 1
path: [] # data, defined in "touch-area"
action: Action # data, defined in "touch-area"
data: Data # data, defined in "touch-area"
x: 100
y: 100
type: 'window'
event: "WindowEvent_FocusGained"
type: 'window-resized'
x: 100
y: 100
Example logs:
// normal moves
{"type":"mouse-move","x":430,"y":162}
{"type":"mouse-move","x":377,"y":120}
// a normal click
{"type":"mouse-down","clicks":1,"x":377,"y":120}
{"type":"mouse-up","clicks":1,"x":377,"y":120}
{"type":"mouse-move","x":385,"y":128}
{"type":"mouse-move","x":388,"y":134}
// a normal drag
{"type":"mouse-down","clicks":1,"x":388,"y":134}
{"type":"mouse-move","x":407,"y":155}
{"type":"mouse-move","x":408,"y":156}
{"type":"mouse-move","x":415,"y":165}
{"type":"mouse-move","x":416,"y":165}
{"type":"mouse-move","x":416,"y":166}
{"type":"mouse-up","clicks":0,"x":416,"y":166}
{"type":"mouse-move","x":406,"y":164}
{"type":"mouse-move","x":291,"y":102}
// move from touch-area
{"type":"mouse-down","clicks":1,"path":["a",1],"action":":demo","data":null,"x":291,"y":102}
{"type":"mouse-move","x":293,"y":105,"dx":2.0,"dy":3.0,"path":["a",1],"action":":demo","data":null}
{"type":"mouse-move","x":318,"y":135,"dx":27.0,"dy":33.0,"path":["a",1],"action":":demo","data":null}
{"type":"mouse-move","x":323,"y":142,"dx":32.0,"dy":40.0,"path":["a",1],"action":":demo","data":null}
{"type":"mouse-move","x":326,"y":150,"dx":35.0,"dy":48.0,"path":["a",1],"action":":demo","data":null}
{"type":"mouse-move","x":327,"y":150,"dx":36.0,"dy":48.0,"path":["a",1],"action":":demo","data":null}
{"type":"mouse-move","x":327,"y":151,"dx":36.0,"dy":49.0,"path":["a",1],"action":":demo","data":null}
{"type":"mouse-up","clicks":0,"path":["a",1],"action":":demo","data":null,"x":327,"y":151,"dx":36.0,"dy":49.0}
{"type":"mouse-move","x":311,"y":132}
{"type":"mouse-move","x":310,"y":132}
{"type":"mouse-move","x":308,"y":129}
{"type":"mouse-move","x":307,"y":129}
{"type":"mouse-move","x":303,"y":120}
// click in touch-area
{"type":"mouse-down","clicks":1,"path":["a",1],"action":":demo","data":null,"x":303,"y":120}
{"type":"mouse-up","clicks":1,"path":["a",1],"action":":demo","data":null,"x":303,"y":120,"dx":0.0,"dy":0.0}
// keyboard events
event: {"type":"key-down","sym":100,"repeat":false,"scancode":"SDL_SCANCODE_D","name":"d"}
event: {"type":"text-input","text":"d"}
event: {"type":"key-up","sym":100,"repeat":false,"scancode":"SDL_SCANCODE_D","name":"d"}
// keydown with actions
event: {"type":"key-down","sym":97,"repeat":false,"scancode":"SDL_SCANCODE_A","name":"a","path":["a",1],"action":":hit-key","data":"demo data"}
event: {"type":"text-input","text":"a"}
event: {"type":"key-up","sym":97,"repeat":false,"scancode":"SDL_SCANCODE_A","name":"a","path":["a",1],"action":":hit-key","data":"demo data"}
MIT