Skip to content

Instantly share code, notes, and snippets.

@rusintez
Last active July 15, 2016 08:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rusintez/feeeb37d9c484249ebfa to your computer and use it in GitHub Desktop.
Save rusintez/feeeb37d9c484249ebfa to your computer and use it in GitHub Desktop.
svg tooltip
/**
* Print SVG that will render a rectangular tooltip with a tip at the bottom
*/
setTimeout(function() {
console.log(
'<svg version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="' +
getTooltipPath(10, 10, 200, 80, 4, 10, 2, 'top').toString() +
'" fill="#777777"/></svg>'
);
}, 0);
/**
*
* Draw a fucking tooltip path in SVG
*
* @param {Number} x, position
* @param {Number} y, position
* @param {Number} w, width
* @param {Number} h, height
* @param {Number} r, corner radius
* @param {Number} ts, tip side
* @param {Number} tr, tip corner radius
* @param {String} position, tooltip position (eg. 'top', 'bottom', 'left', 'right')
* @return {Shape} closed shape
*/
function getTooltipPath(x, y, w, h, r, ts, tr, position) {
var tt = Shape()
.move(x + r, y);
if (position === 'bottom') {
tt = tt
.line(x + w / 2 - ts, y)
.line(x + w / 2 - tr, y - ts + tr)
.quadraticCurve(x + w / 2, y - ts, x + w / 2 + tr, y - ts + tr)
.line(x + w / 2 + ts, y);
}
tt = tt
.line(x + w - r, y)
.curve(x + w - r + kappa * r, y, x + w, r - kappa * r + y, x + w, y + r);
if (position === 'left') {
tt = tt
.line(x + w, y + h / 2 - ts)
.line(x + w + ts - tr, y + h / 2 - tr)
.quadraticCurve(x + w + ts, y + h / 2, x + w + ts - tr , y + h / 2 + tr)
.line(x + w, y + h / 2 + ts);
}
tt = tt
.line(x + w, y + h - r)
.curve(x + w, h - r + kappa * r + y, x + w - r + kappa * r, y + h, x + w - r, y + h);
if (position === 'top') {
tt = tt
.line(x + w / 2 + ts, y + h)
.line(x + w / 2 + tr, y + h + ts - tr)
.quadraticCurve(x + w / 2, y + h + ts, x + w / 2 - tr, y + h + ts - tr)
.line(x + w / 2 - ts, y + h);
}
tt = tt
.line(x + r, y + h)
.curve(x + r - kappa * r, y + h, x, h - r + kappa * r + y, x, h - r + y);
if (position === 'right') {
tt = tt
.line(x, y + h / 2 + ts)
.line(x - ts + tr, y + h / 2 + tr)
.quadraticCurve(x - ts, y + h / 2, x - ts + tr , y + h / 2 - tr)
.line(x, y + h / 2 - ts);
}
tt = tt
.line(x, y + r)
.curve(x, r - kappa * r + y, x + r - kappa * r, y, x + r, y);
return tt.close();
}
/**
* Don't ask
* http://nacho4d-nacho4d.blogspot.hk/2011/05/bezier-paths-rounded-corners-rectangles.html
*/
var kappa = 0.552228474;
/**
* Lightweight SVG path utils; reconstructed from spec:
* https://developer.mozilla.org/en/docs/Web/SVG/Tutorial/Paths
*/
function Shape(stack) {
if (!(this instanceof Shape)) {
return new Shape(stack);
}
this.stack = stack || [];
}
/**
* Move cursor
*
* @param {Number} x
* @param {Number} y
*/
Shape.prototype.move = function() {
return Shape(this.stack.concat({
type: 'move',
args: [].slice.call(arguments)
}));
}
/**
* Draw a line to
*
* @param {Number} x
* @param {Number} y
*/
Shape.prototype.line = function() {
return Shape(this.stack.concat({
type: 'line',
args: [].slice.call(arguments)
}));
}
/**
* Draw a curve (bezier)
*
* @param {Number} aX
* @param {Number} aY
* @param {Number} bX
* @param {Number} bY
* @param {Number} x
* @param {Number} y
*/
Shape.prototype.curve = function() {
return Shape(this.stack.concat({
type: 'curve',
args: [].slice.call(arguments)
}));
}
/**
* Draw a quadractic curve
*
* @param {Number} aX
* @param {Number} aY
* @param {Number} x
* @param {Number} y
*/
Shape.prototype.quadraticCurve = function() {
return Shape(this.stack.concat({
type: 'quadratic',
args: [].slice.call(arguments)
}));
}
/**
* Close path
*/
Shape.prototype.close = function() {
return Shape(this.stack.concat({
type: 'close'
}));
}
/**
* Get SVG path string
*/
Shape.prototype.toString = function() {
var out = [];
this.stack.forEach(function(step) {
switch(step.type) {
case 'move':
out.push('M');
out.push(step.args[0]);
out.push(step.args[1]);
break;
case 'line':
out.push('L');
out.push(step.args[0]);
out.push(step.args[1]);
break;
case 'curve':
out.push('C');
out.push(step.args[0]);
out.push(step.args[1] + ',');
out.push(step.args[2]);
out.push(step.args[3] + ',');
out.push(step.args[4]);
out.push(step.args[5]);
break;
case 'quadratic':
out.push('Q');
out.push(step.args[0]);
out.push(step.args[1]);
out.push(step.args[2]);
out.push(step.args[3]);
break;
case 'close':
out.push('Z');
break;
}
});
return out.join(' ');
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment