| var sprintf = require('./sprintf'); |
| var roundNumber = require("./round-number"); |
|
|
| function drawTie(renderer, params, linestartx, lineendx, selectables) { |
| layout(params, linestartx, lineendx); |
|
|
| var klass = ''; |
| if (params.anchor1) { |
| klass += 'abcjs-start-m' + params.anchor1.parent.counters.measure + '-n' + params.anchor1.parent.counters.note; |
| } else |
| klass += 'abcjs-start-edge'; |
| if (params.anchor2) { |
| klass += ' abcjs-end-m' + params.anchor2.parent.counters.measure + '-n' + params.anchor2.parent.counters.note; |
| } else |
| klass += ' abcjs-end-edge'; |
| if (params.hint) |
| klass = "abcjs-hint"; |
| var fudgeY = params.fixedY ? 1.5 : 0; |
| var el = drawArc(renderer, params.startX, params.endX, params.startY + fudgeY, params.endY + fudgeY, params.above, klass, params.isTie, params.dotted); |
| var startChar = -1 |
| |
| if (params.anchor1 && !params.isTie) |
| startChar = params.anchor1.parent.abcelem.startChar - 1 |
| var endChar = -1 |
| if (params.anchor2 && !params.isTie) |
| endChar = params.anchor2.parent.abcelem.endChar + 1 |
|
|
| selectables.wrapSvgEl({ el_type: "slur", startChar: startChar, endChar: endChar }, el); |
| return [el]; |
| } |
|
|
| |
| var layout = function (params, lineStartX, lineEndX) { |
| |
|
|
| |
| if (!params.anchor1 || !params.anchor2) |
| params.isTie = true; |
| else if (params.anchor1.pitch === params.anchor2.pitch && params.internalNotes.length === 0) |
| params.isTie = true; |
| else |
| params.isTie = false; |
|
|
| if (params.isTie) { |
| params.calcTieDirection(); |
| params.calcX(lineStartX, lineEndX); |
| params.calcTieY(); |
|
|
| } else { |
| params.calcSlurDirection(); |
| params.calcX(lineStartX, lineEndX); |
| params.calcSlurY(); |
| } |
| params.avoidCollisionAbove(); |
| }; |
|
|
| var drawArc = function (renderer, x1, x2, pitch1, pitch2, above, klass, isTie, dotted) { |
| |
| var spacing = isTie ? 1.2 : 1.5; |
|
|
| x1 = roundNumber(x1 + 6); |
| x2 = roundNumber(x2 + 4); |
| pitch1 = pitch1 + ((above) ? spacing : -spacing); |
| pitch2 = pitch2 + ((above) ? spacing : -spacing); |
| var y1 = roundNumber(renderer.calcY(pitch1)); |
| var y2 = roundNumber(renderer.calcY(pitch2)); |
|
|
| |
| var dx = x2 - x1; |
| var dy = y2 - y1; |
| var norm = Math.sqrt(dx * dx + dy * dy); |
| var ux = dx / norm; |
| var uy = dy / norm; |
|
|
| var flatten = norm / 3.5; |
| var maxFlatten = isTie ? 10 : 25; |
| var curve = ((above) ? -1 : 1) * Math.min(maxFlatten, Math.max(4, flatten)); |
|
|
| var controlx1 = roundNumber(x1 + flatten * ux - curve * uy); |
| var controly1 = roundNumber(y1 + flatten * uy + curve * ux); |
| var controlx2 = roundNumber(x2 - flatten * ux - curve * uy); |
| var controly2 = roundNumber(y2 - flatten * uy + curve * ux); |
| var thickness = 2; |
| if (klass) |
| klass += ' slur'; |
| else |
| klass = 'slur'; |
| klass += isTie ? ' tie' : ' legato'; |
| var ret; |
| if (dotted) { |
| klass += ' dotted'; |
| var pathString2 = sprintf("M %f %f C %f %f %f %f %f %f", x1, y1, |
| controlx1, controly1, controlx2, controly2, x2, y2); |
| ret = renderer.paper.path({ path: pathString2, stroke: renderer.foregroundColor, fill: "none", 'stroke-dasharray': "5 5", 'class': renderer.controller.classes.generate(klass), "data-name": isTie ? "tie" : "slur" }); |
| } else { |
| var pathString = sprintf("M %f %f C %f %f %f %f %f %f C %f %f %f %f %f %f z", x1, y1, |
| controlx1, controly1, controlx2, controly2, x2, y2, |
| roundNumber(controlx2 - thickness * uy), roundNumber(controly2 + thickness * ux), roundNumber(controlx1 - thickness * uy), roundNumber(controly1 + thickness * ux), x1, y1); |
| ret = renderer.paper.path({ path: pathString, stroke: "none", fill: renderer.foregroundColor, 'class': renderer.controller.classes.generate(klass), "data-name": isTie ? "tie" : "slur" }); |
| } |
|
|
| return ret; |
| }; |
|
|
| module.exports = drawTie; |
|
|