Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Zoom plots scaling #352

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions examples/advanced/transformations_on_svg_plots.html
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,8 @@
name: "usa_states"
, zoom: {
enabled: true,
maxLevel: 20
maxLevel: 20,
scalePlots: true
}
, defaultArea: {
attrs: {
Expand Down Expand Up @@ -202,7 +203,7 @@
var deletedPlots = ["paris", "lyon"];

$(".mapcontainer").trigger('update', [{
mapOptions: {map: {defaultPlot:{attrs:{transform:'r55'}}}},
mapOptions: {map: {defaultPlot: {attrs: {transform: 'r55'}}}},
animDuration: 1000
}]);
});
Expand All @@ -217,7 +218,7 @@
<div class="container">

<h1>Map with some transformations performed on SVG plotted points</h1>
<input type="button" value="Update elements" id="refresh"/>
<input type="button" value="Update elements" id="refresh"/>
<div class="mapcontainer">
<div class="map">
<span>Alternative content for the map</span>
Expand Down
3 changes: 2 additions & 1 deletion examples/advanced/zoom_event_on_specific_area.html
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,8 @@
name: "france_departments",
zoom: {
enabled: true,
maxLevel: 25
maxLevel: 25,
scalePlots: true
},
defaultPlot: {
attrs: {
Expand Down
10 changes: 6 additions & 4 deletions examples/basic/zoom_features.html
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,8 @@
// Enable zoom on the map
, zoom: {
enabled: true,
maxLevel: 10
maxLevel: 10,
scalePlots: true
}
// Set default plots and areas style
, defaultPlot: {
Expand Down Expand Up @@ -166,10 +167,11 @@
latitude: 48.86,
longitude: 2.3444,
attrs: {
opacity: 1
opacity: 1,
transform: "s0.75"
},
attrsHover: {
transform: "s1.5"
transform: "...s1.5"
}
},
// SVG plot
Expand Down Expand Up @@ -258,4 +260,4 @@ <h1>Map with zoom-in, zoom-out buttons and zoom on mousewheel</h1>
<p><b>All example for jQuery Mapael are available <a href="https://www.vincentbroute.fr/mapael/">here</a>.</b></p>
</div>
</body>
</html>
</html>
134 changes: 126 additions & 8 deletions js/jquery.mapael.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@
zoomX: 0,
zoomY: 0,
panX: 0,
panY: 0
panY: 0,
scaling: false
};

self.currentViewBox = {
Expand Down Expand Up @@ -530,6 +531,9 @@
var self = this;
var $mapElem = $(elem.mapElem.node);

// Store element id
elem.id = id;

// If an HTML link exists for this element, add cursor attributes
if (elem.options.href) {
elem.options.attrs.cursor = "pointer";
Expand Down Expand Up @@ -603,7 +607,8 @@
$.extend(self.zoomData, {
zoomLevel: 0,
panX: 0,
panY: 0
panY: 0,
scaling: false
});

// init zoom buttons
Expand Down Expand Up @@ -939,7 +944,94 @@
panX: panX,
panY: panY,
zoomX: panX + panWidth / 2,
zoomY: panY + panHeight / 2
zoomY: panY + panHeight / 2,
scaling: false
});

// Check if we should scale plots
if (self.options.map.zoom.scalePlots === true) {
// Scaling: inverse fn of zoom value since we need to reduce size when increasing zoom
self.zoomData.scaling = 1 / relativeZoomLevel;
self.handlePlotsScaling(animDuration);
}
},

/*
* Get the plot scaling transform string
*
* @param id int plot id
* @return string
*/
getPlotScalingTransform: function(id) {
var self = this;

// Assign scale string
var scaleStr = 's' + self.zoomData.scaling;

// If text is defined, we need to udpdate the transform string to add center x,y
if (self.plots[id].textElem) {
// Get BBox of malelem to get the center coordinates (cx, cy)
var mapElemBBox = self.plots[id].mapElem.getBBox();
// Transform strinf format is
// s[Scale on x],[Scale on y],[Scale center on X],[Scale center on Y]
scaleStr += "," + self.zoomData.scaling + "," + mapElemBBox.cx + "," + mapElemBBox.cy;
}

return scaleStr;
},

/*
* Handle scaling of plots
* Apply a scaling transformation on plots depending on zoom level
*
* @param animDuration int animation duration in ms
*/
handlePlotsScaling: function(animDuration) {
var self = this;

$.each(self.plots, function(id) {
// Assign scale string
var scaleStr = self.getPlotScalingTransform(id);

// Save once transform if defined
if (self.plots[id].mapElem.transformWithoutZoomScaling === undefined) {
if (self.plots[id].options.attrs.transform) {
self.plots[id].mapElem.transformWithoutZoomScaling = self.plots[id].options.attrs.transform;
} else {
self.plots[id].mapElem.transformWithoutZoomScaling = '';
}
}

// If text is defined, we need to update the transform string to add center x,y
if (self.plots[id].textElem) {

// Save once transform if defined
if (self.plots[id].textElem.transformWithoutZoomScaling === undefined) {
if (self.plots[id].options.text.attrs.transform) {
self.plots[id].textElem.transformWithoutZoomScaling = self.plots[id].options.text.attrs.transform;
} else {
self.plots[id].textElem.transformWithoutZoomScaling = '';
}
}

// Set text transform value
self.plots[id].options.text.attrs.transform = self.plots[id].textElem.transformWithoutZoomScaling + scaleStr;

// Update text Hover options
self.setHoverOptions(self.plots[id].textElem, self.plots[id].options.text.attrs, self.plots[id].options.text.attrsHover);

// Apply text transform
self.animate(self.plots[id].textElem, {transform: scaleStr}, animDuration);
}

// Set base transform value
self.plots[id].options.attrs.transform = self.plots[id].mapElem.transformWithoutZoomScaling + scaleStr;

// Update Hover options
self.setHoverOptions(self.plots[id].mapElem, self.plots[id].options.attrs, self.plots[id].options.attrsHover);

// Apply transform
self.animate(self.plots[id].mapElem, {transform: self.plots[id].options.attrs.transform}, animDuration);
});
},

Expand Down Expand Up @@ -1360,6 +1452,8 @@
* @param plot object plot element
*/
setPlotAttributes: function(plot) {
var self = this;

if (plot.options.type === "square") {
plot.options.attrs.width = plot.options.size;
plot.options.attrs.height = plot.options.size;
Expand All @@ -1386,12 +1480,22 @@

// The base transform will resize the SVG path to the one specified by width/height
// and also move the path to the actual coordinates
plot.mapElem.baseTransform = "m" + (plot.options.width / plot.mapElem.originalBBox.width) + ",0,0," +
(plot.options.height / plot.mapElem.originalBBox.height) + "," +
(plot.coords.x - plot.options.width / 2) + "," +
(plot.coords.y - plot.options.height / 2);
var baseTransform = "m" + (plot.options.width / plot.mapElem.originalBBox.width) + ",0,0," +
(plot.options.height / plot.mapElem.originalBBox.height) + "," +
(plot.coords.x - plot.options.width / 2) + "," +
(plot.coords.y - plot.options.height / 2);

// Handle plot scaling
// Note: plot.id may not be defined (usually at beginning, from initElem)
if (self.options.map.zoom.scalePlots === true && plot.id) {
plot.mapElem.transformWithoutZoomScaling = baseTransform + plot.options.attrs.transform;
if (plot.textElem) {
plot.textElem.transformWithoutZoomScaling = plot.options.text.attrs.transform;
}
baseTransform += self.getPlotScalingTransform(plot.id);
}

plot.options.attrs.transform = plot.mapElem.baseTransform + plot.options.attrs.transform;
plot.options.attrs.transform = baseTransform + plot.options.attrs.transform;

} else { // Default : circle
plot.options.attrs.x = plot.coords.x;
Expand Down Expand Up @@ -2522,6 +2626,15 @@
var self = this;
// Check element
if (!element) return;
// We will keep
var oldStrokeWidth;
// Check if scalePlots option is set, if we are zoomed in and a stroke width is defined
// This is needed because Raphael does not scale the stroke-width when applying a transform
if (self.options.map.zoom.scalePlots && self.zoomData.zoomLevel > 0 && attrs['stroke-width'] !== undefined) {
// Element is scaled, apply it to stroke width
oldStrokeWidth = attrs['stroke-width'];
attrs['stroke-width'] *= self.zoomData.scaling;
}
if (duration > 0) {
// Filter out non-animated attributes
// Note: we don't need to delete from original attribute (they won't be set anyway)
Expand All @@ -2536,11 +2649,15 @@
element.attr(attrsNonAnimated);
// Start animation for all attributes
element.animate(attrs, duration, 'linear', function() {
// Restore old stroke-width
if (oldStrokeWidth) attrs['stroke-width'] = oldStrokeWidth;
if (callback) callback();
});
} else {
// No animation: simply set all attributes...
element.attr(attrs);
// Restore old stroke-width
if (oldStrokeWidth) attrs['stroke-width'] = oldStrokeWidth;
// ... and call the callback if needed
if (callback) callback();
}
Expand Down Expand Up @@ -2659,6 +2776,7 @@
touch: true,
animDuration: 200,
animEasing: "linear",
scalePlots: false,
buttons: {
"reset": {
cssClass: "zoomButton zoomReset",
Expand Down