Adding horizontal scrolling. Changed scroll change callbacks from onScroll_ to setHandlePosition. onScroll_ is not challed when workspace is dragged.

This commit is contained in:
Karan Purohit
2017-03-12 15:29:05 +05:30
parent f77325f289
commit 4e9055a343
2 changed files with 79 additions and 31 deletions

View File

@@ -30,7 +30,7 @@
<div id="masterDiv" style="height: 480px; width: 900px;"></div> <div id="masterDiv" style="height: 480px; width: 900px;"></div>
</td> </td>
<td> <td>
<div id="mapDiv" style="height: 480px; width: 100px;"></div> <div id="mapDiv" style="height: 480px; width: 200px;"></div>
</td> </td>
</tr> </tr>
</table> </table>
@@ -51,7 +51,6 @@
<script> <script>
// Inject master workspace. // Inject master workspace.
var PADDING = 5;
var masterWorkspace = Blockly.inject('masterDiv',{ var masterWorkspace = Blockly.inject('masterDiv',{
media: '../../media/', media: '../../media/',
scrollbars: true, scrollbars: true,
@@ -65,8 +64,8 @@
zoom: zoom:
{controls: false, {controls: false,
wheel: true, wheel: true,
startScale: 0.20, //you can change this accorting to your needs startScale: 0.1, //you can change this accorting to your needs.
maxScale: 0.20, maxScale: 0.1,
minScale: 0.01 minScale: 0.01
}}); }});

View File

@@ -37,23 +37,29 @@ Minimap.init = function(workspace, minimap){
this.workspace = workspace; this.workspace = workspace;
this.minimap = minimap; this.minimap = minimap;
//Adding scroll callback functionlity to vScroll just for this demo. //Adding scroll callback functionlity to vScroll and hScroll just for this demo.
//IMPORTANT: This should be changed when there is proper UI event handling //IMPORTANT: This should be changed when there is proper UI event handling
// api available and should be handled by workspace's event listeners. // api available and should be handled by workspace's event listeners.
this.workspace.scrollbar.vScroll.onScroll_ = function(){ this.workspace.scrollbar.vScroll.setHandlePosition = function(newPosition){
var ratio = this.handlePosition_ / this.scrollViewSize_; this.handlePosition_ = newPosition;
if (isNaN(ratio)) { this.svgHandle_.setAttribute(this.positionAttribute_, this.handlePosition_);
ratio = 0;
}
var xyRatio = {};
if (this.horizontal_) {
xyRatio.x = ratio;
} else {
xyRatio.y = ratio;
}
this.workspace_.setMetrics(xyRatio);
// Code above is same as the original onScroll_ function in core/scrollbar.js. // Code above is same as the original setHandlePosition function in core/scrollbar.js.
// New code starts from here.
// Get the absolutePosition.
var absolutePosition = (this.handlePosition_ / this.ratio_);
// Firing the scroll change listener.
Minimap.onScrollChange(absolutePosition, this.horizontal_);
};
// Adding call back for horizontal scroll.
this.workspace.scrollbar.hScroll.setHandlePosition = function(newPosition){
this.handlePosition_ = newPosition;
this.svgHandle_.setAttribute(this.positionAttribute_, this.handlePosition_);
// Code above is same as the original setHandlePosition function in core/scrollbar.js.
// New code starts from here. // New code starts from here.
// Get the absolutePosition. // Get the absolutePosition.
@@ -63,8 +69,6 @@ Minimap.init = function(workspace, minimap){
Minimap.onScrollChange(absolutePosition, this.horizontal_); Minimap.onScrollChange(absolutePosition, this.horizontal_);
}; };
// Used as left padding in the minimap.
this.PADDING = 5;
// Required to stop a positive feedback loop when user clicks minimap // Required to stop a positive feedback loop when user clicks minimap
// and the scroll changes, which inturn may change minimap. // and the scroll changes, which inturn may change minimap.
@@ -152,6 +156,7 @@ Minimap.mirrorEvent = function(event){
minimapEvent.run(true); minimapEvent.run(true);
Minimap.scaleMinimap(); Minimap.scaleMinimap();
Minimap.setDraggerHeight(); Minimap.setDraggerHeight();
Minimap.setDraggerWidth();
}; };
/** /**
@@ -164,7 +169,7 @@ Minimap.repositionMinimap = function(){
}; };
/** /**
* Updates the rectangle's height and position. * Updates the rectangle's height .
*/ */
Minimap.setDraggerHeight = function(){ Minimap.setDraggerHeight = function(){
var workspaceMetrics = Minimap.workspace.getMetrics(); var workspaceMetrics = Minimap.workspace.getMetrics();
@@ -176,6 +181,20 @@ Minimap.setDraggerHeight = function(){
Minimap.mapDragger.setAttribute("height", draggerHeight); Minimap.mapDragger.setAttribute("height", draggerHeight);
}; };
/**
* Updates the rectangle's width.
*/
Minimap.setDraggerWidth = function(){
var workspaceMetrics = Minimap.workspace.getMetrics();
var draggerWidth = (workspaceMetrics.viewWidth / Minimap.workspace.scale) * Minimap.minimap.scale;
// It's zero when first block is placed.
if(draggerWidth == 0){
return;
}
Minimap.mapDragger.setAttribute("width", draggerWidth);
};
/** /**
* Updates the overall position of the viewport of the minimap by appropriately * Updates the overall position of the viewport of the minimap by appropriately
* using translate functions. * using translate functions.
@@ -189,6 +208,7 @@ Minimap.scaleMinimap = function(){
//Scaling the mimimap such that all the blocks can be seen in the viewport. //Scaling the mimimap such that all the blocks can be seen in the viewport.
//This padding is default because this is how to scrollbar(in main workspace) is implemented. //This padding is default because this is how to scrollbar(in main workspace) is implemented.
var topPadding = (workspaceMetrics.viewHeight) * Minimap.minimap.scale / (2 * Minimap.workspace.scale); var topPadding = (workspaceMetrics.viewHeight) * Minimap.minimap.scale / (2 * Minimap.workspace.scale);
var sidePadding = (workspaceMetrics.viewWidth) * Minimap.minimap.scale / (2 * Minimap.workspace.scale);
// If actual padding is more than half view ports height, change it to actual padding. // If actual padding is more than half view ports height, change it to actual padding.
if((workspaceBoundingBox.y * Minimap.workspace.scale - workspaceMetrics.contentTop) if((workspaceBoundingBox.y * Minimap.workspace.scale - workspaceMetrics.contentTop)
@@ -196,12 +216,20 @@ Minimap.scaleMinimap = function(){
topPadding = (workspaceBoundingBox.y * Minimap.workspace.scale - workspaceMetrics.contentTop) topPadding = (workspaceBoundingBox.y * Minimap.workspace.scale - workspaceMetrics.contentTop)
* Minimap.minimap.scale / Minimap.workspace.scale; * Minimap.minimap.scale / Minimap.workspace.scale;
} }
var scalex = (minimapMetrics.viewWidth - Minimap.PADDING) / minimapBoundingBox.width;
// If actual padding is more than half view ports height, change it to actual padding.
if((workspaceBoundingBox.x * Minimap.workspace.scale - workspaceMetrics.contentLeft)
* Minimap.minimap.scale / Minimap.workspace.scale > sidePadding){
sidePadding = (workspaceBoundingBox.x * Minimap.workspace.scale - workspaceMetrics.contentLeft)
* Minimap.minimap.scale / Minimap.workspace.scale;
}
var scalex = (minimapMetrics.viewWidth - 2 * sidePadding) / minimapBoundingBox.width;
var scaley = (minimapMetrics.viewHeight - 2 * topPadding) / minimapBoundingBox.height; var scaley = (minimapMetrics.viewHeight - 2 * topPadding) / minimapBoundingBox.height;
Minimap.minimap.setScale(Math.min(scalex, scaley)); Minimap.minimap.setScale(Math.min(scalex, scaley));
// Translating the minimap. // Translating the minimap.
Minimap.minimap.translate( - minimapBoundingBox.x * Minimap.minimap.scale+Minimap.PADDING, Minimap.minimap.translate( - minimapMetrics.contentLeft * Minimap.minimap.scale + sidePadding,
- minimapMetrics.contentTop * Minimap.minimap.scale + topPadding); - minimapMetrics.contentTop * Minimap.minimap.scale + topPadding);
}; };
@@ -211,24 +239,44 @@ Minimap.scaleMinimap = function(){
*/ */
Minimap.updateMapDragger = function(e){ Minimap.updateMapDragger = function(e){
var y = e.clientY; var y = e.clientY;
var x = e.clientX;
var draggerHeight = Minimap.mapDragger.getAttribute("height"); var draggerHeight = Minimap.mapDragger.getAttribute("height");
var draggerWidth = Minimap.mapDragger.getAttribute("width");
var finalY = y - Minimap.rect.top - draggerHeight / 2; var finalY = y - Minimap.rect.top - draggerHeight / 2;
var finalX = x - Minimap.rect.left - draggerWidth / 2;
var maxValidY = (Minimap.workspace.getMetrics().contentHeight - Minimap.workspace.getMetrics().viewHeight) var maxValidY = (Minimap.workspace.getMetrics().contentHeight - Minimap.workspace.getMetrics().viewHeight)
* Minimap.minimap.scale; * Minimap.minimap.scale;
var maxValidX = (Minimap.workspace.getMetrics().contentWidth - Minimap.workspace.getMetrics().viewWidth)
* Minimap.minimap.scale;
if(y + draggerHeight / 2 > Minimap.rect.bottom){ if(y + draggerHeight / 2 > Minimap.rect.bottom){
finalY = Minimap.rect.bottom - Minimap.rect.top - draggerHeight; finalY = Minimap.rect.bottom - Minimap.rect.top - draggerHeight;
}else if(y < Minimap.rect.top + draggerHeight / 2){ }else if(y < Minimap.rect.top + draggerHeight / 2){
finalY = 0; finalY = 0;
} }
if(x + draggerWidth / 2 > Minimap.rect.right){
finalX = Minimap.rect.right - Minimap.rect.left - draggerWidth;
}else if(x < Minimap.rect.left + draggerWidth / 2){
finalX = 0;
}
// Do not go below loew bound of scrollbar. // Do not go below loew bound of scrollbar.
if(finalY > maxValidY){ if(finalY > maxValidY){
finalY = maxValidY; finalY = maxValidY;
} }
Minimap.mapDragger.setAttribute("y", finalY);
if(finalX > maxValidX){
finalX = maxValidX;
}
Minimap.mapDragger.setAttribute("y", finalY);
Minimap.mapDragger.setAttribute("x", finalX);
// Required, otherwise creates a feedback loop. // Required, otherwise creates a feedback loop.
Minimap.disableScrollChange = true; Minimap.disableScrollChange = true;
Minimap.workspace.scrollbar.vScroll.set((finalY * Minimap.workspace.scale) / Minimap.minimap.scale); Minimap.workspace.scrollbar.vScroll.set((finalY * Minimap.workspace.scale) / Minimap.minimap.scale);
Minimap.workspace.scrollbar.hScroll.set((finalX * Minimap.workspace.scale) / Minimap.minimap.scale);
Minimap.disableScrollChange = false; Minimap.disableScrollChange = false;
}; };
@@ -245,12 +293,13 @@ Minimap.onScrollChange = function(position, horizontal){
return; return;
} }
// Currently the minimap automatically scales (see function Minimap.scaleMinimap) if the new block is created/moved
// beyond the width of the minimap. Compelete horizontal view is always visible in the minimap.
if(horizontal){
return;
}
var newDraggerPosition = (position * Minimap.minimap.scale / Minimap.workspace.scale); var newDraggerPosition = (position * Minimap.minimap.scale / Minimap.workspace.scale);
Minimap.mapDragger.setAttribute("y", newDraggerPosition); if(horizontal){
// Change the horizontal position of dragger.
Minimap.mapDragger.setAttribute("x", newDraggerPosition);
}
else{
// Change the vertical position of dragger.
Minimap.mapDragger.setAttribute("y", newDraggerPosition);
}
}; };