diff --git a/src/plugins/canvasExtend.js b/src/plugins/canvasExtend.js index 040194f..15ec7a7 100644 --- a/src/plugins/canvasExtend.js +++ b/src/plugins/canvasExtend.js @@ -1,3 +1,5 @@ +import { filterNull } from './methodsExtend' + export function drawLine (ctx, lineBegin, lineEnd, lineWidth = 2, lineColor = '#000', dashArray = [10, 0]) { if (!ctx || !lineBegin || !lineEnd) return @@ -15,19 +17,21 @@ export function drawLine (ctx, lineBegin, lineEnd, lineWidth = 2, lineColor = '# ctx.stroke() } -export function drawPolylinePath (ctx, points, close = false) { +export function drawPolylinePath (ctx, points, close = false, newPath = false) { if (!ctx || !points.length) return + newPath && ctx.beginPath() + points.forEach((point, i) => point && (i === 0 ? ctx.moveTo(...point) : ctx.lineTo(...point))) close && ctx.lineTo(...points[0]) } -export function drawPolyline (ctx, points, lineWidth = 2, lineColor = '#000', close = false, dashArray = [10, 0]) { +export function drawPolyline (ctx, points, lineWidth = 2, lineColor = '#000', close = false, dashArray = [10, 0], newPath = false) { if (!ctx || !points.length) return - drawPolylinePath(ctx, points, close) + drawPolylinePath(ctx, points, close, newPath) ctx.lineWidth = lineWidth ctx.strokeStyle = lineColor @@ -36,46 +40,74 @@ export function drawPolyline (ctx, points, lineWidth = 2, lineColor = '#000', cl ctx.stroke() } -export function drawSmoothlinePath (ctx, points, close = false) { - if (!ctx || !points.length) return +export function drawSmoothlinePath (ctx, points, close = false, newPath = false, moveTo = false) { + if (!ctx || points.length < 3) return - const pointsNum = points.length + const canDrawPoints = filterNull(points) - points.forEach((point, i) => { - if (i === 0) { + close && canDrawPoints.push(canDrawPoints[0]) - } if (i === pointsNum - 1) { + const lastPointIndex = canDrawPoints.length - 1 - } else { + newPath && ctx.beginPath() - } - }) + moveTo && ctx.moveTo(...canDrawPoints[0]) + + canDrawPoints.forEach((t, i) => + (i !== lastPointIndex) && drawBezierCurveLinePath(ctx, + ...getBezierCurveLineControlPoints(canDrawPoints, i, false), + canDrawPoints[i + 1])) } -export function getBezierCurveLineControlPoints (pointBefore, pointMiddle, pointAfter) { - const [offsetA, offsetB] = [6, 6] +export function getBezierCurveLineControlPoints (points, index, close = false, offsetA = 0.25, offsetB = 0.25) { + const pointNum = points.length + + if (pointNum < 3 || index >= pointNum) return + + let beforePointIndex = index - 1 + beforePointIndex < 0 && (beforePointIndex = (close ? pointNum + beforePointIndex : 0)) + + let afterPointIndex = index + 1 + afterPointIndex >= pointNum && (afterPointIndex = (close ? afterPointIndex - pointNum : pointNum - 1)) + + let afterNextPointIndex = index + 2 + afterNextPointIndex >= pointNum && (afterNextPointIndex = (close ? afterNextPointIndex - pointNum : pointNum - 1)) + + const pointBefore = points[beforePointIndex] + const pointMiddle = points[index] + const pointAfter = points[afterPointIndex] + const pointAfterNext = points[afterNextPointIndex] return [ [ - pointMiddle[0] + offsetA(pointAfter[0] - pointBefore[0]), - pointMiddle[1] + offsetA(pointAfter[1] - pointBefore[1]) + pointMiddle[0] + offsetA * (pointAfter[0] - pointBefore[0]), + pointMiddle[1] + offsetA * (pointAfter[1] - pointBefore[1]) ], [ - (pointAfter[0] - offsetB()) + pointAfter[0] - offsetB * (pointAfterNext[0] - pointMiddle[0]), + pointAfter[1] - offsetB * (pointAfterNext[1] - pointMiddle[1]) ] ] } -export function drawSmoothline (ctx, points, lineWidth = 2, lineColor = '#000', close = false, dashArray = [10, 0]) { - if (!ctx || !points.length) return +export function drawSmoothline (ctx, points, lineWidth = 2, lineColor = '#000', close = false, dashArray = [10, 0], newPath = false, moveTo = false) { + if (!ctx || points.length < 3) return - drawSmoothlinePath() + drawSmoothlinePath(ctx, points, close, newPath, moveTo) + + ctx.lineWidth = lineWidth + ctx.strokeStyle = lineColor + ctx.setLineDash(dashArray) + + ctx.stroke() } -export function drawBezierCurveLinePath (ctx, points) { - if (!ctx || !points.length) return +export function drawBezierCurveLinePath (ctx, ctlBefore, ctlAfter, end, newPath = false) { + if (!ctx || !ctlBefore || !ctlAfter || !end) return - points.forEach(point => ctx.bezierCurveTo(...point)) + newPath && ctx.beginPath() + + ctx.bezierCurveTo(...ctlBefore, ...ctlAfter, ...end) } export function drawPoints (ctx, points, radius = 10, color = '#000') { @@ -92,13 +124,32 @@ export function drawPoints (ctx, points, radius = 10, color = '#000') { }) } +export function getLinearGradientColor (ctx, begin, end, color) { + if (!ctx || !begin || !end || !color.length) return + + let colors = color + + typeof colors === 'string' && (colors = [color, color]) + + const linearGradientColor = ctx.createLinearGradient(...begin, ...end) + + const colorGap = 1 / (colors.length - 1) + + colors.forEach((c, i) => linearGradientColor.addColorStop(colorGap * i, c)) + + return linearGradientColor +} + const canvas = { drawLine, drawPolylinePath, drawPolyline, + getBezierCurveLineControlPoints, drawSmoothlinePath, drawSmoothline, - drawPoints + drawBezierCurveLinePath, + drawPoints, + getLinearGradientColor } export default function (Vue) {