UNPKG

@disjukr/croquis-js

Version:
135 lines (134 loc) 4.55 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var stylus_1 = require("../stylus"); var misc_1 = require("../misc"); exports.defaultBrushConfig = Object.freeze({ ctx: misc_1.dummyCanvasContext, color: '#000', size: 10, }); exports.stroke = { resume: function (config, prevState) { return getDrawingContext(exports.stroke, config, prevState); }, down: function (config, curr) { var state = { prev: stylus_1.cloneStylusState(curr), }; var drawingContext = getDrawingContext(exports.stroke, config, state); if (curr.pressure <= 0) return drawingContext; config.ctx.save(); config.ctx.fillStyle = config.color; drawCircle(config.ctx, stylusStateToCircle(curr, config.size)); config.ctx.restore(); return drawingContext; }, }; function getDrawingContext(stroke, config, state) { return { getConfig: function (target) { if (!target || target === stroke) return config; throw undefined; }, getState: function (target) { if (!target || target === stroke) return state; throw undefined; }, move: function (curr) { var c1 = stylusStateToCircle(state.prev, config.size); var c2 = stylusStateToCircle(curr, config.size); config.ctx.save(); config.ctx.fillStyle = config.color; drawCapsule(config.ctx, c1, c2); stylus_1.copyStylusState(state.prev, curr); config.ctx.restore(); }, up: function (curr) { var c1 = stylusStateToCircle(state.prev, config.size); var c2 = stylusStateToCircle(curr, config.size); config.ctx.save(); config.ctx.fillStyle = config.color; drawCapsule(config.ctx, c1, c2); stylus_1.copyStylusState(state.prev, curr); config.ctx.restore(); return { // boundingRect: state.boundingRect, }; }, }; } function stylusStateToCircle(stylusState, size) { return { x: stylusState.x, y: stylusState.y, r: stylusState.pressure * size * 0.5 }; } function drawCapsule(ctx, c1, c2) { var c1IsBig = c1.r > c2.r; var big = c1IsBig ? c1 : c2; var small = c1IsBig ? c2 : c1; var d = Math.sqrt(Math.pow((c2.x - c1.x), 2) + Math.pow((c2.y - c1.y), 2)); if (big.r > small.r + d) return drawCircle(ctx, big); if (big.r === small.r) { drawCapsuleCase1(ctx, big, small); } else { drawCapsuleCase2(ctx, big, small); } } function drawCircle(ctx, circle) { ctx.beginPath(); ctx.moveTo(circle.x + circle.r, circle.y); ctx.arc(circle.x, circle.y, circle.r, 0, Math.PI * 2); ctx.closePath(); ctx.fill(); } var quarter = Math.PI / 2; function drawCapsuleCase1(ctx, c1, c2) { drawCircle(ctx, c1); drawCircle(ctx, c2); var c = Math.atan2(c2.y - c1.y, c2.x - c1.x); var i = c - quarter; var j = c + quarter; var idx = Math.cos(i) * c2.r; var idy = Math.sin(i) * c2.r; var jdx = Math.cos(j) * c2.r; var jdy = Math.sin(j) * c2.r; ctx.beginPath(); ctx.moveTo(c2.x + idx, c2.y + idy); ctx.lineTo(c1.x + idx, c1.y + idy); ctx.lineTo(c1.x + jdx, c1.y + jdy); ctx.lineTo(c2.x + jdx, c2.y + jdy); ctx.closePath(); ctx.fill(); } function drawCapsuleCase2(ctx, c1, c2) { drawCircle(ctx, c1); drawCircle(ctx, c2); var x = c2.x - c1.x || 1e-9; var y = c2.y - c1.y; var r = c1.r - c2.r; var r2 = r * r; var x2 = x * x; var x3 = x * x * x; var y2 = y * y; var ax = (x === 0 ? c1.r : (y * Math.sqrt(r2 * x2 * (-r2 + x2 + y2)) + r2 * x2) / (x3 + x * y2)) + c1.x; var ay = (r2 * y - Math.sqrt(r2 * x2 * (-r2 + x2 + y2))) / (x2 + y2) + c1.y; var bx = (x === 0 ? -c1.r : (-(y * Math.sqrt(r2 * x2 * (-r2 + x2 + y2))) + r2 * x2) / (x3 + x * y2)) + c1.x; var by = (r2 * y + Math.sqrt(r2 * x2 * (-r2 + x2 + y2))) / (x2 + y2) + c1.y; var i = Math.atan2(ay - c1.y, ax - c1.x); var j = Math.atan2(by - c1.y, bx - c1.x); var idx = Math.cos(i) * c2.r; var idy = Math.sin(i) * c2.r; var jdx = Math.cos(j) * c2.r; var jdy = Math.sin(j) * c2.r; ctx.beginPath(); ctx.moveTo(c2.x + idx, c2.y + idy); ctx.lineTo(ax + idx, ay + idy); ctx.lineTo(bx + jdx, by + jdy); ctx.lineTo(c2.x + jdx, c2.y + jdy); ctx.closePath(); ctx.fill(); }