import { filterNull } from './methodsExtend' export function drawLine (ctx, lineBegin, lineEnd, lineWidth = 2, lineColor = '#000', dashArray = [10, 0]) { if (!ctx || !lineBegin || !lineEnd) return ctx.beginPath() ctx.moveTo(...lineBegin) ctx.lineTo(...lineEnd) ctx.closePath() ctx.lineWidth = lineWidth ctx.strokeStyle = lineColor ctx.setLineDash(dashArray) ctx.stroke() } 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], newPath = false) { if (!ctx || !points.length) return drawPolylinePath(ctx, points, close, newPath) ctx.lineWidth = lineWidth ctx.strokeStyle = lineColor ctx.setLineDash(dashArray) ctx.stroke() } export function drawSmoothlinePath (ctx, points, close = false, newPath = false, moveTo = false) { const canDrawPoints = filterNull(points) if (!ctx || canDrawPoints.length < 2) return close && canDrawPoints.push(canDrawPoints[0]) newPath && ctx.beginPath() if (canDrawPoints.length === 2) { ctx.moveTo(...canDrawPoints[0]) ctx.lineTo(...canDrawPoints[1]) return } const lastPointIndex = canDrawPoints.length - 1 moveTo && ctx.moveTo(...canDrawPoints[0]) canDrawPoints.forEach((t, i) => (i !== lastPointIndex) && drawBezierCurveLinePath(ctx, ...getBezierCurveLineControlPoints(canDrawPoints, i, false), canDrawPoints[i + 1])) } 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]) ], [ 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], newPath = false, moveTo = false) { if (!ctx || points.length < 3) return drawSmoothlinePath(ctx, points, close, newPath, moveTo) ctx.lineWidth = lineWidth ctx.strokeStyle = lineColor ctx.setLineDash(dashArray) ctx.stroke() } export function drawBezierCurveLinePath (ctx, ctlBefore, ctlAfter, end, newPath = false) { if (!ctx || !ctlBefore || !ctlAfter || !end) return newPath && ctx.beginPath() ctx.bezierCurveTo(...ctlBefore, ...ctlAfter, ...end) } export function drawPoints (ctx, points, radius = 10, color = '#000') { points.forEach(point => { if (!point) return ctx.beginPath() ctx.arc(...point, radius, 0, Math.PI * 2) ctx.fillStyle = color ctx.fill() }) } 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 } export function getRadialGradientColor (ctx, origin, begin = 0, end = 100, color) { if (!ctx || !origin || !color.length) return let colors = color typeof colors === 'string' && (colors = [color, color]) const radialGradientColor = ctx.createRadialGradient(...origin, begin, ...origin, end) const colorGap = 1 / (colors.length - 1) colors.forEach((c, i) => radialGradientColor.addColorStop(colorGap * i, c)) return radialGradientColor } export function getCircleRadianPoint (x, y, radius, radian) { const { sin, cos } = Math return [x + cos(radian) * radius, y + sin(radian) * radius] } export function getTextsWidth (ctx, texts) { if (!ctx || !texts) return return texts.map(text => ctx.measureText(text).width) } const canvas = { drawLine, drawPolylinePath, drawPolyline, getBezierCurveLineControlPoints, drawSmoothlinePath, drawSmoothline, drawBezierCurveLinePath, drawPoints, getLinearGradientColor, getRadialGradientColor, getCircleRadianPoint, getTextsWidth } export default function (Vue) { Vue.prototype.canvas = canvas }