canvas-designer
Version:
Collaborative, extendable, JavaScript Canvas2D drawing tool, supporting dozens of builtin tools, as well as generates JavaScript code for 2D animations.
822 lines (729 loc) • 28 kB
HTML
<html itemscope itemtype="http://schema.org/WebPage">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0, user-scalable=no">
<title>Canvas Designer | Muaz Khan</title>
<meta name="description" content="HTML5 Canvas Designer | Muaz Khan – A tool aimed to give you a full-fledged drawing surface and also auto generate appropriate code for you in different formats! Generator/Tool/Editor – 2D API/Context">
<meta name="author" content="Muaz Khan">
<link rel="author" type="text/html" href="https://plus.google.com/+MuazKhan">
<style>
/* Muaz Khan (@muazkh/@WebRTCWeb) */
textarea::::-webkit-scrollbar {
width: 0;
height: 0;
}
textarea::-webkit-scrollbar {
height: 0;
overflow: visible;
width: 10px;
border-left: 1px solid rgb(229, 229, 229);
}
textarea::-webkit-scrollbar-thumb {
background-color: rgba(0, 0, 0, .2);
background-clip: padding-box;
min-height: 28px;
padding: 100px 0 0;
box-shadow: inset 1px 1px 0 rgba(0, 0, 0, .1), inset 0 -1px 0 rgba(0, 0, 0, .07);
border-width: 1px 1px 1px 6px;
}
textarea::-webkit-scrollbar-button {
height: 0;
width: 0;
}
textarea::-webkit-scrollbar-track {
background-clip: padding-box;
border: solid transparent;
border-width: 0 0 0 4px;
}
textarea::-webkit-scrollbar-corner {
background: transparent;
}
::selection,
::-moz-selection {
background: #00A2E8;
color: #fff;
text-shadow: none;
}
html,
body,
input,
textarea,
h1,
h2 {
margin: 0;
padding: 0;
word-wrap: break-word;
-o-text-overflow: ellipsis;
-ms-text-overflow: ellipsis;
text-overflow: ellipsis;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
font-family: Verdana, arial, helvetica, sans-serif;
}
html,
body {
background-color: #FBFBFB;
font-size: 13px;
height: 100%;
cursor: default;
color: Gray;
overflow: hidden;
}
/* header */
h1,
.line-width-done,
.colors-done,
.additional-close {
background: -moz-linear-gradient(top, rgba(255, 255, 255, 1) 0%, rgba(243, 243, 243, 1) 97%, rgba(237, 237, 237, 1) 97%, rgba(255, 255, 255, 1) 100%);
/* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, rgba(255, 255, 255, 1)), color-stop(97%, rgba(243, 243, 243, 1)), color-stop(97%, rgba(237, 237, 237, 1)), color-stop(100%, rgba(255, 255, 255, 1)));
/* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, rgba(255, 255, 255, 1) 0%, rgba(243, 243, 243, 1) 97%, rgba(237, 237, 237, 1) 97%, rgba(255, 255, 255, 1) 100%);
/* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, rgba(255, 255, 255, 1) 0%, rgba(243, 243, 243, 1) 97%, rgba(237, 237, 237, 1) 97%, rgba(255, 255, 255, 1) 100%);
/* Opera 11.10+ */
background: -ms-linear-gradient(top, rgba(255, 255, 255, 1) 0%, rgba(243, 243, 243, 1) 97%, rgba(237, 237, 237, 1) 97%, rgba(255, 255, 255, 1) 100%);
/* IE10+ */
background: linear-gradient(top, rgba(255, 255, 255, 1) 0%, rgba(243, 243, 243, 1) 97%, rgba(237, 237, 237, 1) 97%, rgba(255, 255, 255, 1) 100%);
/* W3C */
filter: progid: DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#ffffff', GradientType=0);
/* IE6-9 */
}
/* links */
a {
color: #0b7aff;
text-decoration: none;
}
a:hover {
color: #043877;
}
/* design-surface */
.design-surface {
background-color: transparent;
}
.design-surface canvas {
position: absolute;
}
.design-surface canvas:last-child {
position: static;
}
/* toolbox */
.tool-box {
border-right: 1px solid #E5E5E5;
position: absolute;
top: 0;
width: 40px;
background-color: #FBFBFB;
overflow: hidden;
height: 100%;
overflow: hidden;
overflow-y: auto;
}
.tool-box::-webkit-scrollbar {
width: 0;
height: 0;
background-color:transparent;
}
.tool-box::-webkit-scrollbar-button {
height: 0;
width: 0
}
.tool-box::-webkit-scrollbar-thumb {
background-color:transparent;
border: 0;
}
.tool-box::-webkit-scrollbar-track {
background-color:transparent;
box-shadow: none;
}
.tool-box canvas {
border-bottom: 1px solid #E5E5E5;
border-radius: 2px;
margin-top: -4px;
display: none;
}
.tool-box canvas:first-child,
.tool-box canvas:first-child:hover {
margin-top: 0;
border-top: 0;
}
.tool-box canvas:hover {
box-shadow: none;
background: #eeeeee;
}
.selected-shape {
background: #eeeeee;
}
/* surface */
.preview-panel {
position: absolute;
right: 10px;
background-color: #FBFBFB;
bottom: 0;
}
.preview-panel div {
border: 1px solid #E5E5E5;
display: inline-block;
padding: 5px 10px;
}
.preview-panel #code-preview {
margin-left: -6px;
}
.preview-panel div {
border: 1px solid #E5E5E5;
}
.preview-panel div:not(.preview-selected) {} .preview-panel div {
border: 1px solid rgb(9, 159, 243);
}
.preview-selected {
margin-top: -4px;
background-color: rgb(6, 205, 255);
color: white;
}
/* input */
input,
select {
-webkit-border-radius: 1px;
-moz-border-radius: 1px;
border-radius: 1px;
border: 1px solid #D9D9D9;
-webkit-user-select: initial;
-moz-user-select: initial;
-ms-user-select: initial;
user-select: initial;
outline: none;
}
input:focus {
border: 1px solid #043877;
}
/* select */
.allow-select {
-webkit-user-select: initial;
-moz-user-select: initial;
user-select: initial
}
/* arc */
.arc-range-container, #pdf-page-container {
position: absolute;
z-index: 1000;
display: none;
}
.arc-range {
font-size: 18px;
padding: 2px 16px;
text-align: center;
width: 40px;
}
.arc-range-container-guide {
margin-top: 10px;
color: #C5C5C5;
}
/* code viewer */
.code-container {
position: absolute;
top: 0;
width: 100%;
display: none;
}
.code-text {
resize: none;
width: 99%;
height: 300px;
padding: 15px;
outline: 0;
border: 0;
border-top: 1px solid #E5E5E5;
font-family: Consolas, "Andale Mono", "Lucida Console", "Courier New", monospace;
color: #666;
}
/* options */
.options-container {
position: absolute;
top: 0;
left: 0;
border: 1px solid #E5E5E5;
border-left: 0;
background-color: #FBFBFB;
display: none;
}
.options-container div {
border-bottom: 1px solid #E5E5E5;
padding: 5px;
}
.options-container div:last-child {
border-bottom: 0;
}
/* context menu */
.context-popup {
position: absolute;
display: none;
padding: 5px;
border: 1px solid #E5E5E5;
border-left: 0;
background-color: #FBFBFB;
box-shadow: inset 0 0 14px rgb(229, 229, 229);
}
.line-width-text,
.colors-container input {
width: 25px;
padding: 2px 5px;
text-align: center;
}
/* colors */
.colors-container label {
width: 100px;
display: inline-block;
}
.colors-container input {
width: 100px;
text-align: left;
}
.colors-container .input-div {
margin-bottom: 5px;
}
/* additional controls */
.additional-container label,
.additional-container select {
width: 200px;
display: inline-block;
}
.additional-container select {
width: 120px;
}
.btn-007 {
font-family: Verdana, arial, helvetica, sans-serif;
font-weight: normal;
border-top-left-radius: 3px;
border-top-right-radius: 3px;
border-bottom-right-radius: 3px;
border-bottom-left-radius: 3px;
padding: 2px 3px;
text-decoration: none;
color: rgb(27, 26, 26);
display: inline-block;
box-shadow: rgb(255, 255, 255) 1px 1px 0px 0px inset;
text-shadow: none;
background: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(0.05, rgb(241, 241, 241)), to(rgb(230, 230, 230)));
font-size: 13px;
border: 1px solid red;
outline: none;
}
.btn-007:hover,
.btn-007:focus {
background: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(5%, rgb(221, 221, 221)), to(rgb(250, 250, 250)));
border: 1px solid rgb(142, 142, 142);
}
.btn-007[disabled] {
background: rgb(249, 249, 249);
border: 1px solid rgb(218, 207, 207);
color: rgb(197, 189, 189);
}
.fontSelect {
position: relative;
padding: 3px;
height: 28px;
line-height: 28px;
cursor: pointer;
margin: 3px;
width: 200px;
background-image: -webkit-linear-gradient(top, #f9f9f9, #f0f0f0);
background-image: -moz-linear-gradient(top, #f9f9f9, #f0f0f0);
background-image: -o-linear-gradient(top, #f9f9f9, #f0f0f0);
background-image: -ms-linear-gradient(top, #f9f9f9, #f0f0f0);
background-image: linear-gradient(top, #f9f9f9, #f0f0f0);
filter: progid: DXImageTransform.Microsoft.gradient(GradientType=0, StartColorStr='$from', EndColorStr='$to');
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
border: 1px solid #cecece;
}
.fontSelect span {
overflow: hidden;
margin-left: 5px;
}
.fontSelect .arrow-down {
position: absolute;
right: 10px;
top: 14px;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-top: 6px solid #AAA;
}
.fontSelectUl,
.fontSizeUl {
list-style: none;
width: 200px;
background: #f9f9f9;
position: absolute;
left: 0;
top: 35px;
padding: 0;
}
.fontSelectUl {
padding-left: 5px;
}
.fontSelectUl li,
.fontSizeUl li {
height: 24px;
line-height: 24px;
overflow: hidden;
cursor: pointer;
padding: 0 10px;
font-size: 14px;
border-left: 1px solid #f0f0f0;
border-right: 1px solid #f0f0f0;
}
.fontSelectUl li:last-child,
.fontSizeUl li:last-child {
-webkit-border-radius: 0 0 4px 4px;
-moz-border-radius: 0 0 4px 4px;
border-radius: 0 0 4px 4px;
border-bottom: 1px solid #EEEEEE;
}
.fontSelectUl li:hover,
.fontSizeUl li:hover {
background: #DDD;
}
.fontSelectUl li.font-family-selected,
.fontSizeUl li.font-size-selected {
background: rgb(6, 205, 255);
color: white;
}
#marker-selected-color,
#marker-selected-color-2, #pencil-selected-color,
#pencil-selected-color-2 {
display: inline-block;
vertical-align: middle;
width: 30px;
height: 30px;
}
#marker-fill-colors, #pencil-fill-colors {
display: none;
}
#marker-color-container, #pencil-color-container {
position: relative;
}
#marker-fill-colors, #pencil-fill-colors {
left: 100%;
top: 0;
width: 100px;
padding: 10px;
}
#marker-fill-style, #pencil-fill-style {
width: 50px;
display: inline-block;
}
#marker-colors-list, #pencil-colors-list {
margin: 10px auto;
border-collapse: collapse;
}
#marker-colors-list td, #pencil-colors-list td {
width: 15px;
height: 15px;
border: 1px solid black;
padding: 0;
}
#marker-colors-list td:hover, #pencil-colors-list td:hover {
border: 1px solid white;
}
#pdf-next, #pdf-prev, #pdf-close {
width: 22px;
vertical-align: middle;
cursor: pointer;
}
</style>
</head>
<body>
<section class="design-surface">
<canvas id="temp-canvas"></canvas>
<canvas id="main-canvas"></canvas>
</section>
<!-- toolbox -->
<section id="tool-box" class="tool-box">
<canvas id="pencil-icon" width="40" height="40" title="Panchil"></canvas>
<canvas id="marker-icon" width="40" height="40" title="Marker"></canvas>
<canvas id="eraser-icon" width="40" height="40" title="Erase drawings"></canvas>
<canvas id="text-icon" width="40" height="40" title="Write text"></canvas>
<canvas id="image-icon" width="40" height="40" title="Add image"></canvas>
<canvas id="pdf-icon" width="40" height="40" title="Add pdf"></canvas>
<canvas id="drag-last-path" width="40" height="40" title="Drag/move last path"></canvas>
<canvas id="drag-all-paths" width="40" height="40" title="Drag/move all paths"></canvas>
<canvas id="line" width="40" height="40" title="Draw Lines"></canvas>
<canvas id="arrow" width="40" height="40" title="Draw Arrows"></canvas>
<canvas id="zoom-up" width="40" height="40" title="Zoon-In"></canvas>
<canvas id="zoom-down" width="40" height="40" title="Zoom-Out"></canvas>
<canvas id="arc" width="40" height="40" title="Arc"></canvas>
<canvas id="rectangle" width="40" height="40" title="Rectangle"></canvas>
<canvas id="quadratic-curve" width="40" height="40" title="Quadratic curve"></canvas>
<canvas id="bezier-curve" width="40" height="40" title="Bezier curve"></canvas>
<canvas id="undo" width="40" height="40" title="Undo: Remove recent shapes"></canvas>
<canvas id="line-width" width="40" height="40" title="Set line-width"></canvas>
<canvas id="colors" width="40" height="40" title="Set foreground and background colors"></canvas>
<canvas id="additional" width="40" height="40" title="Extra options"></canvas>
</section>
<!-- pdf -->
<section id="pdf-page-container">
<img id="pdf-prev" />
<select id="pdf-pages-list"></select>
<img id="pdf-next" />
<img id="pdf-close" />
</section>
<!-- arc -->
<section id="arc-range-container" class="arc-range-container">
<input id="arc-range" class="arc-range" type="text" value="2">
<input type="checkbox" id="is-clockwise" checked="" class="allow-select">
<label for="is-clockwise">Clockwise?</label>
<div class="arc-range-container-guide">Use arrow keys ↑↓</div>
</section>
<!-- generated code -->
<section class="code-container">
<textarea id="code-text" class="code-text allow-select"></textarea>
</section>
<section class="preview-panel" style="display: none;">
<div id="design-preview" class="preview-selected">Preview</div>
<div id="code-preview">Code</div>
</section>
<!-- options -->
<section id="options-container" class="options-container">
<div>
<input type="checkbox" id="is-absolute-points" checked="">
<label for="is-absolute-points">Absolute Points</label>
</div>
<div>
<input type="checkbox" id="is-shorten-code" checked="">
<label for="is-shorten-code">Shorten Code</label>
</div>
</section>
<!-- line-width -->
<section id="line-width-container" class="context-popup">
<label for="line-width-text">Line Width:</label>
<input id="line-width-text" class="line-width-text" type="text" value="2">
<div id="line-width-done" class="btn-007">Done</div>
</section>
<!-- colors selector -->
<section id="colors-container" class="context-popup colors-container">
<div class="input-div">
<label for="stroke-style">Stroke Style:</label>
<input id="stroke-style" type="color" value="#6c96c8">
</div>
<div class="input-div">
<label for="fill-style">Fill Style:</label>
<input id="fill-style" type="color" value="#ffffff">
</div>
<div id="colors-done" class="btn-007">Done</div>
</section>
<!-- marker selector -->
<section id="marker-container" class="context-popup colors-container">
<div class="input-div">
<label for="marker-stroke-style">Thickness:</label>
<select id="marker-stroke-style" value="8">
<option value='8'>8</option>
<option value='9'>9</option>
<option value='10'>10</option>
<option value='11'>11</option>
<option value='12'>12</option>
<option value='14'>14</option>
<option value='16'>16</option>
<option value='18'>18</option>
<option value='20'>20</option>
<option value='22'>22</option>
<option value='22'>22</option>
<option value='24'>24</option>
<option value='26'>26</option>
<option value='28'>28</option>
<option value='36'>36</option>
<option value='36'>36</option>
<option value='48'>48</option>
<option value='72'>72</option>
</select>
</div>
<div class="input-div" id='marker-color-container'>
<label for="marker-fill-style">Fill Color:</label>
<div id="marker-selected-color"></div>
<div id="marker-fill-colors" class='context-popup'>
<div class="top">
<div id="marker-selected-color-2"></div>
<input id="marker-fill-style" type="text" value="FF7373">
</div>
<table id="marker-colors-list">
</table>
</div>
</div>
</div>
<div id="marker-done" class="btn-007">Done</div>
</section>
<!-- marker selector -->
<!-- pencil selector -->
<section id="pencil-container" class="context-popup colors-container">
<div class="input-div">
<label for="pencil-stroke-style">Thickness:</label>
<select id="pencil-stroke-style">
<option value='1'>1</option>
<option value='2'>2</option>
<option value='3'>3</option>
<option value='4'>4</option>
<option value='5' selected>5</option>
<option value='6'>6</option>
<option value='7'>7</option>
<option value='8'>8</option>
<option value='9'>9</option>
<option value='10'>10</option>
<option value='11'>11</option>
<option value='12'>12</option>
<option value='14'>14</option>
<option value='16'>16</option>
<option value='18'>18</option>
<option value='20'>20</option>
<option value='22'>22</option>
<option value='22'>22</option>
<option value='24'>24</option>
<option value='26'>26</option>
<option value='28'>28</option>
<option value='36'>36</option>
<option value='36'>36</option>
<option value='48'>48</option>
<option value='72'>72</option>
</select>
</div>
<div class="input-div" id='pencil-color-container'>
<label for="pencil-fill-style">Fill Color:</label>
<div id="pencil-selected-color"></div>
<div id="pencil-fill-colors" class='context-popup'>
<div class="top">
<div id="pencil-selected-color-2"></div>
<input id="pencil-fill-style" type="text" value="6699FF">
</div>
<table id="pencil-colors-list">
</table>
</div>
</div>
</div>
<div id="pencil-done" class="btn-007">Done</div>
</section>
<!-- pencil selector -->
<!-- copy paths -->
<section id="copy-container" class="context-popup">
<div>
<input type="checkbox" id="copy-last" checked="" />
<label for="copy-last">Copy last path</label>
</div>
<div style="margin-top: 5px;">
<input type="checkbox" id="copy-all" />
<label for="copy-all">Copy all paths</label>
</div>
</section>
<!-- additional controls -->
<section id="additional-container" class="context-popup additional-container">
<div>
<label for="lineCap-select">Line Cap:</label>
<select id="lineCap-select">
<option>round</option>
<option>butt</option>
<option>square</option>
</select>
</div>
<div>
<label for="lineJoin-select">Line Join:</label>
<select id="lineJoin-select">
<option>round</option>
<option>bevel</option>
<option>miter</option>
</select>
</div>
<div>
<label for="globalAlpha-select">globalAlpha:</label>
<select id="globalAlpha-select">
<option>1.0</option>
<option>0.9</option>
<option>0.8</option>
<option>0.7</option>
<option>0.6</option>
<option>0.5</option>
<option>0.4</option>
<option>0.3</option>
<option>0.2</option>
<option>0.1</option>
<option>0.0</option>
</select>
</div>
<div>
<label for="globalCompositeOperation-select">globalCompositeOperation:</label>
<select id="globalCompositeOperation-select">
<option>source-atop</option>
<option>source-in</option>
<option>source-out</option>
<option selected="">source-over</option>
<option>destination-atop</option>
<option>destination-in</option>
<option>destination-out</option>
<option>destination-over</option>
<option>lighter</option>
<option>copy</option>
<option>xor</option>
</select>
</div>
<div id="additional-close" class="btn-007">Done</div>
</section>
<!-- fade -->
<div id="fade"></div>
<!-- text font/family/color -->
<ul class="fontSelectUl" style="display: none; position: absolute; top: 0; left: 0; width: 166px;">
<li>Arial</li>
<li>Arial Black</li>
<li>Comic Sans MS</li>
<li>Courier New</li>
<li>Georgia</li>
<li>Tahoma</li>
<li>Times New Roman</li>
<li>Trebuchet MS</li>
<li>Verdana</li>
</ul>
<ul class="fontSizeUl" style="display: none; position: absolute; top: 0; left: 0; width: 50px; text-align: center;">
<li>15</li>
<li>17</li>
<li>19</li>
<li>20</li>
<li>22</li>
<li>25</li>
<li>30</li>
<li>35</li>
<li>42</li>
<li>48</li>
<li>60</li>
<li>72</li>
</ul>
<!-- url-parameters -->
<script>
(function() {
var params = {},
r = /([^&=]+)=?([^&]*)/g;
function d(s) {
return decodeURIComponent(s.replace(/\+/g, ' '));
}
var match, search = window.location.search;
while (match = r.exec(search.substring(1)))
params[d(match[1])] = d(match[2]);
window.params = params;
})();
window.selectedIcon = params.selectedIcon;
if (window.selectedIcon) {
try {
window.selectedIcon = window.selectedIcon.split('')[0].toUpperCase() + window.selectedIcon.replace(window.selectedIcon.split('').shift(1), '');
} catch (e) {
window.selectedIcon = 'Pencil';
}
} else {
window.selectedIcon = 'Pencil';
}
var script = document.createElement('script');
script.src = params.widgetJsURL || 'https://cdn.webrtc-experiment.com/Canvas-Designer/widget.min.js';
(document.body || document.documentElement).appendChild(script);
</script>
<script src="https://cdn.jsdelivr.net/npm/pdfjs-dist@2.0.489/build/pdf.min.js"></script>
</body>
</html>