-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js.map
1 lines (1 loc) · 51.7 KB
/
index.js.map
1
{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./src/index.css?a55a","webpack:///./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js","webpack:///./src/index.css","webpack:///./node_modules/css-loader/dist/runtime/api.js","webpack:///./src/js/App/loop.js","webpack:///./src/js/App/layout.js","webpack:///./src/js/App/drawer.js","webpack:///./src/js/App/history.js","webpack:///./src/js/App/App.js","webpack:///./src/js/index.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","api","content","default","options","locals","memo","isOldIE","Boolean","window","document","all","atob","getTarget","target","styleTarget","querySelector","HTMLIFrameElement","contentDocument","head","e","stylesInDom","getIndexByIdentifier","identifier","result","length","modulesToDom","list","idCountMap","identifiers","item","id","base","count","concat","index","obj","css","media","sourceMap","references","updater","push","addStyle","insertStyleElement","style","createElement","attributes","nonce","keys","forEach","setAttribute","insert","Error","appendChild","textStore","replaceText","replacement","filter","join","applyToSingletonTag","remove","styleSheet","cssText","cssNode","createTextNode","childNodes","removeChild","insertBefore","applyToTag","removeAttribute","btoa","unescape","encodeURIComponent","JSON","stringify","firstChild","singleton","singletonCounter","update","styleIndex","parentNode","removeStyleElement","newObj","lastIdentifiers","newList","toString","newLastIdentifiers","_i","_index","splice","___CSS_LOADER_API_IMPORT___","useSourceMap","this","map","cssMapping","sourceMapping","base64","data","sourceURLs","sources","source","sourceRoot","cssWithMappingToString","mediaQuery","dedupe","alreadyImportedModules","callback","loop","requestAnimationFrame","stop","cancelAnimationFrame","tool","x1","x2","y1","y2","Math","min","max","layout","every","canvas","ctx","getContext","width","offsetWidth","height","offsetHeight","buffering","layouts","lastRenderedCached","lastGoingRendered","compare","slice","renderLayout","clearRect","renderCircle","coords","some","Number","isFinite","a","b","radius","sqrt","bigEnough","weight","fillStyle","beginPath","arc","PI","fill","renderLine","lineWidth","moveTo","lineTo","stroke","fillRect","renderRect","getConsistentCoords","getCoords","renderBrush","step","history","getSteps","lastStep","lastStepIndex","from","to","h","container","clicked","paper","control","buttons","main","clear","tools","rect","brush","circle","line","undo","redo","drawer","render","selectTool","bindEvents","refreshHistoryButtons","canvasRect","getBoundingClientRect","canvasCoords","x","y","toCanvasCoords","addEventListener","currentTarget","checked","values","button","getAttribute","clientX","clientY","start","previousLayout","pop","addStep","ex","hasAttribute","reduce","prev","next","querySelectorAll","el","classList","add","getLayoutsFromHistory","previousLayouts","lastPreviousLayout","init"],"mappings":"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","file":"index.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 4);\n","var api = require(\"!../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\");\n var content = require(\"!!../node_modules/css-loader/dist/cjs.js!./index.css\");\n\n content = content.__esModule ? content.default : content;\n\n if (typeof content === 'string') {\n content = [[module.id, content, '']];\n }\n\nvar options = {\"injectType\":\"singletonStyleTag\"};\n\noptions.insert = \"head\";\noptions.singleton = true;\n\nvar update = api(content, options);\n\n\n\nmodule.exports = content.locals || {};","\"use strict\";\n\nvar isOldIE = function isOldIE() {\n var memo;\n return function memorize() {\n if (typeof memo === 'undefined') {\n // Test for IE <= 9 as proposed by Browserhacks\n // @see http://browserhacks.com/#hack-e71d8692f65334173fee715c222cb805\n // Tests for existence of standard globals is to allow style-loader\n // to operate correctly into non-standard environments\n // @see https://github.com/webpack-contrib/style-loader/issues/177\n memo = Boolean(window && document && document.all && !window.atob);\n }\n\n return memo;\n };\n}();\n\nvar getTarget = function getTarget() {\n var memo = {};\n return function memorize(target) {\n if (typeof memo[target] === 'undefined') {\n var styleTarget = document.querySelector(target); // Special case to return head of iframe instead of iframe itself\n\n if (window.HTMLIFrameElement && styleTarget instanceof window.HTMLIFrameElement) {\n try {\n // This will throw an exception if access to iframe is blocked\n // due to cross-origin restrictions\n styleTarget = styleTarget.contentDocument.head;\n } catch (e) {\n // istanbul ignore next\n styleTarget = null;\n }\n }\n\n memo[target] = styleTarget;\n }\n\n return memo[target];\n };\n}();\n\nvar stylesInDom = [];\n\nfunction getIndexByIdentifier(identifier) {\n var result = -1;\n\n for (var i = 0; i < stylesInDom.length; i++) {\n if (stylesInDom[i].identifier === identifier) {\n result = i;\n break;\n }\n }\n\n return result;\n}\n\nfunction modulesToDom(list, options) {\n var idCountMap = {};\n var identifiers = [];\n\n for (var i = 0; i < list.length; i++) {\n var item = list[i];\n var id = options.base ? item[0] + options.base : item[0];\n var count = idCountMap[id] || 0;\n var identifier = \"\".concat(id, \" \").concat(count);\n idCountMap[id] = count + 1;\n var index = getIndexByIdentifier(identifier);\n var obj = {\n css: item[1],\n media: item[2],\n sourceMap: item[3]\n };\n\n if (index !== -1) {\n stylesInDom[index].references++;\n stylesInDom[index].updater(obj);\n } else {\n stylesInDom.push({\n identifier: identifier,\n updater: addStyle(obj, options),\n references: 1\n });\n }\n\n identifiers.push(identifier);\n }\n\n return identifiers;\n}\n\nfunction insertStyleElement(options) {\n var style = document.createElement('style');\n var attributes = options.attributes || {};\n\n if (typeof attributes.nonce === 'undefined') {\n var nonce = typeof __webpack_nonce__ !== 'undefined' ? __webpack_nonce__ : null;\n\n if (nonce) {\n attributes.nonce = nonce;\n }\n }\n\n Object.keys(attributes).forEach(function (key) {\n style.setAttribute(key, attributes[key]);\n });\n\n if (typeof options.insert === 'function') {\n options.insert(style);\n } else {\n var target = getTarget(options.insert || 'head');\n\n if (!target) {\n throw new Error(\"Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid.\");\n }\n\n target.appendChild(style);\n }\n\n return style;\n}\n\nfunction removeStyleElement(style) {\n // istanbul ignore if\n if (style.parentNode === null) {\n return false;\n }\n\n style.parentNode.removeChild(style);\n}\n/* istanbul ignore next */\n\n\nvar replaceText = function replaceText() {\n var textStore = [];\n return function replace(index, replacement) {\n textStore[index] = replacement;\n return textStore.filter(Boolean).join('\\n');\n };\n}();\n\nfunction applyToSingletonTag(style, index, remove, obj) {\n var css = remove ? '' : obj.media ? \"@media \".concat(obj.media, \" {\").concat(obj.css, \"}\") : obj.css; // For old IE\n\n /* istanbul ignore if */\n\n if (style.styleSheet) {\n style.styleSheet.cssText = replaceText(index, css);\n } else {\n var cssNode = document.createTextNode(css);\n var childNodes = style.childNodes;\n\n if (childNodes[index]) {\n style.removeChild(childNodes[index]);\n }\n\n if (childNodes.length) {\n style.insertBefore(cssNode, childNodes[index]);\n } else {\n style.appendChild(cssNode);\n }\n }\n}\n\nfunction applyToTag(style, options, obj) {\n var css = obj.css;\n var media = obj.media;\n var sourceMap = obj.sourceMap;\n\n if (media) {\n style.setAttribute('media', media);\n } else {\n style.removeAttribute('media');\n }\n\n if (sourceMap && btoa) {\n css += \"\\n/*# sourceMappingURL=data:application/json;base64,\".concat(btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))), \" */\");\n } // For old IE\n\n /* istanbul ignore if */\n\n\n if (style.styleSheet) {\n style.styleSheet.cssText = css;\n } else {\n while (style.firstChild) {\n style.removeChild(style.firstChild);\n }\n\n style.appendChild(document.createTextNode(css));\n }\n}\n\nvar singleton = null;\nvar singletonCounter = 0;\n\nfunction addStyle(obj, options) {\n var style;\n var update;\n var remove;\n\n if (options.singleton) {\n var styleIndex = singletonCounter++;\n style = singleton || (singleton = insertStyleElement(options));\n update = applyToSingletonTag.bind(null, style, styleIndex, false);\n remove = applyToSingletonTag.bind(null, style, styleIndex, true);\n } else {\n style = insertStyleElement(options);\n update = applyToTag.bind(null, style, options);\n\n remove = function remove() {\n removeStyleElement(style);\n };\n }\n\n update(obj);\n return function updateStyle(newObj) {\n if (newObj) {\n if (newObj.css === obj.css && newObj.media === obj.media && newObj.sourceMap === obj.sourceMap) {\n return;\n }\n\n update(obj = newObj);\n } else {\n remove();\n }\n };\n}\n\nmodule.exports = function (list, options) {\n options = options || {}; // Force single-tag solution on IE6-9, which has a hard limit on the # of <style>\n // tags it will allow on a page\n\n if (!options.singleton && typeof options.singleton !== 'boolean') {\n options.singleton = isOldIE();\n }\n\n list = list || [];\n var lastIdentifiers = modulesToDom(list, options);\n return function update(newList) {\n newList = newList || [];\n\n if (Object.prototype.toString.call(newList) !== '[object Array]') {\n return;\n }\n\n for (var i = 0; i < lastIdentifiers.length; i++) {\n var identifier = lastIdentifiers[i];\n var index = getIndexByIdentifier(identifier);\n stylesInDom[index].references--;\n }\n\n var newLastIdentifiers = modulesToDom(newList, options);\n\n for (var _i = 0; _i < lastIdentifiers.length; _i++) {\n var _identifier = lastIdentifiers[_i];\n\n var _index = getIndexByIdentifier(_identifier);\n\n if (stylesInDom[_index].references === 0) {\n stylesInDom[_index].updater();\n\n stylesInDom.splice(_index, 1);\n }\n }\n\n lastIdentifiers = newLastIdentifiers;\n };\n};","// Imports\nvar ___CSS_LOADER_API_IMPORT___ = require(\"../node_modules/css-loader/dist/runtime/api.js\");\nexports = ___CSS_LOADER_API_IMPORT___(false);\n// Module\nexports.push([module.id, \"body, html {\\n padding: 0;\\n margin: 0;\\n width: 100%;\\n height: 100%;\\n}\\nbody {\\n display: flex;\\n justify-content: center;\\n align-items: center;\\n}\\n\\n#app {\\n display: flex;\\n flex-direction: column;\\n width: 100%;\\n height: 100%;\\n justify-content: center;\\n align-items: center;\\n font-family: sans-serif;\\n}\\n\\n#drawer-control {\\n padding: 7px;\\n width: 100%;\\n max-width: 800px;\\n display: flex;\\n justify-content: space-around;\\n}\\n#drawer-control code {\\n font-size: 1.2em;\\n}\\n#drawer-control .request-animation-frame {\\n display: flex;\\n}\\n#drawer-control .request-animation-frame input {\\n margin-left: 15px;\\n}\\n\\n#drawer-area {\\n border: 1px solid black;\\n width: 100%;\\n height: 100%;\\n max-width: 800px;\\n max-height: 600px;\\n display: flex;\\n align-items: stretch;\\n justify-content: stretch;\\n}\\n#drawer-area, #drawer-area * {\\n box-sizing: border-box;\\n}\\n#drawer-area .tool {\\n background-color: silver;\\n width: 40px;\\n border-right: 1px solid #aaa;\\n display: flex;\\n justify-content: center;\\n align-items: center;\\n flex-direction: column;\\n}\\n#drawer-area .tool .tools {\\n display: flex;\\n justify-content: center;\\n align-items: center;\\n flex-direction: column;\\n padding: 10px 0;\\n}\\n#drawer-area .tool .tools.tools-drawing {\\n flex-grow: 1;\\n}\\n#drawer-area .icon-button {\\n padding: 0;\\n display: flex;\\n justify-content: center;\\n align-items: center;\\n background-color: #ddd;\\n border: 1px solid gray;\\n border-radius: 3px;\\n width: 28px;\\n height: 28px;\\n margin: 5px;\\n cursor: pointer;\\n box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.25);\\n transition-duration: 300ms;\\n font-size: 18px;\\n}\\n#drawer-area .icon-button:hover {\\n border-color: black;\\n background-color: white;\\n transform: scale(1.1);\\n transition-duration: 200ms;\\n}\\n#drawer-area .icon-button:focus {\\n outline: none;\\n}\\n#drawer-area .icon-button.active {\\n background-color: yellow;\\n}\\n#drawer-area .icon-button.clear {\\n align-self: flex-start;\\n}\\n#drawer-area .icon-button .line-icon {\\n width: 20px;\\n height: 0px;\\n border: 1px solid black;\\n transform: rotate(40deg);\\n border-radius: 3px;\\n}\\n#drawer-area .paper {\\n background-color: #eee;\\n flex-grow: 1;\\n cursor: crosshair;\\n}\\n\", \"\"]);\n// Exports\nmodule.exports = exports;\n","\"use strict\";\n\n/*\n MIT License http://www.opensource.org/licenses/mit-license.php\n Author Tobias Koppers @sokra\n*/\n// css base code, injected by the css-loader\n// eslint-disable-next-line func-names\nmodule.exports = function (useSourceMap) {\n var list = []; // return the list of modules as css string\n\n list.toString = function toString() {\n return this.map(function (item) {\n var content = cssWithMappingToString(item, useSourceMap);\n\n if (item[2]) {\n return \"@media \".concat(item[2], \" {\").concat(content, \"}\");\n }\n\n return content;\n }).join('');\n }; // import a list of modules into the list\n // eslint-disable-next-line func-names\n\n\n list.i = function (modules, mediaQuery, dedupe) {\n if (typeof modules === 'string') {\n // eslint-disable-next-line no-param-reassign\n modules = [[null, modules, '']];\n }\n\n var alreadyImportedModules = {};\n\n if (dedupe) {\n for (var i = 0; i < this.length; i++) {\n // eslint-disable-next-line prefer-destructuring\n var id = this[i][0];\n\n if (id != null) {\n alreadyImportedModules[id] = true;\n }\n }\n }\n\n for (var _i = 0; _i < modules.length; _i++) {\n var item = [].concat(modules[_i]);\n\n if (dedupe && alreadyImportedModules[item[0]]) {\n // eslint-disable-next-line no-continue\n continue;\n }\n\n if (mediaQuery) {\n if (!item[2]) {\n item[2] = mediaQuery;\n } else {\n item[2] = \"\".concat(mediaQuery, \" and \").concat(item[2]);\n }\n }\n\n list.push(item);\n }\n };\n\n return list;\n};\n\nfunction cssWithMappingToString(item, useSourceMap) {\n var content = item[1] || ''; // eslint-disable-next-line prefer-destructuring\n\n var cssMapping = item[3];\n\n if (!cssMapping) {\n return content;\n }\n\n if (useSourceMap && typeof btoa === 'function') {\n var sourceMapping = toComment(cssMapping);\n var sourceURLs = cssMapping.sources.map(function (source) {\n return \"/*# sourceURL=\".concat(cssMapping.sourceRoot || '').concat(source, \" */\");\n });\n return [content].concat(sourceURLs).concat([sourceMapping]).join('\\n');\n }\n\n return [content].join('\\n');\n} // Adapted from convert-source-map (MIT)\n\n\nfunction toComment(sourceMap) {\n // eslint-disable-next-line no-undef\n var base64 = btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap))));\n var data = \"sourceMappingURL=data:application/json;charset=utf-8;base64,\".concat(base64);\n return \"/*# \".concat(data, \" */\");\n}","/**\n * Controls animation frames\n */\nclass Loop {\n constructor(callback) {\n // This callback will be run at each animation frame\n this.callback = callback;\n this.id = null;\n }\n\n start() {\n const loop = () => {\n this.id = requestAnimationFrame(loop);\n this.callback();\n };\n this.stop();\n loop();\n }\n\n stop() {\n if (this.id) {\n cancelAnimationFrame(this.id);\n this.id = null;\n // Run callback last time to apply all the changes\n this.callback();\n }\n this.id = null;\n }\n}\n\nexport default Loop;\n","/**\n * Represents layout coords and selected tool.\n */\nclass Layout {\n constructor(options = {}) {\n this.tool = options.tool || null;\n this.x1 = options.x1 || null;\n this.x2 = options.x2 || null;\n this.y1 = options.y1 || null;\n this.y2 = options.y2 || null;\n }\n\n /**\n * Returns original coords\n * @returns {object}\n */\n getCoords() {\n return {\n x1: this.x1,\n x2: this.x2,\n y1: this.y1,\n y2: this.y2,\n };\n }\n\n /**\n * Returns coords assuming that x1 and y1 are coords of the top left cornor.\n * @returns {object}\n */\n getConsistentCoords() {\n const { x1, x2 } = this;\n const { y1, y2 } = this;\n const result = {};\n\n if (x2 === null || x1 === null) {\n result.x1 = x1 === null ? x2 : x1;\n result.x2 = x1 === null ? x1 : x2;\n } else {\n result.x1 = Math.min(x1, x2);\n result.x2 = Math.max(x1, x2);\n }\n\n if (y1 === null || y2 === null) {\n result.y1 = y1 === null ? y2 : y1;\n result.y2 = y1 === null ? y1 : y2;\n } else {\n result.y1 = Math.min(y1, y2);\n result.y2 = Math.max(y1, y2);\n }\n return result;\n }\n\n /**\n * Returns true if layouts are identical\n * @param {Layout} layout\n * @returns {boolean}\n */\n compare(layout) {\n const conditions = [\n layout.tool === this.tool,\n layout.x1 === this.x1,\n layout.x2 === this.x2,\n layout.y1 === this.y1,\n layout.y2 === this.y2,\n ];\n return conditions.every((c) => c);\n }\n}\n\nexport default Layout;\n","/**\n * Canvas controller.\n */\nclass Drawer {\n constructor(options = {}) {\n const { canvas } = options;\n\n this.ctx = canvas.getContext('2d');\n this.width = canvas.offsetWidth;\n this.height = canvas.offsetHeight;\n\n // If buffering is enabled, Drawer will render only new layouts (without clearing canvas and\n // render all the data from the scratch).\n this.buffering = false;\n\n // Last rendered layouts array\n this.layouts = [];\n }\n\n /**\n * Update canvas with new layouts\n * @param {object[]} layouts\n */\n update(layouts = []) {\n if (this.buffering) {\n if (this.layouts.length < layouts.length && layouts.length > 1) {\n const lastRenderedCached = this.layouts[this.layouts.length - 1];\n const lastGoingRendered = layouts[this.layouts.length - 1];\n const equals = lastRenderedCached.compare(lastGoingRendered);\n\n if (equals) {\n const newLayouts = layouts.slice(this.layouts.length, layouts.length);\n newLayouts.forEach((l) => this.renderLayout(l));\n this.layouts = layouts;\n return;\n }\n }\n }\n this.layouts = layouts;\n // Clear canvas before update\n this.ctx.clearRect(0, 0, this.width, this.height);\n layouts.forEach((l) => this.renderLayout(l));\n }\n\n renderLayout(layout) {\n // Lines width\n const weight = 4;\n const { ctx } = this;\n\n const renderRect = (coords) => {\n const { x1, y1 } = coords;\n const { x2, y2 } = coords;\n\n if ([x1, x2, y1, y2].some((c) => !Number.isFinite(c))) {\n return;\n }\n // If the shape is biggest then two lines width sum, fill it inside with white color\n const bigEnough = (x2 - x1) > (weight * 2) && (y2 - y1) > (weight * 2);\n ctx.fillStyle = 'black';\n ctx.fillRect(x1, y1, x2 - x1, y2 - y1);\n\n // Draw white rectangle within black\n if (bigEnough) {\n ctx.fillStyle = 'white';\n ctx.fillRect(\n x1 + weight,\n y1 + weight,\n (x2 - x1) - (weight * 2),\n (y2 - y1) - (weight * 2),\n );\n }\n };\n const renderCircle = (coords) => {\n if ([coords.x2, coords.y2].some((c) => !Number.isFinite(c))) {\n return;\n }\n const { x1, y1 } = coords;\n const { x2, y2 } = coords;\n\n const a = x2 - x1;\n const b = y2 - y1;\n const radius = Math.sqrt((a * a) + (b * b));\n\n // If the shape is biggest then two lines width sum, fill it inside with white color\n const bigEnough = radius > weight * 2;\n\n ctx.fillStyle = 'black';\n ctx.beginPath();\n ctx.arc(x1, y1, radius, 0, Math.PI * 2);\n ctx.fill();\n\n // Draw white circle within black one\n if (bigEnough) {\n ctx.fillStyle = 'white';\n ctx.beginPath();\n ctx.arc(x1, y1, radius - weight, 0, Math.PI * 2);\n ctx.fill();\n }\n };\n const renderLine = (coords) => {\n if ([coords.x2, coords.y2].some((c) => !Number.isFinite(c))) {\n return;\n }\n const { x1, y1 } = coords;\n const { x2, y2 } = coords;\n\n ctx.lineWidth = weight;\n ctx.beginPath();\n ctx.moveTo(x1, y1);\n ctx.lineTo(x2, y2);\n ctx.stroke();\n };\n const renderBrush = (coords) => {\n const { x1, y1 } = coords;\n const { x2, y2 } = coords;\n\n // Each brush move is a combination of two circles located at start and end coords, and a\n // line between them. We will draw small circle at the start coords even in case there is no\n // finish coords yet (so it will look like bursh touch right after mousedown event).\n renderCircle({\n x1,\n y1,\n x2: x1 + (weight / 2),\n y2: y1,\n });\n if ([x2, y2].some((c) => !Number.isFinite(c))) {\n return;\n }\n renderLine({\n x1,\n y1,\n x2,\n y2,\n });\n renderCircle({\n x1: x2,\n y1: y2,\n x2: x2 + (weight / 2),\n y2,\n });\n };\n\n switch (layout.tool) {\n case 'rect': {\n const coords = layout.getConsistentCoords();\n renderRect(coords);\n break;\n }\n case 'circle': {\n const coords = layout.getCoords();\n renderCircle(coords);\n break;\n }\n case 'brush': {\n const coords = layout.getCoords();\n renderBrush(coords);\n break;\n }\n default:\n case 'line': {\n const coords = layout.getCoords();\n renderLine(coords);\n break;\n }\n }\n }\n}\n\nexport default Drawer;\n","/**\n * Represents history storage. Helps to manage history actions (undo, redo, etc).\n */\nclass History {\n constructor() {\n // Current step.\n this.step = 0;\n\n // Steps storage.\n this.history = [];\n }\n\n /**\n * Save value as a new step. Increase current step index.\n * @param {any} value\n */\n addStep(value) {\n // Do not change step untill [getSteps] function run.\n const step = this.step + 1;\n\n this.history = [\n ...this.getSteps(),\n { value, step },\n ];\n this.step = step;\n }\n\n /**\n * Return to the previous step, if possible.\n */\n prev() {\n this.step = this.step > 0 ? this.step - 1 : 0;\n }\n\n /**\n * Go to the next step, if possible.\n */\n next() {\n const lastStep = this.lastStepIndex();\n this.step = this.step >= lastStep ? lastStep : this.step + 1;\n }\n\n /**\n * Returns array of all steps from given step, to given step (from 0 to current step by default).\n * @param {object} [options]\n * @param {number} [options.from]\n * @param {number} [options.to]\n * @returns {object[]}\n */\n getSteps(options = {}) {\n const {\n from = 0,\n to = this.step,\n } = options;\n\n return this.history.filter((h) => h.step >= from && h.step <= to);\n }\n\n /**\n * Returns last saved step index.\n * @returns {number}\n */\n lastStepIndex() {\n return this.history.length ? this.history[this.history.length - 1].step : 0;\n }\n\n /**\n * Clear history storage.\n */\n clear() {\n this.step = 0;\n this.history.length = 0;\n }\n}\n\nexport default History;\n","import Loop from './loop';\nimport Layout from './layout';\nimport Drawer from './drawer';\nimport History from './history';\n\n// TODO: Listen for window size changing\n// TODO: Add ability to change line weight\n// TODO: Add ability to change the color\n\n/**\n * Drawer controller\n * @param {object} options\n * @param {HTMLElement} options.container\n */\nclass DrawerApp {\n constructor(options = {}) {\n const { container } = options;\n\n // If true, render will be started on requestAnimationFrame callback.\n this.requestAnimationFrame = false;\n\n // We will set this property to true during drawing process (when the left mouse button will\n // be pressed).\n this.clicked = false;\n\n // This is currently selected drawing tool. Could be one of: rect, circle, line, brush.\n this.tool = 'rect';\n\n // This is the place where we will store our current step layouts.\n this.layouts = [];\n\n this.container = container;\n this.paper = container.querySelector('.paper');\n this.canvas = container.querySelector('canvas');\n this.control = {\n requestAnimationFrame: container.querySelector('.request-animation-frame input'),\n buffering: container.querySelector('.buffering input'),\n };\n this.buttons = {\n main: {\n clear: container.querySelector('.icon-button[data-tool=\"clear\"]'),\n },\n tools: {\n rect: container.querySelector('.icon-button[data-tool=\"rect\"]'),\n brush: container.querySelector('.icon-button[data-tool=\"brush\"]'),\n circle: container.querySelector('.icon-button[data-tool=\"circle\"]'),\n line: container.querySelector('.icon-button[data-tool=\"line\"]'),\n },\n history: {\n undo: container.querySelector('.icon-button[data-tool=\"undo\"]'),\n redo: container.querySelector('.icon-button[data-tool=\"redo\"]'),\n },\n };\n const { offsetWidth, offsetHeight } = this.paper;\n this.canvas.setAttribute('width', offsetWidth);\n this.canvas.setAttribute('height', offsetHeight);\n\n // Create Drawer instance.\n this.drawer = new Drawer({ canvas: this.canvas });\n\n // Storage, where we will keep our already finished layouts for each step.\n this.history = new History();\n\n this.loop = new Loop(() => this.render());\n }\n\n /**\n * Initialize the instance\n */\n init() {\n this.selectTool();\n this.bindEvents();\n this.refreshHistoryButtons();\n }\n\n /**\n * Listen for DOM events\n */\n bindEvents() {\n const canvasRect = this.canvas.getBoundingClientRect();\n const canvasCoords = {\n x1: canvasRect.x,\n x2: canvasRect.x + this.paper.offsetWidth,\n y1: canvasRect.y,\n y2: canvasRect.y + this.paper.offsetHeight,\n };\n\n /**\n * Transforms viewport coords to the canvas coords.\n * @param {number} x - Viewport X coord\n * @param {number} y - Viewport Y coord\n */\n const toCanvasCoords = (x, y) => ({\n x: x - canvasCoords.x1,\n y: y - canvasCoords.y1,\n });\n\n // Listen for requestAnimationFrame option change\n this.control.requestAnimationFrame.addEventListener('change', (e) => {\n this.requestAnimationFrame = e.currentTarget.checked;\n });\n\n this.control.buffering.addEventListener('change', (e) => {\n this.drawer.buffering = e.currentTarget.checked;\n });\n\n // Listen for each tool button click and change currently selected tool.\n Object.values(this.buttons.tools).forEach((button) => {\n button.addEventListener('click', (e) => {\n const tool = e.currentTarget.getAttribute('data-tool');\n this.selectTool(tool);\n });\n });\n\n // Listen for each main button click\n Object.values(this.buttons.main).forEach((button) => {\n button.addEventListener('click', (e) => {\n const tool = e.currentTarget.getAttribute('data-tool');\n\n if (tool === 'clear') {\n // Clear all the data and redraw the canvas.\n this.layouts = [];\n this.history.clear();\n this.refreshHistoryButtons();\n this.render();\n }\n });\n });\n\n // Canvas mousedown event\n this.canvas.addEventListener('mousedown', (e) => {\n const c = toCanvasCoords(e.clientX, e.clientY);\n\n // User starts drawing\n this.clicked = true;\n\n // Create new layout instance for new shape (at this moment we have only starting coords).\n this.layouts.push(new Layout({\n tool: this.tool,\n x1: c.x,\n y1: c.y,\n }));\n if (this.requestAnimationFrame) {\n // Render using requestAnimationFrame callback\n this.loop.start();\n return;\n }\n // Otherwise run render directly\n this.render();\n });\n\n // Canvas mousemove event\n this.canvas.addEventListener('mousemove', (e) => {\n // Run only in case of drawing process. Also do not run this condition in case of new shape's\n // layout is not presented (could be an error case).\n if (this.clicked && this.layouts.length) {\n const c = toCanvasCoords(e.clientX, e.clientY);\n const previousLayout = this.layouts.pop();\n\n // Replace last shape layout with new coords after move.\n this.layouts.push(new Layout({\n tool: previousLayout.tool,\n x1: previousLayout.x1,\n y1: previousLayout.y1,\n x2: c.x,\n y2: c.y,\n }));\n\n // We emulate brush tool with number of small lines. So, in the case of brush tool we\n // finish a small line, and repeat steps from the [mousedown] event to create new small\n // line layout\n if (this.tool === 'brush') {\n this.layouts.push(new Layout({\n tool: this.tool,\n x1: c.x,\n y1: c.y,\n }));\n }\n if (!this.requestAnimationFrame) {\n // Render directly from event callback.\n this.render();\n }\n }\n });\n\n // Canvas mouseup event\n this.canvas.addEventListener('mouseup', () => {\n // User finishes drawing\n this.clicked = false;\n\n // Current drawing step is finished, move all step layouts to the history.\n if (this.layouts.length) {\n this.history.addStep(this.layouts);\n }\n this.layouts = [];\n this.refreshHistoryButtons();\n\n // Last render call will be run from the loop instance after stopping.\n if (this.requestAnimationFrame) {\n this.loop.stop();\n return;\n }\n // requestAnimationFrame is off. Run render directly.\n this.render();\n });\n\n // Listen for document mousemove event to catch the moment when the cursor has left the canvas.\n // If it happened, clear not finished shape's layout.\n document.addEventListener('mousemove', (e) => {\n const exceptions = [\n e.clientX < canvasCoords.x1,\n e.clientX > canvasCoords.x2,\n e.clientY < canvasCoords.y1,\n e.clientY > canvasCoords.y2,\n ];\n if (exceptions.some((ex) => ex)) {\n const inProcess = Boolean(this.clicked && this.layouts.length);\n\n if (inProcess) {\n // Clear all step layouts, mark drawing process as finished, and redraw the canvas.\n this.clicked = false;\n this.layouts = [];\n\n // Rerender will be run from loop instance.\n if (this.requestAnimationFrame) {\n this.loop.stop();\n return;\n }\n // requestAnimationFrame is off. Run rerender directly.\n this.render();\n }\n }\n });\n\n // History buttons\n Object.values(this.buttons.history).forEach((button) => {\n button.addEventListener('click', (/* e */) => {\n if (button.hasAttribute('disabled')) {\n return;\n }\n const direction = button.getAttribute('data-tool');\n\n if (direction === 'undo') {\n this.undo();\n return;\n }\n this.redo();\n });\n });\n }\n\n /**\n * Returns all layouts from history.\n * @returns {Layout[]}\n */\n getLayoutsFromHistory() {\n return this.history.getSteps().reduce((layouts, { value }) => ([\n ...layouts,\n ...value,\n ]), []);\n }\n\n /**\n * Refresh history buttons state and look.\n */\n refreshHistoryButtons() {\n const { undo, redo } = this.buttons.history;\n const { step } = this.history;\n const lastStep = this.history.lastStepIndex();\n\n if (step < 1) {\n undo.setAttribute('disabled', '');\n } else {\n undo.removeAttribute('disabled');\n }\n\n if (lastStep) {\n if (step >= lastStep) {\n redo.setAttribute('disabled', '');\n } else {\n redo.removeAttribute('disabled');\n }\n } else {\n redo.setAttribute('disabled', '');\n }\n }\n\n /**\n * Go to the previous step if possible.\n */\n undo() {\n this.history.prev();\n this.refreshHistoryButtons();\n this.render();\n }\n\n /**\n * Go to the next step if possible.\n */\n redo() {\n this.history.next();\n this.refreshHistoryButtons();\n this.render();\n }\n\n /**\n * Change currently selected drawing tool.\n * @param {string} [tool]\n */\n selectTool(tool = this.tool) {\n // Remove active class from all the buttons.\n this.container.querySelectorAll('.icon-button.active').forEach((el) => {\n el.classList.remove('active');\n });\n // Add active class to the actual tool button.\n this.buttons.tools[tool].classList.add('active');\n this.tool = tool;\n }\n\n /**\n * Readraw canvas in case of some changes.\n */\n render() {\n // Get all actual layouts from history with current step layouts.\n const layouts = [\n ...this.getLayoutsFromHistory(),\n ...this.layouts,\n ];\n\n // This is last time rendered layouts.\n const previousLayouts = this.drawer.layouts;\n\n // Length of layouts has changed. Redraw the canvas.\n if (layouts.length !== previousLayouts.length) {\n this.drawer.update(layouts);\n return;\n }\n // If current step layouts array is empty, and layouts from the history are the same length as\n // already drown layouts, consider there is no changes.\n if (!this.layouts.length) {\n return;\n }\n\n // Make sure that last rendered layout is the same coords as already drown last layout (could\n // be changed at the [mousemove] step).\n const lastPreviousLayout = previousLayouts[previousLayouts.length - 1];\n const lastCurrentLayout = this.layouts[this.layouts.length - 1];\n const changes = !lastCurrentLayout.compare(lastPreviousLayout);\n\n // We have the same amount of layouts, but different coords for the last ones. Redraw.\n if (changes) {\n this.drawer.update(layouts);\n }\n }\n}\n\nexport default DrawerApp;\n","import DrawerApp from './App/App';\n\nrequire('../index.css');\n\ndocument.addEventListener('DOMContentLoaded', () => {\n const container = document.querySelector('#app');\n const App = new DrawerApp({ container });\n App.init();\n});\n"],"sourceRoot":""}