leaflet-distortableimage
Advanced tools
Comparing version 0.1.6 to 0.2.0
@@ -639,2 +639,21 @@ L.DomUtil = L.extend(L.DomUtil, { | ||
} | ||
}), | ||
ToggleExport = EditOverlayAction.extend({ | ||
options: { | ||
toolbarIcon: { | ||
html: '<span class="fa fa-download"></span>', | ||
tooltip: 'Export Image', | ||
title: 'Export Image' | ||
} | ||
}, | ||
addHooks: function () | ||
{ | ||
var editing = this._overlay.editing; | ||
editing._toggleExport(); | ||
this.disable(); | ||
} | ||
}); | ||
@@ -649,3 +668,4 @@ | ||
ToggleEditable, | ||
ToggleRotateDistort | ||
ToggleRotateDistort, | ||
ToggleExport | ||
] | ||
@@ -663,2 +683,3 @@ } | ||
68: '_toggleRotateDistort', // d | ||
69: '_toggleIsolate', // e | ||
73: '_toggleIsolate', // i | ||
@@ -687,2 +708,5 @@ 76: '_toggleLock', // l | ||
/* bring the selected image into view */ | ||
overlay.bringToFront(); | ||
this._lockHandles = new L.LayerGroup(); | ||
@@ -703,5 +727,5 @@ for (i = 0; i < 4; i++) { | ||
this._handles = { | ||
'lock': this._lockHandles, | ||
'distort': this._distortHandles, | ||
this._handles = { | ||
'lock': this._lockHandles, | ||
'distort': this._distortHandles, | ||
'rotate': this._rotateHandles | ||
@@ -795,5 +819,5 @@ }; | ||
/* | ||
/* | ||
* Adjust default behavior of L.Draggable. | ||
* By default, L.Draggable overwrites the CSS3 distort transform | ||
* By default, L.Draggable overwrites the CSS3 distort transform | ||
* that we want when it calls L.DomUtil.setPosition. | ||
@@ -825,3 +849,3 @@ */ | ||
} | ||
}, | ||
}, | ||
@@ -870,4 +894,4 @@ _toggleRotateDistort: function() { | ||
/* Switch mode. */ | ||
if (this._mode === 'lock') { | ||
this._mode = 'distort'; | ||
if (this._mode === 'lock') { | ||
this._mode = 'distort'; | ||
this._enableDragging(); | ||
@@ -902,3 +926,3 @@ } else { | ||
var raised_point = map.containerPointToLatLng(new L.Point(point.x,point.y-20)); | ||
raised_point.lng = overlay.getCenter().lng; | ||
raised_point.lng = overlay.getCenter().lng; | ||
this.toolbar = new L.DistortableImage.EditToolbar(raised_point).addTo(map, overlay); | ||
@@ -910,2 +934,61 @@ overlay.fire('toolbar:created'); | ||
// Based on https://github.com/publiclab/mapknitter/blob/8d94132c81b3040ae0d0b4627e685ff75275b416/app/assets/javascripts/mapknitter/Map.js#L47-L82 | ||
_toggleExport: function (){ | ||
var map = this._overlay._map; | ||
var overlay = this._overlay; | ||
// make a new image | ||
var downloadable = new Image(); | ||
downloadable.id = downloadable.id || "tempId12345"; | ||
$('body').append(downloadable); | ||
downloadable.onload = function onLoadDownloadableImage() { | ||
var height = downloadable.height, | ||
width = downloadable.width, | ||
nw = map.latLngToLayerPoint(overlay._corners[0]), | ||
ne = map.latLngToLayerPoint(overlay._corners[1]), | ||
sw = map.latLngToLayerPoint(overlay._corners[2]), | ||
se = map.latLngToLayerPoint(overlay._corners[3]); | ||
// I think this is to move the image to the upper left corner, | ||
// jywarren: i think we may need these or the image goes off the edge of the canvas | ||
// jywarren: but these seem to break the distortion math... | ||
// jywarren: i think it should be rejiggered so it | ||
// finds the most negative values of x and y and then | ||
// adds those to all coordinates | ||
//nw.x -= nw.x; | ||
//ne.x -= nw.x; | ||
//se.x -= nw.x; | ||
//sw.x -= nw.x; | ||
//nw.y -= nw.y; | ||
//ne.y -= nw.y; | ||
//se.y -= nw.y; | ||
//sw.y -= nw.y; | ||
// run once warping is complete | ||
downloadable.onload = function() { | ||
$(downloadable).remove(); | ||
}; | ||
if (window && window.hasOwnProperty('warpWebGl')) { | ||
warpWebGl( | ||
downloadable.id, | ||
[0, 0, width, 0, width, height, 0, height], | ||
[nw.x, nw.y, ne.x, ne.y, se.x, se.y, sw.x, sw.y], | ||
true // trigger download | ||
); | ||
} | ||
}; | ||
downloadable.src = overlay.options.fullResolutionSrc || overlay._image.src; | ||
}, | ||
toggleIsolate: function() { | ||
@@ -939,3 +1022,3 @@ // this.isolated = !this.isolated; | ||
if (this.editing) { this.editing.disable(); } | ||
}); | ||
}); | ||
}); |
@@ -30,2 +30,3 @@ module.exports = function(grunt) { | ||
LeafletToolbar: false, | ||
warpWebGl: false, | ||
@@ -56,8 +57,5 @@ // Mocha | ||
configFile: 'test/karma.conf.js', | ||
background: true | ||
}, | ||
test: { | ||
configFile: 'test/karma.conf.js', | ||
background: false, | ||
singleRun: true | ||
} | ||
@@ -105,3 +103,3 @@ }, | ||
'jshint', | ||
'karma:development:run', | ||
'karma:development:start', | ||
'coverage', | ||
@@ -133,3 +131,3 @@ 'concat:dist' | ||
} | ||
}); | ||
}); | ||
}; |
{ | ||
"name": "leaflet-distortableimage", | ||
"version": "0.1.6", | ||
"version": "0.2.0", | ||
"description": "Leaflet plugin enabling image overlays to be distorted, stretched, and warped (built for Public Lab's MapKnitter: http://publiclab.org).", | ||
@@ -31,12 +31,16 @@ "scripts": { | ||
"homepage": "https://github.com/publiclab/Leaflet.DistortableImage", | ||
"dependencies": { | ||
"grunt-cli": "^1.2.0" | ||
}, | ||
"devDependencies": { | ||
"chai": "^4.1.2", | ||
"font-awesome": "^4.2.0", | ||
"glfx": "0.0.4", | ||
"grunt": "^1.0.3", | ||
"grunt-contrib-concat": "^1.0.1", | ||
"grunt-contrib-jshint": "^1.1.0", | ||
"grunt-contrib-jshint": "^2.0.0", | ||
"grunt-contrib-watch": "^1.0.0", | ||
"grunt-karma": "^2.0.0", | ||
"jquery": "~> 3.0.0", | ||
"karma": "^1.7.1", | ||
"grunt-karma": "^3.0.1", | ||
"jquery": "~> 3.3.1", | ||
"karma": "^3.1.4", | ||
"karma-coverage": "^1.1.1", | ||
@@ -48,9 +52,7 @@ "karma-mocha": "^1.3.0", | ||
"leaflet-toolbar": "^0.3.0", | ||
"matchdep": "^0.3.0", | ||
"mocha": "^2.0.1", | ||
"sinon": "^1.12.2" | ||
}, | ||
"dependencies": { | ||
"grunt-cli": "^1.2.0" | ||
"matchdep": "^2.0.0", | ||
"mocha": "^5.2.0", | ||
"sinon": "^7.2.2", | ||
"webgl-distort": "0.0.2" | ||
} | ||
} |
@@ -26,8 +26,52 @@ Leaflet.DistortableImage | ||
## Demo | ||
Check out this [simple demo](https://publiclab.github.io/Leaflet.DistortableImage/examples/index.html). | ||
Download as zip or clone to get a copy of the Repo. | ||
And watch this GIF demo: | ||
 | ||
To test the code, open `index.html` in your browser and click and drag the markers on the edges of the image. The image will show perspectival distortions. | ||
## Usage | ||
```js | ||
// basic Leaflet map setup | ||
map = new L.map('map').setView([51.505, -0.09], 13); | ||
L.tileLayer('https://{s}.tiles.mapbox.com/v3/anishshah101.ipm9j6em/{z}/{x}/{y}.png', { | ||
maxZoom: 18, | ||
attribution: 'Map data © <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, ' + | ||
'<a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ' + | ||
'Imagery © <a href="http://mapbox.com">Mapbox</a>', | ||
id: 'examples.map-i86knfo3' | ||
}).addTo(map); | ||
// create an image | ||
img = new L.DistortableImageOverlay( | ||
'example.png', { | ||
corners: [ | ||
new L.latLng(51.52,-0.10), | ||
new L.latLng(51.52,-0.14), | ||
new L.latLng(51.50,-0.10), | ||
new L.latLng(51.50,-0.14) | ||
], | ||
fullResolutionSrc: 'large.jpg' // optionally pass in a higher resolution image to use in full-res exporting | ||
} | ||
).addTo(map); | ||
L.DomEvent.on(img._image, 'load', img.editing.enable, img.editing); // enable editing | ||
``` | ||
## Full-resolution download | ||
We've added a GPU-accelerated means to generate a full resolution version of the distorted image; it requires two additional dependencies to enable; see how we've included them in the demo: | ||
``` | ||
<script src="../node_modules/webgl-distort/dist/webgl-distort.js"></script> | ||
<script src="../node_modules/glfx-js/dist/glfx.js"></script> | ||
``` | ||
**** | ||
@@ -53,2 +97,2 @@ | ||
More at https://github.com/publiclab/Leaflet.DistortableImage/graphs/contributors | ||
Many more at https://github.com/publiclab/Leaflet.DistortableImage/graphs/contributors |
@@ -9,2 +9,3 @@ L.DistortableImage = L.DistortableImage || {}; | ||
68: '_toggleRotateDistort', // d | ||
69: '_toggleIsolate', // e | ||
73: '_toggleIsolate', // i | ||
@@ -33,2 +34,5 @@ 76: '_toggleLock', // l | ||
/* bring the selected image into view */ | ||
overlay.bringToFront(); | ||
this._lockHandles = new L.LayerGroup(); | ||
@@ -49,5 +53,5 @@ for (i = 0; i < 4; i++) { | ||
this._handles = { | ||
'lock': this._lockHandles, | ||
'distort': this._distortHandles, | ||
this._handles = { | ||
'lock': this._lockHandles, | ||
'distort': this._distortHandles, | ||
'rotate': this._rotateHandles | ||
@@ -141,5 +145,5 @@ }; | ||
/* | ||
/* | ||
* Adjust default behavior of L.Draggable. | ||
* By default, L.Draggable overwrites the CSS3 distort transform | ||
* By default, L.Draggable overwrites the CSS3 distort transform | ||
* that we want when it calls L.DomUtil.setPosition. | ||
@@ -171,3 +175,3 @@ */ | ||
} | ||
}, | ||
}, | ||
@@ -216,4 +220,4 @@ _toggleRotateDistort: function() { | ||
/* Switch mode. */ | ||
if (this._mode === 'lock') { | ||
this._mode = 'distort'; | ||
if (this._mode === 'lock') { | ||
this._mode = 'distort'; | ||
this._enableDragging(); | ||
@@ -248,3 +252,3 @@ } else { | ||
var raised_point = map.containerPointToLatLng(new L.Point(point.x,point.y-20)); | ||
raised_point.lng = overlay.getCenter().lng; | ||
raised_point.lng = overlay.getCenter().lng; | ||
this.toolbar = new L.DistortableImage.EditToolbar(raised_point).addTo(map, overlay); | ||
@@ -256,2 +260,61 @@ overlay.fire('toolbar:created'); | ||
// Based on https://github.com/publiclab/mapknitter/blob/8d94132c81b3040ae0d0b4627e685ff75275b416/app/assets/javascripts/mapknitter/Map.js#L47-L82 | ||
_toggleExport: function (){ | ||
var map = this._overlay._map; | ||
var overlay = this._overlay; | ||
// make a new image | ||
var downloadable = new Image(); | ||
downloadable.id = downloadable.id || "tempId12345"; | ||
$('body').append(downloadable); | ||
downloadable.onload = function onLoadDownloadableImage() { | ||
var height = downloadable.height, | ||
width = downloadable.width, | ||
nw = map.latLngToLayerPoint(overlay._corners[0]), | ||
ne = map.latLngToLayerPoint(overlay._corners[1]), | ||
sw = map.latLngToLayerPoint(overlay._corners[2]), | ||
se = map.latLngToLayerPoint(overlay._corners[3]); | ||
// I think this is to move the image to the upper left corner, | ||
// jywarren: i think we may need these or the image goes off the edge of the canvas | ||
// jywarren: but these seem to break the distortion math... | ||
// jywarren: i think it should be rejiggered so it | ||
// finds the most negative values of x and y and then | ||
// adds those to all coordinates | ||
//nw.x -= nw.x; | ||
//ne.x -= nw.x; | ||
//se.x -= nw.x; | ||
//sw.x -= nw.x; | ||
//nw.y -= nw.y; | ||
//ne.y -= nw.y; | ||
//se.y -= nw.y; | ||
//sw.y -= nw.y; | ||
// run once warping is complete | ||
downloadable.onload = function() { | ||
$(downloadable).remove(); | ||
}; | ||
if (window && window.hasOwnProperty('warpWebGl')) { | ||
warpWebGl( | ||
downloadable.id, | ||
[0, 0, width, 0, width, height, 0, height], | ||
[nw.x, nw.y, ne.x, ne.y, se.x, se.y, sw.x, sw.y], | ||
true // trigger download | ||
); | ||
} | ||
}; | ||
downloadable.src = overlay.options.fullResolutionSrc || overlay._image.src; | ||
}, | ||
toggleIsolate: function() { | ||
@@ -285,3 +348,3 @@ // this.isolated = !this.isolated; | ||
if (this.editing) { this.editing.disable(); } | ||
}); | ||
}); | ||
}); |
@@ -93,2 +93,21 @@ L.DistortableImage = L.DistortableImage || {}; | ||
} | ||
}), | ||
ToggleExport = EditOverlayAction.extend({ | ||
options: { | ||
toolbarIcon: { | ||
html: '<span class="fa fa-download"></span>', | ||
tooltip: 'Export Image', | ||
title: 'Export Image' | ||
} | ||
}, | ||
addHooks: function () | ||
{ | ||
var editing = this._overlay.editing; | ||
editing._toggleExport(); | ||
this.disable(); | ||
} | ||
}); | ||
@@ -103,5 +122,6 @@ | ||
ToggleEditable, | ||
ToggleRotateDistort | ||
ToggleRotateDistort, | ||
ToggleExport | ||
] | ||
} | ||
}); |
@@ -1,2 +0,2 @@ | ||
// Karma configuration | ||
// Karma configuration | ||
// Generated on Tue Jul 08 2014 12:47:31 GMT-0500 (CDT) | ||
@@ -6,37 +6,46 @@ | ||
config.set({ | ||
// base path that will be used to resolve all patterns (eg. files, exclude) | ||
basePath: '../', | ||
basePath: "../", | ||
plugins: [ | ||
require("mocha"), | ||
require("karma-mocha"), | ||
require("karma-coverage"), | ||
require("karma-mocha-reporter"), | ||
require("karma-phantomjs-launcher"), | ||
require("glfx"), | ||
require("webgl-distort/dist/webgl-distort.js") | ||
], | ||
// frameworks to use | ||
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter | ||
frameworks: ['mocha'], | ||
frameworks: ["mocha"], | ||
// list of files / patterns to load in the browser | ||
files: [ | ||
{ pattern: 'examples/*.jpg', included: false, served: true }, | ||
'node_modules/leaflet/dist/leaflet-src.js', | ||
'node_modules/leaflet/dist/leaflet.css', | ||
'node_modules/leaflet-toolbar/dist/leaflet.toolbar.js', | ||
'node_modules/leaflet-toolbar/dist/leaflet.toolbar.css', | ||
'node_modules/chai/chai.js', | ||
'node_modules/sinon/pkg/sinon.js', | ||
'src/util/*.js', | ||
'src/edit/EditHandle.js', | ||
'src/edit/LockHandle.js', | ||
'src/edit/DistortHandle.js', | ||
'src/edit/RotateHandle.js', | ||
'src/DistortableImageOverlay.js', | ||
'src/edit/DistortableImage.EditToolbar.js', | ||
'src/edit/DistortableImage.Edit.js', | ||
'test/SpecHelper.js', | ||
'test/src/**/*Spec.js' | ||
{ pattern: "examples/*.jpg", included: false, served: true }, | ||
{ pattern: "examples/*.png", included: false, served: true }, | ||
"node_modules/leaflet/dist/leaflet-src.js", | ||
"node_modules/leaflet/dist/leaflet.css", | ||
"node_modules/leaflet-toolbar/dist/leaflet.toolbar.js", | ||
"node_modules/leaflet-toolbar/dist/leaflet.toolbar.css", | ||
"node_modules/webgl-distort/dist/webgl-distort.js", | ||
"node_modules/glfx/glfx.js", | ||
"node_modules/chai/chai.js", | ||
"node_modules/sinon/pkg/sinon.js", | ||
"src/util/*.js", | ||
"src/edit/EditHandle.js", | ||
"src/edit/LockHandle.js", | ||
"src/edit/DistortHandle.js", | ||
"src/edit/RotateHandle.js", | ||
"src/DistortableImageOverlay.js", | ||
"src/edit/DistortableImage.EditToolbar.js", | ||
"src/edit/DistortableImage.Edit.js", | ||
"test/SpecHelper.js", | ||
"test/src/**/*Spec.js" | ||
], | ||
// so that karma can serve examples/example.jpg | ||
proxies: { | ||
'/examples/': '/base/examples/' | ||
"/examples/": "/base/examples/" | ||
}, | ||
@@ -47,6 +56,6 @@ | ||
// available reporters: https://npmjs.org/browse/keyword/karma-reporter | ||
reporters: [ 'mocha', 'coverage' ], | ||
reporters: ["mocha", "coverage"], | ||
preprocessors: { | ||
'../src/**/*.js': 'coverage' | ||
"../src/**/*.js": "coverage" | ||
}, | ||
@@ -57,7 +66,5 @@ | ||
// enable / disable colors in the output (reporters and logs) | ||
colors: true, | ||
// level of logging | ||
@@ -67,29 +74,20 @@ // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG | ||
// start these browsers | ||
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher | ||
browsers: [ 'PhantomJS' ], | ||
browsers: ["PhantomJS"], | ||
plugins: [ | ||
'karma-mocha', | ||
'karma-phantomjs-launcher', | ||
'karma-mocha-reporter', | ||
'karma-coverage' | ||
], | ||
// Continuous Integration mode | ||
// if true, Karma captures browsers, runs the tests and exits | ||
singleRun: false, | ||
singleRun: true, | ||
background: false, | ||
coverageReporter: { | ||
reporters: [ | ||
{ type: 'text', dir: '../coverage/', file: 'coverage.txt' }, | ||
{ type: 'lcovonly', dir: '../coverage/' }, | ||
{ type: 'html', dir: '../coverage/' } | ||
{ type: "text", dir: "../coverage/", file: "coverage.txt" }, | ||
{ type: "lcovonly", dir: "../coverage/" }, | ||
{ type: "html", dir: "../coverage/" } | ||
] | ||
} | ||
} | ||
}); | ||
}; |
@@ -17,3 +17,3 @@ describe("L.DistortableImageOverlay", function() { | ||
distortable = new L.DistortableImageOverlay('/examples/example.jpg', { | ||
distortable = new L.DistortableImageOverlay('/examples/example.png', { | ||
corners: [ | ||
@@ -53,2 +53,2 @@ new L.LatLng(41.7934, -87.6052), | ||
}); | ||
}); | ||
}); |
@@ -8,3 +8,3 @@ describe("L.DistortableImage.Edit", function() { | ||
overlay = new L.DistortableImageOverlay('/examples/example.jpg', { | ||
overlay = new L.DistortableImageOverlay('/examples/example.png', { | ||
corners: [ | ||
@@ -65,2 +65,2 @@ new L.LatLng(41.7934, -87.6052), | ||
}); | ||
}); | ||
}); |
@@ -8,3 +8,3 @@ describe("L.RotateHandle", function() { | ||
map = new L.Map(L.DomUtil.create('div', '', document.body)).setView([41.7896,-87.5996], 15); | ||
distortable = new L.DistortableImageOverlay('/examples/example.jpg', { | ||
distortable = new L.DistortableImageOverlay('/examples/example.png', { | ||
corners: [ | ||
@@ -41,2 +41,2 @@ new L.LatLng(41.7934, -87.6052), | ||
}); | ||
}); | ||
}); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
823424
34
2091
97
20