diff --git a/.svgo.yml b/.svgo.yml
index 313bf7c68..f3c425cfe 100644
--- a/.svgo.yml
+++ b/.svgo.yml
@@ -41,6 +41,7 @@ plugins:
- removeHiddenElems
- removeEmptyText
- convertShapeToPath
+ - removeOffCanvasPaths
- moveElemsAttrsToGroup
- moveGroupAttrsToElems
- collapseGroups
diff --git a/plugins/removeOffCanvasPaths.js b/plugins/removeOffCanvasPaths.js
new file mode 100644
index 000000000..30fba2870
--- /dev/null
+++ b/plugins/removeOffCanvasPaths.js
@@ -0,0 +1,79 @@
+'use strict';
+
+exports.type = 'perItem';
+
+exports.active = false;
+
+exports.description = 'removes elements that are drawn outside of the viewbox (disabled by default)';
+
+var SVGO = require('../lib/svgo.js'),
+ _path = require('./_path.js'),
+ intersects = _path.intersects,
+ path2js = _path.path2js,
+ viewBoxJS;
+
+/**
+ * Remove elements that are drawn outside of the viewbox.
+ *
+ * @param {Object} item current iteration item
+ * @return {Boolean} if false, item will be filtered out
+ *
+ * @author JoshyPHP
+ */
+exports.fn = function(item) {
+
+ if (item.isElem('path') && typeof viewBoxJS !== 'undefined')
+ {
+ return intersects(viewBoxJS, path2js(item));
+ }
+ if (item.isElem('svg'))
+ {
+ viewBoxJS = getViewBoxJS(item);
+ }
+
+ return true;
+};
+
+/**
+ * Compute the JS representation of the viewbox's path.
+ *
+ * @param {Object} svg svg element item
+ * @return {Object} JS representation, or undefined
+ */
+function getViewBoxJS(svg)
+{
+ var viewbox = '';
+ if (svg.hasAttr('viewBox'))
+ {
+ // Remove commas and plus signs, normalize and trim whitespace
+ viewbox = svg.attr('viewBox').value;
+ }
+ else if (svg.hasAttr('height') && svg.hasAttr('width'))
+ {
+ viewbox = '0 0 ' + svg.attr('width').value + ' ' + svg.attr('height').value;
+ }
+
+ // Remove commas and plus signs, normalize and trim whitespace
+ viewbox = viewbox.replace(/[,+]|px/g, ' ').replace(/\s+/g, ' ').replace(/^\s*|\s*$/g, '');
+
+ // Ensure that the dimensions are 4 values separated by space
+ var m = /^(-?\d*\.?\d+) (-?\d*\.?\d+) (\d*\.?\d+) (\d*\.?\d+)$/.exec(viewbox);
+ if (!m)
+ {
+ return undefined;
+ }
+
+ var path = new SVGO().createContentItem({
+ elem: 'path',
+ prefix: '',
+ local: 'path'
+ });
+ path.addAttr({
+ name: 'd',
+ prefix: '',
+ local: 'd',
+ value: 'M' + m[1] + ' ' + m[2] + 'h' + m[3] + 'v' + m[4] + 'H' + m[1] + 'z'
+ });
+
+ return path2js(path);
+}
diff --git a/test/plugins/removeOffCanvasPaths.01.svg b/test/plugins/removeOffCanvasPaths.01.svg
new file mode 100644
index 000000000..6bf8f4318
--- /dev/null
+++ b/test/plugins/removeOffCanvasPaths.01.svg
@@ -0,0 +1,13 @@
+
+
+@@@
+
+
diff --git a/test/plugins/removeOffCanvasPaths.02.svg b/test/plugins/removeOffCanvasPaths.02.svg
new file mode 100644
index 000000000..3597831a4
--- /dev/null
+++ b/test/plugins/removeOffCanvasPaths.02.svg
@@ -0,0 +1,15 @@
+
+
+@@@
+
+