Implement new zoom controls. Resolves GH-43

* WIP: New zoom controls

* Adjust sizing as per discussion with Carl

* Update icons and spacing as per discussions with Carl

* Remove unused 'rnd' function

* Updated icons

* Resolve issues from PR review
This commit is contained in:
Andrew Sliwinski 2017-02-22 11:33:39 -05:00 committed by GitHub
parent 57c3666198
commit 292296af30
7 changed files with 113 additions and 86 deletions

View file

@ -573,15 +573,7 @@ Blockly.Css.CONTENT = [
'}',
'.blocklyZoom>image {',
'opacity: .4;',
'}',
'.blocklyZoom>image:hover {',
'opacity: .6;',
'}',
'.blocklyZoom>image:active {',
'opacity: .8;',
'opacity: 1;',
'}',
/* Darken flyout scrollbars due to being on a grey background. */

View file

@ -56,7 +56,7 @@ Blockly.Options = function(options) {
languageTree.getElementsByTagName('category').length);
var hasTrashcan = options['trashcan'];
if (hasTrashcan === undefined) {
hasTrashcan = hasCategories;
hasTrashcan = false;
}
var hasCollapse = options['collapse'];
if (hasCollapse === undefined) {

View file

@ -39,33 +39,61 @@ Blockly.ZoomControls = function(workspace) {
this.workspace_ = workspace;
};
/**
* Zoom in icon path.
* @type {string}
* @private
*/
Blockly.ZoomControls.prototype.ZOOM_IN_PATH_ = 'zoom-in.svg';
/**
* Zoom out icon path.
* @type {string}
* @private
*/
Blockly.ZoomControls.prototype.ZOOM_OUT_PATH_ = 'zoom-out.svg';
/**
* Zoom reset icon path.
* @type {string}
* @private
*/
Blockly.ZoomControls.prototype.ZOOM_RESET_PATH_ = 'zoom-reset.svg';
/**
* Width of the zoom controls.
* @type {number}
* @private
*/
Blockly.ZoomControls.prototype.WIDTH_ = 32;
Blockly.ZoomControls.prototype.WIDTH_ = 36;
/**
* Height of the zoom controls.
* @type {number}
* @private
*/
Blockly.ZoomControls.prototype.HEIGHT_ = 110;
Blockly.ZoomControls.prototype.HEIGHT_ = 124;
/**
* Distance between each zoom control.
* @type {number}
* @private
*/
Blockly.ZoomControls.prototype.MARGIN_BETWEEN_ = 8;
/**
* Distance between zoom controls and bottom edge of workspace.
* @type {number}
* @private
*/
Blockly.ZoomControls.prototype.MARGIN_BOTTOM_ = 20;
Blockly.ZoomControls.prototype.MARGIN_BOTTOM_ = 12;
/**
* Distance between zoom controls and right edge of workspace.
* @type {number}
* @private
*/
Blockly.ZoomControls.prototype.MARGIN_SIDE_ = 20;
Blockly.ZoomControls.prototype.MARGIN_SIDE_ = 12;
/**
* The SVG group containing the zoom controls.
@ -95,82 +123,79 @@ Blockly.ZoomControls.prototype.top_ = 0;
Blockly.ZoomControls.prototype.createDom = function() {
var workspace = this.workspace_;
/* Here's the markup that will be generated:
<g class="blocklyZoom">
<clippath id="blocklyZoomoutClipPath837493">
<rect width="32" height="32" y="77"></rect>
</clippath>
<image width="96" height="124" x="-64" y="-15" xlink:href="media/sprites.png"
clip-path="url(#blocklyZoomoutClipPath837493)"></image>
<clippath id="blocklyZoominClipPath837493">
<rect width="32" height="32" y="43"></rect>
</clippath>
<image width="96" height="124" x="-32" y="-49" xlink:href="media/sprites.png"
clip-path="url(#blocklyZoominClipPath837493)"></image>
<clippath id="blocklyZoomresetClipPath837493">
<rect width="32" height="32"></rect>
</clippath>
<image width="96" height="124" y="-92" xlink:href="media/sprites.png"
clip-path="url(#blocklyZoomresetClipPath837493)"></image>
<g class="blocklyZoom" transform="translate(822,594)">
<image width="36" height="36" y="0" xlink:href="../media/zoom-in.svg">
</image>
<image width="36" height="36" y="44" xlink:href="../media/zoom-out.svg">
</image>
<image width="36" height="36" y="88" xlink:href="../media/zoom-reset.svg">
</image>
</g>
*/
this.svgGroup_ = Blockly.utils.createSvgElement('g',
{'class': 'blocklyZoom'}, null);
var rnd = String(Math.random()).substring(2);
this.svgGroup_ = Blockly.utils.createSvgElement(
'g',
{'class': 'blocklyZoom'},
null
);
var clip = Blockly.utils.createSvgElement('clipPath',
{'id': 'blocklyZoomoutClipPath' + rnd},
this.svgGroup_);
Blockly.utils.createSvgElement('rect',
{'width': 32, 'height': 32, 'y': 77},
clip);
var zoomoutSvg = Blockly.utils.createSvgElement('image',
{'width': Blockly.SPRITE.width,
'height': Blockly.SPRITE.height, 'x': -64,
'y': -15,
'clip-path': 'url(#blocklyZoomoutClipPath' + rnd + ')'},
this.svgGroup_);
zoomoutSvg.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href',
workspace.options.pathToMedia + Blockly.SPRITE.url);
/**
* Zoom in control.
* @type {SVGElement}
*/
var zoominSvg = Blockly.utils.createSvgElement(
'image',
{
'width': this.WIDTH_,
'height': this.WIDTH_,
'y': 0
},
this.svgGroup_
);
zoominSvg.setAttributeNS(
'http://www.w3.org/1999/xlink',
'xlink:href',
workspace.options.pathToMedia + this.ZOOM_IN_PATH_
);
var clip = Blockly.utils.createSvgElement('clipPath',
{'id': 'blocklyZoominClipPath' + rnd},
this.svgGroup_);
Blockly.utils.createSvgElement('rect',
{'width': 32, 'height': 32, 'y': 43},
clip);
var zoominSvg = Blockly.utils.createSvgElement('image',
{'width': Blockly.SPRITE.width,
'height': Blockly.SPRITE.height,
'x': -32,
'y': -49,
'clip-path': 'url(#blocklyZoominClipPath' + rnd + ')'},
this.svgGroup_);
zoominSvg.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href',
workspace.options.pathToMedia + Blockly.SPRITE.url);
/**
* Zoom out control.
* @type {SVGElement}
*/
var zoomoutSvg = Blockly.utils.createSvgElement(
'image',
{
'width': this.WIDTH_,
'height': this.WIDTH_,
'y': (this.WIDTH_ * 1) + (this.MARGIN_BETWEEN_ * 1)
},
this.svgGroup_
);
zoomoutSvg.setAttributeNS(
'http://www.w3.org/1999/xlink',
'xlink:href',
workspace.options.pathToMedia + this.ZOOM_OUT_PATH_
);
var clip = Blockly.utils.createSvgElement('clipPath',
{'id': 'blocklyZoomresetClipPath' + rnd},
this.svgGroup_);
Blockly.utils.createSvgElement('rect',
{'width': 32, 'height': 32},
clip);
var zoomresetSvg = Blockly.utils.createSvgElement('image',
{'width': Blockly.SPRITE.width,
'height': Blockly.SPRITE.height, 'y': -92,
'clip-path': 'url(#blocklyZoomresetClipPath' + rnd + ')'},
this.svgGroup_);
zoomresetSvg.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href',
workspace.options.pathToMedia + Blockly.SPRITE.url);
/**
* Zoom reset control.
* @type {SVGElement}
*/
var zoomresetSvg = Blockly.utils.createSvgElement(
'image',
{
'width': this.WIDTH_,
'height': this.WIDTH_,
'y': (this.WIDTH_ * 2) + (this.MARGIN_BETWEEN_ * 2)
},
this.svgGroup_
);
zoomresetSvg.setAttributeNS(
'http://www.w3.org/1999/xlink',
'xlink:href',
workspace.options.pathToMedia + this.ZOOM_RESET_PATH_
);
// Attach event listeners.
Blockly.bindEventWithChecks_(zoomresetSvg, 'mousedown', null, function(e) {
workspace.markFocused();
workspace.setScale(workspace.options.zoomOptions.startScale);
workspace.scrollCenter();
Blockly.Touch.clearTouchIdentifier(); // Don't block future drags.
e.stopPropagation(); // Don't start a workspace scroll.
e.preventDefault(); // Stop double-clicking from selecting text.
});
Blockly.bindEventWithChecks_(zoominSvg, 'mousedown', null, function(e) {
workspace.markFocused();
workspace.zoomCenter(1);
@ -185,6 +210,14 @@ Blockly.ZoomControls.prototype.createDom = function() {
e.stopPropagation(); // Don't start a workspace scroll.
e.preventDefault(); // Stop double-clicking from selecting text.
});
Blockly.bindEventWithChecks_(zoomresetSvg, 'mousedown', null, function(e) {
workspace.markFocused();
workspace.setScale(workspace.options.zoomOptions.startScale);
workspace.scrollCenter();
Blockly.Touch.clearTouchIdentifier(); // Don't block future drags.
e.stopPropagation(); // Don't start a workspace scroll.
e.preventDefault(); // Stop double-clicking from selecting text.
});
return this.svgGroup_;
};

1
media/zoom-in.svg Normal file
View file

@ -0,0 +1 @@
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36"><defs><style>.cls-1{fill:#231f20;opacity:0.15;}.cls-2{fill:#fff;}.cls-3{opacity:0.75;}.cls-4{fill:none;stroke:#575e75;stroke-linecap:round;stroke-linejoin:round;stroke-width:1.5px;}</style></defs><title>zoom-in</title><circle class="cls-1" cx="18" cy="18" r="18"/><circle class="cls-2" cx="18" cy="18" r="16"/><g class="cls-3"><circle class="cls-4" cx="18" cy="18" r="7"/><line class="cls-4" x1="23" y1="23" x2="26" y2="26"/><line class="cls-4" x1="16" y1="18" x2="20" y2="18"/><line class="cls-4" x1="18" y1="16" x2="18" y2="20"/></g></svg>

After

Width:  |  Height:  |  Size: 634 B

1
media/zoom-out.svg Normal file
View file

@ -0,0 +1 @@
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36"><defs><style>.cls-1{fill:#231f20;opacity:0.15;}.cls-2{fill:#fff;}.cls-3{opacity:0.75;}.cls-4{fill:none;stroke:#575e75;stroke-linecap:round;stroke-linejoin:round;stroke-width:1.5px;}</style></defs><title>zoom-out</title><circle class="cls-1" cx="18" cy="18" r="18"/><circle class="cls-2" cx="18" cy="18" r="16"/><g class="cls-3"><circle class="cls-4" cx="18" cy="18" r="7"/><line class="cls-4" x1="23" y1="23" x2="26" y2="26"/><line class="cls-4" x1="16" y1="18" x2="20" y2="18"/></g></svg>

After

Width:  |  Height:  |  Size: 582 B

1
media/zoom-reset.svg Normal file
View file

@ -0,0 +1 @@
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36"><defs><style>.cls-1{fill:#231f20;opacity:0.15;}.cls-2{fill:#fff;}.cls-3{opacity:0.75;}.cls-4{fill:#575e75;}</style></defs><title>zoom-reset</title><circle class="cls-1" cx="18" cy="18" r="18"/><circle class="cls-2" cx="18" cy="18" r="16"/><g class="cls-3"><rect class="cls-4" x="13" y="14" width="10" height="2" rx="1" ry="1"/><rect class="cls-4" x="13" y="20" width="10" height="2" rx="1" ry="1"/></g></svg>

After

Width:  |  Height:  |  Size: 501 B

View file

@ -71,7 +71,6 @@
toolbox: toolbox,
toolboxPosition: side == 'top' || side == 'start' ? 'start' : 'end',
horizontalLayout: side == 'top' || side == 'bottom',
trashcan: true,
sounds: soundsEnabled,
zoom: {
controls: true,
@ -92,7 +91,7 @@
dragShadowOpacity: 0.6
}
});
if (sessionStorage) {
// Restore previously displayed text.
var text = sessionStorage.getItem('textarea');
@ -101,7 +100,7 @@
}
taChange();
}
if (sessionStorage) {
// Restore event logging state.
var state = sessionStorage.getItem('logEvents');