{ "cells": [ { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import param\n", "import panel as pn\n", "\n", "from panel.reactive import ReactiveHTML\n", "\n", "pn.extension()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "class Canvas(ReactiveHTML):\n", " \n", " color = param.Color(default='#000000')\n", " \n", " line_width = param.Number(default=1, bounds=(0.1, 10))\n", " \n", " uri = param.String()\n", "\n", " _template = \"\"\"\n", " \n", " \n", " \n", " \n", " \"\"\"\n", " \n", " _scripts = {\n", " 'render': \"\"\"\n", " state.ctx = canvas.getContext(\"2d\")\n", " \"\"\",\n", " 'start': \"\"\"\n", " state.start = event\n", " state.ctx.beginPath()\n", " state.ctx.moveTo(state.start.offsetX, state.start.offsetY)\n", " \"\"\",\n", " 'draw': \"\"\"\n", " if (state.start == null)\n", " return\n", " state.ctx.lineTo(event.offsetX, event.offsetY)\n", " state.ctx.stroke()\n", " \"\"\",\n", " 'end': \"\"\"\n", " delete state.start\n", " \"\"\",\n", " 'clear': \"\"\"\n", " state.ctx.clearRect(0, 0, canvas.width, canvas.height);\n", " \"\"\",\n", " 'save': \"\"\"\n", " data.uri = canvas.toDataURL();\n", " \"\"\",\n", " 'line_width': \"\"\"\n", " state.ctx.lineWidth = data.line_width;\n", " \"\"\",\n", " 'color': \"\"\"\n", " state.ctx.strokeStyle = data.color;\n", " \"\"\"\n", " }" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Example" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "canvas = Canvas(width=400, height=400)\n", "\n", "# We create a separate HTML element which syncs with the uri parameter of the Canvas\n", "png_view = pn.pane.HTML(height=400)\n", "canvas.jslink(png_view, code={'uri': \"target.text = ``\"})\n", "\n", "pn.Column(\n", " '# Drag on canvas to draw\\n To export the drawing to a png click save.',\n", " pn.Row(\n", " canvas.controls(['color', 'line_width']),\n", " canvas,\n", " png_view\n", " )\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## App\n", "\n", "Let's wrap it into nice template that can be served via `panel serve CanvasDraw.ipynb`" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "description=pn.pane.Markdown(\"This example shows how to use the `ReactiveHTML` component to develop a **Drawable Canvas**.\", sizing_mode=\"stretch_width\")\n", "pn.template.FastListTemplate(\n", " site=\"Panel\", title=\"Canvas Draw\", \n", " sidebar=[canvas.controls(['color', 'line_width'])], \n", " main=[description, pn.Row(canvas, png_view, height=460)]\n", ").servable();" ] } ], "metadata": { "language_info": { "name": "python", "pygments_lexer": "ipython3" } }, "nbformat": 4, "nbformat_minor": 4 }