Skip to content

Instantly share code, notes, and snippets.

@rememberlenny
Last active December 10, 2015 02:48
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rememberlenny/4369915 to your computer and use it in GitHub Desktop.
Save rememberlenny/4369915 to your computer and use it in GitHub Desktop.
Firefox 1.5 quadraticCurveTo() bug workaround There is a bug in the Firefox 1.5 implementation of quadatricCurveTo(). It does NOT draw a quadratic curve, as it is just calling the same cubic curve function bezierCurveTo() calls, and repeating the single quadratic control point (x,y) coordinate twice. For this reason quadraticCurveTo() will yield…
var currentX, currentY; // set to last x,y sent to lineTo/moveTo/bezierCurveTo or quadraticCurveToFixed()
function quadraticCurveToFixed( cpx, cpy, x, y ) {
/*
For the equations below the following variable name prefixes are used:
qp0 is the quadratic curve starting point (you must keep this from your last point sent to moveTo(), lineTo(), or bezierCurveTo() ).
qp1 is the quadratic curve control point (this is the cpx,cpy you would have sent to quadraticCurveTo() ).
qp2 is the quadratic curve ending point (this is the x,y arguments you would have sent to quadraticCurveTo() ).
We will convert these points to compute the two needed cubic control points (the starting/ending points are the same for both
the quadratic and cubic curves.
The exact equations for the two cubic control points are:
cp0 = qp0 and cp3 = qp2
cp1 = qp0 + (qp1 - qp0) * ratio
cp2 = cp1 + (qp2 - qp0) * (1 - ratio)
where ratio = (sqrt(2) - 1) * 4 / 3 exactly (approx. 0.5522847498307933984022516322796)
if the quadratic is an approximation of an elliptic arc, and the cubic must approximate the same arc, or
ratio = 2.0 / 3.0 for keeping the same quadratic curve.
In the code below, we must compute both the x and y terms for each point separately.
cp1x = qp0x + (qp1x - qp0x) * ratio;
cp1y = qp0y + (qp1y - qp0y) * ratio;
cp2x = cp1x + (qp2x - qp0x) * (1 - ratio);
cp2y = cp1y + (qp2y - qp0y) * (1 - ratio);
We will now
a) replace the qp0x and qp0y variables with currentX and currentY (which *you* must store for each moveTo/lineTo/bezierCurveTo)
b) replace the qp1x and qp1y variables with cpx and cpy (which we would have passed to quadraticCurveTo)
c) replace the qp2x and qp2y variables with x and y.
which leaves us with:
*/
var ratio = 2.0 / 3.0; // 0.5522847498307933984022516322796 if the Bezier is approximating an elliptic arc with best fitting
var cp1x = currentX + (cpx - currentX) * ratio;
var cp1y = currentY + (cpy - currentY) * ratio;
var cp2x = cp1x + (x - currentX) * (1 - ratio);
var cp2y = cp1y + (y - currentY) * (1 - ratio);
// and now call cubic Bezier curve to function
bezierCurveTo( cp1x, cp1y, cp2x, cp2y, x, y );
currentX = x;
currentY = y;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment