Итак, у нас есть этот путь, который делает стрелку. Я прокомментировал это:
dc.moveTo(p1.x, p1.y);
dc.lineTo(p2.x, p2.y); // end of main block
dc.lineTo(p3.x, p3.y); // topmost point
dc.lineTo(p4.x, p4.y); // endpoint
dc.lineTo(p5.x, p5.y); // bottommost point
dc.lineTo(p6.x, p6.y); // end at bottom point
dc.lineTo(p7.x, p7.y);
Мы действительно хотим, чтобы он был как можно более похожим, за исключением того, что мы хотим добраться до конечной точки (и обратно) другим способом, чем просто прямая линия. Мы абсолютно не хотим использовать какие-либо moveTo
команды, кроме первой. Это действительно смущает вещи и затрудняет их понимание. Я также избегал бы использования arcTo, если вам действительно не нужна часть дуги (как в круговой диаграмме), потому что она довольно запутанная по сравнению с другими командами пути.
Итак, мы будем использовать квадратичные кривые, которые похожи на кривые Безье, но имеют только одну контрольную точку, что делает их довольно простыми. Они работают путем указания контрольной точки, например this (слева) .
Итак, мы берем один и тот же точный код стрелки и вставляем два квадратичных Безье, чтобы сделать тощую стрелку. Мы хотим, чтобы контрольные точки были как бы "внутри" массы стрелки, чтобы квадратики изгибались внутрь:
dc.moveTo(p1.x, p1.y);
dc.lineTo(p2.x, p2.y); // end of main block
dc.lineTo(p3.x, p3.y); // topmost point
// control point is based on p3 (topmost point)
dc.quadraticCurveTo(p3.x + 20, p3.y + 30, p4.x, p4.y); // endpoint
// control point is based on p5 (bottommost point)
dc.quadraticCurveTo(p5.x + 20, p5.y - 30, p5.x, p5.y); // bottommost point
dc.lineTo(p6.x, p6.y); // end at bottom point
dc.lineTo(p7.x, p7.y);
Или толстая, мы помещаем контрольную точку на той же высоте, что и самая верхняя и самая нижняя точки, и вокруг того же X, что и конечная точка:
dc.beginPath();
// Draw arrow without curves
dc.moveTo(p1.x, p1.y);
dc.lineTo(p2.x, p2.y); // end of main block
dc.lineTo(p3.x, p3.y); // topmost point
// control point is based on p3 (topmost point)
dc.quadraticCurveTo(p3.x + 120, p3.y, p4.x, p4.y); // endpoint
// control point is based on p5 (bottommost point)
dc.quadraticCurveTo(p5.x + 120, p5.y, p5.x, p5.y); // bottommost point
dc.lineTo(p6.x, p6.y); // end at bottom point
dc.lineTo(p7.x, p7.y);
Живой пример здесь: http://jsfiddle.net/Yp7DM/