#!/usr/bin/env python # coding: utf-8 # In[ ]: import param import panel as pn from panel.reactive import ReactiveHTML pn.extension() # In[ ]: class Canvas(ReactiveHTML): color = param.Color(default='#000000') line_width = param.Number(default=1, bounds=(0.1, 10)) uri = param.String() _template = """ """ _scripts = { 'render': """ state.ctx = canvas.getContext("2d") """, 'start': """ state.start = event state.ctx.beginPath() state.ctx.moveTo(state.start.offsetX, state.start.offsetY) """, 'draw': """ if (state.start == null) return state.ctx.lineTo(event.offsetX, event.offsetY) state.ctx.stroke() """, 'end': """ delete state.start """, 'clear': """ state.ctx.clearRect(0, 0, canvas.width, canvas.height); """, 'save': """ data.uri = canvas.toDataURL(); """, 'line_width': """ state.ctx.lineWidth = data.line_width; """, 'color': """ state.ctx.strokeStyle = data.color; """ } # ## Example # In[ ]: canvas = Canvas(width=400, height=400) # We create a separate HTML element which syncs with the uri parameter of the Canvas png_view = pn.pane.HTML() canvas.jslink(png_view, code={'uri': "target.text = ``"}) pn.Column( '# Drag on canvas to draw\n To export the drawing to a png click save.', pn.Row( canvas.controls(['color', 'line_width']), canvas, png_view ) )