Skip to content

Instantly share code, notes, and snippets.

@cletusw
Created May 21, 2015 21:28
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 cletusw/60ca0a9a54e60781f7c0 to your computer and use it in GitHub Desktop.
Save cletusw/60ca0a9a54e60781f7c0 to your computer and use it in GitHub Desktop.
Generate a backdrop with a cutout (ie, for highlighting a page element in an app walkthrough)
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%">
<defs>
<mask id="walkthrough-backdrop-mask">
<rect width="100%" height="100%" x="0" y="0" fill="white"></rect>
<ellipse class="hole" ng-attr-cx="{{cutoutCenterX}}" ng-attr-cy="{{cutoutCenterY}}" ng-attr-rx="{{cutoutRadiusX}}" ng-attr-ry="{{cutoutRadiusY}}" fill="black"></ellipse>
</mask>
</defs>
<rect width="100%" height="100%" x="0" y="0" fill="black" fill-opacity="0.75" mask="url(#walkthrough-backdrop-mask)"></rect>
</svg>
var boundingRect = target.getBoundingClientRect();
var halfWidth = boundingRect.width / 2;
var halfHeight = boundingRect.height / 2;
var padding = (parseInt(scope.padding, 10) || 0);
var radius = Math.sqrt(halfWidth * halfWidth + halfHeight * halfHeight);
scope.cutoutCenterX = boundingRect.left + halfWidth;
scope.cutoutCenterY = boundingRect.top + halfHeight;
if (scope.cutoutShape === 'circle' || halfHeight === halfWidth) {
scope.cutoutRadiusX = scope.cutoutRadiusY = radius + padding;
}
else {
// Approximate an oval that bounds the bounding client rect
var factor = (halfHeight - halfWidth) / radius;
if (factor > 0) {
scope.cutoutRadiusX = radius * Math.sqrt(1 - factor) + padding;
scope.cutoutRadiusY = radius + padding;
}
else {
scope.cutoutRadiusX = radius + padding;
scope.cutoutRadiusY = radius * Math.sqrt(1 + factor) + padding;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment