| 1 |
global css body m:0 p:0 rd:lg bg:yellow1 of:hidden |
| 2 |
tag value-picker |
| 3 |
css w:100px h:40px pos:rel |
| 4 |
d:hgrid ji:center ai:center |
| 5 |
css .item h:100% pos:rel tween:styles 0.1s ease-out |
| 6 |
|
| 7 |
def update e |
| 8 |
data = options[e.x] |
| 9 |
|
| 10 |
<self @touch.stop.fit(0,options.length - 1,1)=update> |
| 11 |
for item in options |
| 12 |
<div.item[$value:{item}] .sel=(item==data)> |
| 13 |
|
| 14 |
tag stroke-picker < value-picker |
| 15 |
css .item bg:black w:calc($value*1px) h:40% rd:sm |
| 16 |
o:0.3 @hover:0.8 .sel:1 |
| 17 |
|
| 18 |
tag color-picker < value-picker |
| 19 |
css .item js:stretch rdt:lg bg:$value mx:2px scale-y.sel:1.5 |
| 20 |
|
| 21 |
tag app-canvas |
| 22 |
prop dpr = window.devicePixelRatio |
| 23 |
prop state = {} |
| 24 |
|
| 25 |
def draw e |
| 26 |
let path = e.#path ||= new Path2D |
| 27 |
let ctx = $canvas.getContext('2d') |
| 28 |
path.lineTo(e.x * dpr,e.y * dpr) |
| 29 |
ctx.lineWidth = state.stroke * dpr |
| 30 |
ctx.strokeStyle = state.color |
| 31 |
ctx.stroke(path) |
| 32 |
|
| 33 |
def resized e |
| 34 |
$canvas.width = offsetWidth * dpr |
| 35 |
$canvas.height = offsetHeight * dpr |
| 36 |
|
| 37 |
<self @resize=resized @touch.prevent.moved.fit(self)=draw> |
| 38 |
<canvas$canvas[pos:abs w:100% h:100%]> |
| 39 |
|
| 40 |
const strokes = [1,2,3,5,8,12] |
| 41 |
const colors = ['#F59E0B','#10B981','#3B82F6','#8B5CF6'] |
| 42 |
const state = {stroke: 5, color: '#3B82F6'} |
| 43 |
|
| 44 |
tag App |
| 45 |
<self> |
| 46 |
<div[ta:center pt:20 o:0.2 fs:xl]> 'draw here' |
| 47 |
<app-canvas[pos:abs inset:0] state=state> |
| 48 |
<div.tools[pos:abs b:0 w:100% d:hgrid ja:center]> |
| 49 |
<stroke-picker options=strokes bind=state.stroke> |
| 50 |
<color-picker options=colors bind=state.color> |
| 51 |
|
| 52 |
imba.mount <App[pos:abs inset:0]> |
| 53 |
|
| 54 |
# from https://imba.io |
| 55 |
# run online at https://scrimba.com/scrim/cPPdD4Aq |