mirror of
https://github.com/google/blockly.git
synced 2026-01-09 10:00:09 +01:00
Add zoom support for single-direction-scroll (#4653)
* Add zoom support for single-direction scroll
This commit is contained in:
@@ -28,11 +28,13 @@ goog.require('Blockly.utils.object');
|
||||
* event.
|
||||
* @param {string=} opt_workspaceId The workspace identifier for this event.
|
||||
* Undefined for a blank event.
|
||||
* @param {number=} opt_oldScale The old scale of the workspace. Undefined for a
|
||||
* blank event.
|
||||
* @extends {Blockly.Events.UiBase}
|
||||
* @constructor
|
||||
*/
|
||||
Blockly.Events.ViewportChange = function(opt_top, opt_left, opt_scale,
|
||||
opt_workspaceId) {
|
||||
opt_workspaceId, opt_oldScale) {
|
||||
Blockly.Events.ViewportChange.superClass_.constructor.call(this, opt_workspaceId);
|
||||
|
||||
/**
|
||||
@@ -54,6 +56,12 @@ Blockly.Events.ViewportChange = function(opt_top, opt_left, opt_scale,
|
||||
* @type {number|undefined}
|
||||
*/
|
||||
this.scale = opt_scale;
|
||||
|
||||
/**
|
||||
* The old scale of the workspace.
|
||||
* @type {number|undefined}
|
||||
*/
|
||||
this.oldScale = opt_oldScale;
|
||||
};
|
||||
Blockly.utils.object.inherits(Blockly.Events.ViewportChange,
|
||||
Blockly.Events.UiBase);
|
||||
@@ -73,6 +81,7 @@ Blockly.Events.ViewportChange.prototype.toJson = function() {
|
||||
json['viewTop'] = this.viewTop;
|
||||
json['viewLeft'] = this.viewLeft;
|
||||
json['scale'] = this.scale;
|
||||
json['oldScale'] = this.oldScale;
|
||||
return json;
|
||||
};
|
||||
|
||||
@@ -85,6 +94,7 @@ Blockly.Events.ViewportChange.prototype.fromJson = function(json) {
|
||||
this.viewTop = json['viewTop'];
|
||||
this.viewLeft = json['viewLeft'];
|
||||
this.scale = json['scale'];
|
||||
this.oldScale = json['oldScale'];
|
||||
};
|
||||
|
||||
Blockly.registry.register(Blockly.registry.Type.EVENT,
|
||||
|
||||
@@ -245,32 +245,38 @@ Blockly.bumpTopObjectsIntoBounds_ = function(workspace) {
|
||||
Blockly.bumpIntoBoundsHandler_ = function(workspace) {
|
||||
return function(e) {
|
||||
var metricsManager = workspace.getMetricsManager();
|
||||
if (!metricsManager.hasFixedEdges() || workspace.isDragging() ||
|
||||
Blockly.Events.BUMP_EVENTS.indexOf(e.type) === -1) {
|
||||
if (!metricsManager.hasFixedEdges || workspace.isDragging()) {
|
||||
return;
|
||||
}
|
||||
|
||||
var scrollMetricsInWsCoords = metricsManager.getScrollMetrics(true);
|
||||
if (Blockly.Events.BUMP_EVENTS.indexOf(e.type) !== -1) {
|
||||
var scrollMetricsInWsCoords = metricsManager.getScrollMetrics(true);
|
||||
|
||||
// Triggered by move/create event
|
||||
var object = Blockly.extractObjectFromEvent_(workspace, e);
|
||||
if (!object) {
|
||||
return;
|
||||
}
|
||||
// Handle undo.
|
||||
var oldGroup = Blockly.Events.getGroup();
|
||||
Blockly.Events.setGroup(e.group);
|
||||
// Triggered by move/create event
|
||||
var object = Blockly.extractObjectFromEvent_(workspace, e);
|
||||
if (!object) {
|
||||
return;
|
||||
}
|
||||
// Handle undo.
|
||||
var oldGroup = Blockly.Events.getGroup();
|
||||
Blockly.Events.setGroup(e.group);
|
||||
|
||||
var wasBumped = Blockly.bumpObjectIntoBounds_(
|
||||
workspace, scrollMetricsInWsCoords,
|
||||
/** @type {!Blockly.IBoundedElement} */ (object));
|
||||
var wasBumped = Blockly.bumpObjectIntoBounds_(
|
||||
workspace, scrollMetricsInWsCoords,
|
||||
/** @type {!Blockly.IBoundedElement} */ (object));
|
||||
|
||||
if (wasBumped && !e.group) {
|
||||
console.warn('Moved object in bounds but there was no' +
|
||||
' event group. This may break undo.');
|
||||
}
|
||||
if (oldGroup !== null) {
|
||||
Blockly.Events.setGroup(oldGroup);
|
||||
if (wasBumped && !e.group) {
|
||||
console.warn('Moved object in bounds but there was no' +
|
||||
' event group. This may break undo.');
|
||||
}
|
||||
if (oldGroup !== null) {
|
||||
Blockly.Events.setGroup(oldGroup);
|
||||
}
|
||||
} else if (e.type === Blockly.Events.VIEWPORT_CHANGE) {
|
||||
var viewportEvent = /** @type {!Blockly.Events.ViewportChange} */ (e);
|
||||
if (viewportEvent.scale > viewportEvent.oldScale) {
|
||||
Blockly.bumpTopObjectsIntoBounds_(workspace);
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
@@ -275,10 +275,10 @@ Blockly.Options.parseMoveOptions_ = function(options, hasCategories) {
|
||||
} else {
|
||||
moveOptions.scrollbars = !!move['scrollbars'] || !!options['scrollbars'];
|
||||
}
|
||||
|
||||
|
||||
if (!moveOptions.scrollbars || move['wheel'] === undefined) {
|
||||
// Defaults to false so that developers' settings don't appear to change.
|
||||
moveOptions.wheel = false;
|
||||
// Defaults to true if single-direction scroll is enabled.
|
||||
moveOptions.wheel = typeof moveOptions.scrollbars == 'object';
|
||||
} else {
|
||||
moveOptions.wheel = !!move['wheel'];
|
||||
}
|
||||
|
||||
@@ -1238,7 +1238,7 @@ Blockly.WorkspaceSvg.prototype.maybeFireViewportChangeEvent = function() {
|
||||
return;
|
||||
}
|
||||
var event = new (Blockly.Events.get(Blockly.Events.VIEWPORT_CHANGE))(top,
|
||||
left, scale, this.id);
|
||||
left, scale, this.id, this.oldScale_);
|
||||
this.oldScale_ = scale;
|
||||
this.oldTop_ = top;
|
||||
this.oldLeft_ = left;
|
||||
|
||||
@@ -450,9 +450,21 @@ Blockly.ZoomControls.prototype.createZoomResetSvg_ = function(rnd) {
|
||||
*/
|
||||
Blockly.ZoomControls.prototype.resetZoom_ = function(e) {
|
||||
this.workspace_.markFocused();
|
||||
this.workspace_.setScale(this.workspace_.options.zoomOptions.startScale);
|
||||
|
||||
// zoom is passed amount and computes the new scale using the formula:
|
||||
// targetScale = currentScale * Math.pow(speed, amount)
|
||||
var targetScale = this.workspace_.options.zoomOptions.startScale;
|
||||
var currentScale = this.workspace_.scale;
|
||||
var speed = this.workspace_.options.zoomOptions.scaleSpeed;
|
||||
// To compute amount:
|
||||
// amount = log(speed, (targetScale / currentScale))
|
||||
// Math.log computes natural logarithm (ln), to change the base, use formula:
|
||||
// log(base, value) = ln(value) / ln(base)
|
||||
var amount = Math.log(targetScale / currentScale) / Math.log(speed);
|
||||
|
||||
this.workspace_.beginCanvasTransition();
|
||||
this.workspace_.scrollCenter();
|
||||
this.workspace_.zoomCenter(amount);
|
||||
|
||||
setTimeout(this.workspace_.endCanvasTransition.bind(this.workspace_), 500);
|
||||
this.fireZoomEvent_();
|
||||
Blockly.Touch.clearTouchIdentifier(); // Don't block future drags.
|
||||
|
||||
@@ -551,13 +551,13 @@ suite('Events', function() {
|
||||
getArgs: (thisObj) => [true, thisObj.workspace.id],
|
||||
getExpectedJson: () => ({type: 'trashcan_open', isOpen: true})},
|
||||
{title: 'Viewport change', class: Blockly.Events.ViewportChange,
|
||||
getArgs: (thisObj) => [2.666, 1.333, 1.2, thisObj.workspace.id],
|
||||
getArgs: (thisObj) => [2.666, 1.333, 1.2, thisObj.workspace.id, 1],
|
||||
getExpectedJson: () => ({type: 'viewport_change', viewTop: 2.666,
|
||||
viewLeft: 1.333, scale: 1.2})},
|
||||
viewLeft: 1.333, scale: 1.2, oldScale: 1})},
|
||||
{title: 'Viewport change (0,0)', class: Blockly.Events.ViewportChange,
|
||||
getArgs: (thisObj) => [0, 0, 1.2, thisObj.workspace.id],
|
||||
getArgs: (thisObj) => [0, 0, 1.2, thisObj.workspace.id, 1],
|
||||
getExpectedJson: () => ({type: 'viewport_change', viewTop: 0,
|
||||
viewLeft: 0, scale: 1.2})},
|
||||
viewLeft: 0, scale: 1.2, oldScale: 1})},
|
||||
];
|
||||
var blockEventTestCases = [
|
||||
{title: 'Block change', class: Blockly.Events.BlockChange,
|
||||
|
||||
@@ -178,6 +178,7 @@ suite('WorkspaceSvg', function() {
|
||||
var metrics = workspace.getMetrics();
|
||||
var expectedProperties = {
|
||||
scale: workspace.scale,
|
||||
oldScale: 1,
|
||||
viewTop: metrics.viewTop,
|
||||
viewLeft: metrics.viewLeft
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user