{"version":3,"sources":["webpack://Atrament/webpack/bootstrap","webpack://Atrament/./index.js","webpack://Atrament/./src/atrament.js","webpack://Atrament/./src/mouse.js","webpack://Atrament/./src/constants.js","webpack://Atrament/./src/events.js","webpack://Atrament/./src/pixels.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","require","Mouse","Point","Constants","AtramentEventTarget","Pixels","DrawingMode","DRAW","ERASE","FILL","DISABLED","PathDrawingModes","selector","config","window","Error","Node","tagName","canvas","document","querySelector","width","height","mouse","mouseMove","event","cancelable","preventDefault","rect","getBoundingClientRect","position","changedTouches","x","offsetX","y","offsetY","clientX","left","clientY","top","down","includes","draw","previous","newX","newY","_dirty","fireDirty","set","mouseDown","beginStroke","fill","mouseUp","e","nx","ny","endStroke","addEventListener","destroy","clear","removeEventListener","context","getContext","globalCompositeOperation","globalAlpha","strokeStyle","color","lineCap","lineJoin","translate","_filling","_fillStack","recordStrokes","strokeMemory","smoothing","initialSmoothingFactor","_thickness","initialThickness","_targetThickness","_weight","_maxWeight","weightSpread","_mode","adaptiveStroke","forEach","undefined","this","beginPath","moveTo","strokeTimestamp","performance","now","push","point","time","dispatchEvent","closePath","stroke","points","slice","weight","prevX","prevY","rawDist","lineDistance","smoothingFactor","Math","min","minSmoothingFactor","procX","procY","dist","minLineThickness","lineThicknessRange","thicknessIncrement","lineWidth","quadraticCurveTo","isDirty","clearRect","toDataURL","startColor","Array","from","getImageData","data","setTimeout","_floodFill","floodFillInterval","_startX","_startY","startX","floor","startY","canvasWidth","canvasHeight","pixelStack","fillColor","hexToRgb","colorLayer","alpha","colorPixel","matchColor","matchFillColor","length","newPos","pop","pixelPos","reachLeft","reachRight","putImageData","shift","w","C","maxLineThickness","eventListeners","Map","eventName","handler","handlers","Set","add","x1","y1","x2","y2","xs","pow","ys","sqrt","hexColor","match","parseInt","compR","compG","compB","compA","g","b","a","fillR","fillG","fillB","matcher"],"mappings":"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","file":"atrament.min.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 = 0);\n","module.exports = require('./src/atrament.js');\n","const { Mouse, Point } = require('./mouse.js');\nconst Constants = require('./constants.js');\nconst { AtramentEventTarget } = require('./events.js');\nconst Pixels = require('./pixels.js');\n\nconst DrawingMode = {\n DRAW: 'draw',\n ERASE: 'erase',\n FILL: 'fill',\n DISABLED: 'disabled'\n};\n\nconst PathDrawingModes = [DrawingMode.DRAW, DrawingMode.ERASE];\n\nmodule.exports = class Atrament extends AtramentEventTarget {\n constructor(selector, config = {}) {\n if (typeof window === 'undefined') {\n throw new Error('Looks like we\\'re not running in a browser');\n }\n\n super();\n\n // get canvas element\n if (selector instanceof window.Node && selector.tagName === 'CANVAS') this.canvas = selector;\n else if (typeof selector === 'string') this.canvas = document.querySelector(selector);\n else throw new Error(`can't look for canvas based on '${selector}'`);\n if (!this.canvas) throw new Error('canvas not found');\n\n // set external canvas params\n this.canvas.width = config.width || this.canvas.width;\n this.canvas.height = config.height || this.canvas.height;\n\n // create a mouse object\n this.mouse = new Mouse();\n\n // mousemove handler\n const mouseMove = (event) => {\n if (event.cancelable) {\n event.preventDefault();\n }\n\n const rect = this.canvas.getBoundingClientRect();\n const position = event.changedTouches && event.changedTouches[0] || event;\n let x = position.offsetX;\n let y = position.offsetY;\n\n if (typeof x === 'undefined') {\n x = position.clientX - rect.left;\n }\n if (typeof y === 'undefined') {\n y = position.clientY - rect.top;\n }\n\n const { mouse } = this;\n // draw if we should draw\n if (mouse.down && PathDrawingModes.includes(this.mode)) {\n const { x: newX, y: newY } = this.draw(x, y, mouse.previous.x, mouse.previous.y);\n\n if (!this._dirty && this.mode === DrawingMode.DRAW && (x !== mouse.x || y !== mouse.y)) {\n this._dirty = true;\n this.fireDirty();\n }\n\n mouse.set(x, y);\n mouse.previous.set(newX, newY);\n }\n else {\n mouse.set(x, y);\n }\n };\n\n // mousedown handler\n const mouseDown = (event) => {\n if (event.cancelable) {\n event.preventDefault();\n }\n // update position just in case\n mouseMove(event);\n\n // if we are filling - fill and return\n if (this.mode === DrawingMode.FILL) {\n this.fill();\n return;\n }\n // remember it\n const { mouse } = this;\n mouse.previous.set(mouse.x, mouse.y);\n mouse.down = true;\n\n this.beginStroke(mouse.previous.x, mouse.previous.y);\n };\n\n const mouseUp = (e) => {\n if (this.mode === DrawingMode.FILL) {\n return;\n }\n\n const { mouse } = this;\n\n if (!mouse.down) {\n return;\n }\n\n const position = e.changedTouches && e.changedTouches[0] || e;\n const x = position.offsetX;\n const y = position.offsetY;\n mouse.down = false;\n\n if (mouse.x === x && mouse.y === y && PathDrawingModes.includes(this.mode)) {\n const { x: nx, y: ny } = this.draw(mouse.x, mouse.y, mouse.previous.x, mouse.previous.y);\n mouse.previous.set(nx, ny);\n }\n\n this.endStroke(mouse.x, mouse.y);\n };\n\n // attach listeners\n this.canvas.addEventListener('mousemove', mouseMove);\n this.canvas.addEventListener('mousedown', mouseDown);\n document.addEventListener('mouseup', mouseUp);\n this.canvas.addEventListener('touchstart', mouseDown);\n this.canvas.addEventListener('touchend', mouseUp);\n this.canvas.addEventListener('touchmove', mouseMove);\n\n // helper for destroying Atrament (removing event listeners)\n this.destroy = () => {\n this.clear();\n this.canvas.removeEventListener('mousemove', mouseMove);\n this.canvas.removeEventListener('mousedown', mouseDown);\n document.removeEventListener('mouseup', mouseUp);\n this.canvas.removeEventListener('touchstart', mouseDown);\n this.canvas.removeEventListener('touchend', mouseUp);\n this.canvas.removeEventListener('touchmove', mouseMove);\n };\n\n // set internal canvas params\n this.context = this.canvas.getContext('2d');\n this.context.globalCompositeOperation = 'source-over';\n this.context.globalAlpha = 1;\n this.context.strokeStyle = config.color || 'rgba(0,0,0,1)';\n this.context.lineCap = 'round';\n this.context.lineJoin = 'round';\n this.context.translate(0.5, 0.5);\n\n this._filling = false;\n this._fillStack = [];\n\n // set drawing params\n this.recordStrokes = false;\n this.strokeMemory = [];\n\n this.smoothing = Constants.initialSmoothingFactor;\n this._thickness = Constants.initialThickness;\n this._targetThickness = this._thickness;\n this._weight = this._thickness;\n this._maxWeight = this._thickness + Constants.weightSpread;\n\n this._mode = DrawingMode.DRAW;\n this.adaptiveStroke = true;\n\n // update from config object\n ['weight', 'smoothing', 'adaptiveStroke', 'mode']\n .forEach(key => config[key] === undefined ? 0 : this[key] = config[key]);\n }\n\n /**\n * Begins a stroke at a given position\n *\n * @param {number} x\n * @param {number} y\n */\n beginStroke(x, y) {\n this.context.beginPath();\n this.context.moveTo(x, y);\n\n if (this.recordStrokes) {\n this.strokeTimestamp = performance.now();\n this.strokeMemory.push({ point: new Point(x, y), time: performance.now() - this.strokeTimestamp });\n }\n this.dispatchEvent('strokestart', { x, y });\n }\n\n /**\n * Ends a stroke at a given position\n *\n * @param {number} x\n * @param {number} y\n */\n endStroke(x, y) {\n this.context.closePath();\n\n if (this.recordStrokes) {\n this.strokeMemory.push({ point: new Point(x, y), time: performance.now() - this.strokeTimestamp });\n }\n this.dispatchEvent('strokeend', { x, y });\n\n if (this.recordStrokes) {\n const stroke = {\n points: this.strokeMemory.slice(),\n mode: this.mode,\n weight: this.weight,\n smoothing: this.smoothing,\n color: this.color,\n adaptiveStroke: this.adaptiveStroke\n };\n\n this.dispatchEvent('strokerecorded', { stroke });\n }\n this.strokeMemory = [];\n delete (this.strokeTimestamp);\n }\n\n /**\n * Draws a smooth quadratic curve with adaptive stroke thickness\n * between two points\n *\n * @param {number} x current X coordinate\n * @param {number} y current Y coordinate\n * @param {number} prevX previous X coordinate\n * @param {number} prevY previous Y coordinate\n */\n draw(x, y, prevX, prevY) {\n if (this.recordStrokes) {\n this.strokeMemory.push({ point: new Point(x, y), time: performance.now() - this.strokeTimestamp });\n }\n\n const { context } = this;\n // calculate distance from previous point\n const rawDist = Pixels.lineDistance(x, y, prevX, prevY);\n\n // now, here we scale the initial smoothing factor by the raw distance\n // this means that when the mouse moves fast, there is more smoothing\n // and when we're drawing small detailed stuff, we have more control\n // also we hard clip at 1\n const smoothingFactor = Math.min(Constants.minSmoothingFactor, this.smoothing + (rawDist - 60) / 3000);\n\n // calculate processed coordinates\n const procX = x - (x - prevX) * smoothingFactor;\n const procY = y - (y - prevY) * smoothingFactor;\n\n // recalculate distance from previous point, this time relative to the smoothed coords\n const dist = Pixels.lineDistance(procX, procY, prevX, prevY);\n\n if (this.adaptiveStroke) {\n // calculate target thickness based on the new distance\n this._targetThickness = (dist - Constants.minLineThickness)\n / Constants.lineThicknessRange * (this._maxWeight - this._weight) + this._weight;\n // approach the target gradually\n if (this._thickness > this._targetThickness) {\n this._thickness -= Constants.thicknessIncrement;\n }\n else if (this._thickness < this._targetThickness) {\n this._thickness += Constants.thicknessIncrement;\n }\n // set line width\n context.lineWidth = this._thickness;\n }\n else {\n // line width is equal to default weight\n context.lineWidth = this._weight;\n }\n\n // draw using quad interpolation\n context.quadraticCurveTo(prevX, prevY, procX, procY);\n context.stroke();\n\n return { x: procX, y: procY };\n }\n\n get color() {\n return this.context.strokeStyle;\n }\n\n set color(c) {\n if (typeof c !== 'string') throw new Error('wrong argument type');\n this.context.strokeStyle = c;\n }\n\n get weight() {\n return this._weight;\n }\n\n set weight(w) {\n if (typeof w !== 'number') throw new Error('wrong argument type');\n this._weight = w;\n this._thickness = w;\n this._targetThickness = w;\n this._maxWeight = w + Constants.weightSpread;\n }\n\n get mode() {\n return this._mode;\n }\n\n set mode(m) {\n if (typeof m !== 'string') throw new Error('wrong argument type');\n switch (m) {\n case DrawingMode.ERASE:\n this._mode = DrawingMode.ERASE;\n this.context.globalCompositeOperation = 'destination-out';\n break;\n case DrawingMode.FILL:\n this._mode = DrawingMode.FILL;\n this.context.globalCompositeOperation = 'source-over';\n break;\n case DrawingMode.DISABLED:\n this._mode = DrawingMode.DISABLED;\n break;\n default:\n this._mode = DrawingMode.DRAW;\n this.context.globalCompositeOperation = 'source-over';\n break;\n }\n }\n\n isDirty() {\n return !!this._dirty;\n }\n\n fireDirty() {\n this.dispatchEvent('dirty');\n }\n\n clear() {\n if (!this.isDirty) {\n return;\n }\n\n this._dirty = false;\n this.dispatchEvent('clean');\n\n // make sure we're in the right compositing mode, and erase everything\n if (this.mode === DrawingMode.ERASE) {\n this.mode = DrawingMode.DRAW;\n this.context.clearRect(-10, -10, this.canvas.width + 20, this.canvas.height + 20);\n this.mode = DrawingMode.ERASE;\n }\n else {\n this.context.clearRect(-10, -10, this.canvas.width + 20, this.canvas.height + 20);\n }\n }\n\n toImage() {\n return this.canvas.toDataURL();\n }\n\n fill() {\n const { mouse } = this;\n const { context } = this;\n // converting to Array because Safari 9\n const startColor = Array.from(context.getImageData(mouse.x, mouse.y, 1, 1).data);\n\n if (!this._filling) {\n const { x, y } = mouse;\n this.dispatchEvent('fillstart', { x, y });\n this._filling = true;\n setTimeout(() => { this._floodFill(mouse.x, mouse.y, startColor); }, Constants.floodFillInterval);\n }\n else {\n this._fillStack.push([\n mouse.x,\n mouse.y,\n startColor\n ]);\n }\n }\n\n _floodFill(_startX, _startY, startColor) {\n const { context } = this;\n const startX = Math.floor(_startX);\n const startY = Math.floor(_startY);\n const canvasWidth = context.canvas.width;\n const canvasHeight = context.canvas.height;\n const pixelStack = [[startX, startY]];\n // hex needs to be trasformed to rgb since colorLayer accepts RGB\n const fillColor = Pixels.hexToRgb(this.color);\n // Need to save current context with colors, we will update it\n const colorLayer = context.getImageData(0, 0, context.canvas.width, context.canvas.height);\n const alpha = Math.min(context.globalAlpha * 10 * 255, 255);\n const colorPixel = Pixels.colorPixel(colorLayer.data, ...fillColor, startColor, alpha);\n const matchColor = Pixels.matchColor(colorLayer.data, ...startColor);\n const matchFillColor = Pixels.matchColor(colorLayer.data, ...[...fillColor, 255]);\n\n // check if we're trying to fill with the same colour, if so, stop\n if (matchFillColor((startY * context.canvas.width + startX) * 4)) {\n this._filling = false;\n this.dispatchEvent('fillend', {});\n return;\n }\n\n while (pixelStack.length) {\n const newPos = pixelStack.pop();\n const x = newPos[0];\n let y = newPos[1];\n\n let pixelPos = (y * canvasWidth + x) * 4;\n\n while (y-- >= 0 && matchColor(pixelPos)) {\n pixelPos -= canvasWidth * 4;\n }\n pixelPos += canvasWidth * 4;\n\n ++y;\n\n let reachLeft = false;\n let reachRight = false;\n\n while (y++ < canvasHeight - 1 && matchColor(pixelPos)) {\n colorPixel(pixelPos);\n\n if (x > 0) {\n if (matchColor(pixelPos - 4)) {\n if (!reachLeft) {\n pixelStack.push([x - 1, y]);\n reachLeft = true;\n }\n }\n else if (reachLeft) {\n reachLeft = false;\n }\n }\n\n if (x < canvasWidth - 1) {\n if (matchColor(pixelPos + 4)) {\n if (!reachRight) {\n pixelStack.push([x + 1, y]);\n reachRight = true;\n }\n }\n else if (reachRight) {\n reachRight = false;\n }\n }\n\n pixelPos += canvasWidth * 4;\n }\n }\n\n // Update context with filled bucket!\n context.putImageData(colorLayer, 0, 0);\n\n if (this._fillStack.length) {\n this._floodFill(...this._fillStack.shift());\n }\n else {\n this._filling = false;\n this.dispatchEvent('fillend', {});\n }\n }\n};\n","// make a class for Point\nclass Point {\n constructor(x, y) {\n this.x = x;\n this.y = y;\n }\n\n set(x, y) {\n this.x = x;\n this.y = y;\n }\n}\n\n// make a class for the mouse data\nclass Mouse extends Point {\n constructor() {\n super(0, 0);\n this.down = false;\n this.previous = new Point(0, 0);\n }\n}\n\nmodule.exports = { Mouse, Point };\n","const C = {};\nC.floodFillInterval = 100;\nC.maxLineThickness = 50;\nC.minLineThickness = 1;\nC.lineThicknessRange = C.maxLineThickness - C.minLineThickness;\nC.thicknessIncrement = 0.5;\nC.minSmoothingFactor = 0.87;\nC.initialSmoothingFactor = 0.85;\nC.weightSpread = 10;\nC.initialThickness = 2;\n\nmodule.exports = C;\n","class AtramentEventTarget {\n constructor() {\n this.eventListeners = new Map();\n }\n\n addEventListener(eventName, handler) {\n const handlers = this.eventListeners.get(eventName) || new Set();\n handlers.add(handler);\n this.eventListeners.set(eventName, handlers);\n }\n\n removeEventListener(eventName, handler) {\n const handlers = this.eventListeners.get(eventName);\n if (!handlers) return;\n handlers.delete(handler);\n }\n\n dispatchEvent(eventName, data) {\n const handlers = this.eventListeners.get(eventName);\n if (!handlers) return;\n [...handlers].forEach(handler => handler(data));\n }\n}\n\nmodule.exports = { AtramentEventTarget };\n","exports.lineDistance = (x1, y1, x2, y2) => {\n // calculate euclidean distance between (x1, y1) and (x2, y2)\n const xs = Math.pow(x2 - x1, 2);\n const ys = Math.pow(y2 - y1, 2);\n return Math.sqrt(xs + ys);\n};\n\nexports.hexToRgb = (hexColor) => {\n // Since input type color provides hex and ImageData accepts RGB need to transform\n const m = hexColor.match(/^#?([\\da-f]{2})([\\da-f]{2})([\\da-f]{2})$/i);\n return [\n parseInt(m[1], 16),\n parseInt(m[2], 16),\n parseInt(m[3], 16)\n ];\n};\n\nexports.matchColor = (data, compR, compG, compB, compA) => (pixelPos) => {\n // Pixel color equals comp color?\n const r = data[pixelPos];\n const g = data[pixelPos + 1];\n const b = data[pixelPos + 2];\n const a = data[pixelPos + 3];\n\n return (r === compR && g === compG && b === compB && a === compA);\n};\n\nexports.colorPixel = (data, fillR, fillG, fillB, startColor, alpha) => {\n const matcher = exports.matchColor(data, ...startColor);\n\n return (pixelPos) => {\n // Update fill color in matrix\n data[pixelPos] = fillR;\n data[pixelPos + 1] = fillG;\n data[pixelPos + 2] = fillB;\n data[pixelPos + 3] = alpha;\n\n if (!matcher(pixelPos + 4)) {\n data[pixelPos + 4] = data[pixelPos + 4] * 0.01 + fillR * 0.99;\n data[pixelPos + 4 + 1] = data[pixelPos + 4 + 1] * 0.01 + fillG * 0.99;\n data[pixelPos + 4 + 2] = data[pixelPos + 4 + 2] * 0.01 + fillB * 0.99;\n data[pixelPos + 4 + 3] = data[pixelPos + 4 + 3] * 0.01 + alpha * 0.99;\n }\n\n if (!matcher(pixelPos - 4)) {\n data[pixelPos - 4] = data[pixelPos - 4] * 0.01 + fillR * 0.99;\n data[pixelPos - 4 + 1] = data[pixelPos - 4 + 1] * 0.01 + fillG * 0.99;\n data[pixelPos - 4 + 2] = data[pixelPos - 4 + 2] * 0.01 + fillB * 0.99;\n data[pixelPos - 4 + 3] = data[pixelPos - 4 + 3] * 0.01 + alpha * 0.99;\n }\n };\n};\n"],"sourceRoot":""}