-
Notifications
You must be signed in to change notification settings - Fork 584
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
Scale Tutorial Text Alongside Workspace #9729
base: master
Are you sure you want to change the base?
Changes from 7 commits
462f987
1f56f2f
8da311f
c7f0bdc
30b0a2c
1811886
3e60074
fff1d72
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -152,6 +152,10 @@ export class ProjectView | |
private rootClasses: string[]; | ||
private pendingImport: pxt.Util.DeferredPromise<void>; | ||
|
||
private initialEditorScale: number; | ||
private tutorialInitialFontSize = 1.125; // rem | ||
private tutorialMaxFontSize = 2; // rem | ||
|
||
private highContrastSubscriber: data.DataSubscriber = { | ||
subscriptions: [], | ||
onDataChanged: () => { | ||
|
@@ -211,6 +215,7 @@ export class ProjectView | |
this.exitTutorial = this.exitTutorial.bind(this); | ||
this.setEditorOffset = this.setEditorOffset.bind(this); | ||
this.resetTutorialTemplateCode = this.resetTutorialTemplateCode.bind(this); | ||
this.onScaleChanged = this.onScaleChanged.bind(this); | ||
this.initSimulatorMessageHandlers(); | ||
|
||
// add user hint IDs and callback to hint manager | ||
|
@@ -1029,7 +1034,10 @@ export class ProjectView | |
} | ||
this.allEditors = [this.pxtJsonEditor, this.gitjsonEditor, this.blocksEditor, this.serialEditor, this.assetEditor, this.textEditor] | ||
this.allEditors.forEach(e => e.changeCallback = changeHandler) | ||
this.allEditors.forEach(e => e.onScaleChanged = this.onScaleChanged) | ||
|
||
this.editor = this.allEditors[this.allEditors.length - 1] | ||
this.initialEditorScale = undefined; | ||
} | ||
|
||
public UNSAFE_componentWillMount() { | ||
|
@@ -1108,6 +1116,8 @@ export class ProjectView | |
// subscribe to user preference changes (for simulator or non-render subscriptions) | ||
data.subscribe(this.highContrastSubscriber, auth.HIGHCONTRAST); | ||
data.subscribe(this.cloudStatusSubscriber, `${cloud.HEADER_CLOUDSTATE}:*`); | ||
|
||
document.getElementById("root").style.setProperty("--tutorialFontSize", `${this.tutorialInitialFontSize}rem`); | ||
} | ||
|
||
public componentWillUnmount() { | ||
|
@@ -1532,6 +1542,26 @@ export class ProjectView | |
} | ||
} | ||
|
||
onScaleChanged(oldScale: number, newScale: number) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. passing in the oldScale here to set the initial scale seems kinda fragile. is the initial scale not always the same value? and failing that, can't we just read it from blockly when we load the workspace? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's different between Monaco and Blockly. I'll see about reading it when we load the workspace. Should be do-able. |
||
if (this.isTutorial && oldScale !== newScale) { | ||
if (this.initialEditorScale === undefined) { | ||
this.initialEditorScale = oldScale; | ||
} | ||
|
||
const root = document.getElementById("root"); | ||
if (root && newScale <= this.initialEditorScale) { | ||
// Do not shrink the text beyond its initial size. | ||
root.style.setProperty("--tutorialFontSize", `${this.tutorialInitialFontSize}rem`); | ||
} else if (root) { | ||
// Increase font size to match the editor's % zoom. | ||
const maxEditorScale = this.editor.getMaxScale(); | ||
const zoomAmt = (newScale - this.initialEditorScale) / (maxEditorScale - this.initialEditorScale); | ||
const newTutorialFontSize = this.tutorialInitialFontSize + (this.tutorialMaxFontSize - this.tutorialInitialFontSize) * zoomAmt; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you explain this math a bit? I'm having a hard time understanding why we want to multiply zoom amount with the difference of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This may be tricky without a whiteboard, but I'll give it a try :) So the question we're trying to answer is how far between the minimum (initial) font and the maximum font we want the new font size to be. To do this, we're basically mapping how far between the editor's min and max scale we are (as a fraction between 0 and 1) and we want to be that same fraction between the font's min and max. We start with the editor's Then to get the font size from that, we kind of do the opposite. We need to figure out where, between the Here's a diagram of questionable value: Also happy to hop on a call and talk through it, if that'd be helpful. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, this explanation was extremely helpful! Thank you for that clarification!! |
||
root.style.setProperty("--tutorialFontSize", `${newTutorialFontSize}rem`); | ||
} | ||
} | ||
} | ||
|
||
/////////////////////////////////////////////////////////// | ||
//////////// Load header ///////////// | ||
/////////////////////////////////////////////////////////// | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -31,6 +31,7 @@ export class Editor extends toolboxeditor.ToolboxEditor { | |
compilationResult: pxt.blocks.BlockCompilationResult; | ||
isFirstBlocklyLoad = true; | ||
functionsDialog: CreateFunctionDialog = null; | ||
onScaleChanged: (oldScale: number, newScale: number) => void; | ||
|
||
showCategories: boolean = true; | ||
breakpointsByBlock: pxt.Map<number>; // Map block id --> breakpoint ID | ||
|
@@ -48,6 +49,10 @@ export class Editor extends toolboxeditor.ToolboxEditor { | |
|
||
public nsMap: pxt.Map<toolbox.BlockDefinition[]>; | ||
|
||
// Blockly fires a scale event when it loads, but the user hasn't actually changed the scale. | ||
// We use this flag to ignore that initial event. | ||
private initialScaleSet: boolean = false; | ||
|
||
constructor(parent: pxt.editor.IProjectView) { | ||
super(parent); | ||
|
||
|
@@ -581,7 +586,6 @@ export class Editor extends toolboxeditor.ToolboxEditor { | |
Blockly.Events.UI, | ||
Blockly.Events.SELECTED, | ||
Blockly.Events.CLICK, | ||
Blockly.Events.VIEWPORT_CHANGE, | ||
Blockly.Events.BUBBLE_OPEN | ||
]; | ||
|
||
|
@@ -636,6 +640,15 @@ export class Editor extends toolboxeditor.ToolboxEditor { | |
} | ||
} | ||
} | ||
else if (ev.type === Blockly.Events.VIEWPORT_CHANGE) { | ||
const viewportChangeEvent = ev as Blockly.Events.ViewportChange; | ||
if (this.initialScaleSet && viewportChangeEvent.oldScale !== viewportChangeEvent.scale) { | ||
if (this.onScaleChanged) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is it possible that the function doesn't get initialized? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, it's optional. For example, we only set it at the moment if we're in a tutorial, otherwise it remains undefined. I should probably combine this with the above if statement though. No real reason to break it out into a separate one :) |
||
this.onScaleChanged(viewportChangeEvent.oldScale, viewportChangeEvent.scale); | ||
} | ||
} | ||
this.initialScaleSet = true; | ||
} | ||
|
||
// reset tutorial hint animation on any blockly event | ||
if (this.parent.state.tutorialOptions != undefined) { | ||
|
@@ -753,6 +766,11 @@ export class Editor extends toolboxeditor.ToolboxEditor { | |
this.editor.zoomCenter(-0.8); | ||
} | ||
|
||
getMaxScale() { | ||
if (!this.editor) return undefined; | ||
return this.editor.options.zoomOptions.maxScale; | ||
} | ||
|
||
setScale(scale: number) { | ||
if (!this.editor) return; | ||
if (scale != this.editor.scale) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i would define this in css instead of adding it here and just override it when the scale changes. that way it'll always have at least some value... anything set on the root directly will override whatever is in the css styles.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I went back and forth on this. Decided to put it here to keep it all in once place, but happy to move it back to css.