scratch-blocks 2.0.2 → 2.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.nvmrc +1 -1
- package/commitlint.config.js +2 -2
- package/dist/main.mjs +1 -2
- package/dist/types/msg/scratch_msgs.d.ts.map +1 -1
- package/dist/types/src/block_reporting.d.ts.map +1 -1
- package/dist/types/src/blocks/colour.d.ts +0 -19
- package/dist/types/src/blocks/colour.d.ts.map +1 -1
- package/dist/types/src/blocks/control.d.ts +0 -19
- package/dist/types/src/blocks/control.d.ts.map +1 -1
- package/dist/types/src/blocks/data.d.ts +0 -19
- package/dist/types/src/blocks/data.d.ts.map +1 -1
- package/dist/types/src/blocks/event.d.ts +0 -19
- package/dist/types/src/blocks/event.d.ts.map +1 -1
- package/dist/types/src/blocks/looks.d.ts +0 -19
- package/dist/types/src/blocks/looks.d.ts.map +1 -1
- package/dist/types/src/blocks/math.d.ts +0 -19
- package/dist/types/src/blocks/math.d.ts.map +1 -1
- package/dist/types/src/blocks/matrix.d.ts +0 -19
- package/dist/types/src/blocks/matrix.d.ts.map +1 -1
- package/dist/types/src/blocks/motion.d.ts +0 -19
- package/dist/types/src/blocks/motion.d.ts.map +1 -1
- package/dist/types/src/blocks/note.d.ts +0 -19
- package/dist/types/src/blocks/note.d.ts.map +1 -1
- package/dist/types/src/blocks/operators.d.ts +0 -19
- package/dist/types/src/blocks/operators.d.ts.map +1 -1
- package/dist/types/src/blocks/procedures.d.ts +7 -10
- package/dist/types/src/blocks/procedures.d.ts.map +1 -1
- package/dist/types/src/blocks/sensing.d.ts +0 -19
- package/dist/types/src/blocks/sensing.d.ts.map +1 -1
- package/dist/types/src/blocks/sound.d.ts +0 -19
- package/dist/types/src/blocks/sound.d.ts.map +1 -1
- package/dist/types/src/blocks/text.d.ts +0 -19
- package/dist/types/src/blocks/text.d.ts.map +1 -1
- package/dist/types/src/blocks/vertical_extensions.d.ts +0 -19
- package/dist/types/src/blocks/vertical_extensions.d.ts.map +1 -1
- package/dist/types/src/checkable_continuous_flyout.d.ts +2 -7
- package/dist/types/src/checkable_continuous_flyout.d.ts.map +1 -1
- package/dist/types/src/checkbox_bubble.d.ts +13 -12
- package/dist/types/src/checkbox_bubble.d.ts.map +1 -1
- package/dist/types/src/colours.d.ts.map +1 -1
- package/dist/types/src/constants.d.ts +0 -7
- package/dist/types/src/constants.d.ts.map +1 -1
- package/dist/types/src/context_menu_items.d.ts +0 -5
- package/dist/types/src/context_menu_items.d.ts.map +1 -1
- package/dist/types/src/data_category.d.ts +2 -4
- package/dist/types/src/data_category.d.ts.map +1 -1
- package/dist/types/src/events/events_block_comment_base.d.ts +2 -3
- package/dist/types/src/events/events_block_comment_base.d.ts.map +1 -1
- package/dist/types/src/events/events_block_comment_change.d.ts +0 -5
- package/dist/types/src/events/events_block_comment_change.d.ts.map +1 -1
- package/dist/types/src/events/events_block_comment_collapse.d.ts +0 -5
- package/dist/types/src/events/events_block_comment_collapse.d.ts.map +1 -1
- package/dist/types/src/events/events_block_comment_create.d.ts +0 -5
- package/dist/types/src/events/events_block_comment_create.d.ts.map +1 -1
- package/dist/types/src/events/events_block_comment_delete.d.ts +0 -5
- package/dist/types/src/events/events_block_comment_delete.d.ts.map +1 -1
- package/dist/types/src/events/events_block_comment_move.d.ts +0 -5
- package/dist/types/src/events/events_block_comment_move.d.ts.map +1 -1
- package/dist/types/src/events/events_block_comment_resize.d.ts +0 -5
- package/dist/types/src/events/events_block_comment_resize.d.ts.map +1 -1
- package/dist/types/src/events/events_block_drag_end.d.ts +1 -2
- package/dist/types/src/events/events_block_drag_end.d.ts.map +1 -1
- package/dist/types/src/events/events_block_drag_outside.d.ts +1 -2
- package/dist/types/src/events/events_block_drag_outside.d.ts.map +1 -1
- package/dist/types/src/events/events_scratch_variable_create.d.ts +0 -5
- package/dist/types/src/events/events_scratch_variable_create.d.ts.map +1 -1
- package/dist/types/src/fields/field_colour_slider.d.ts +7 -9
- package/dist/types/src/fields/field_colour_slider.d.ts.map +1 -1
- package/dist/types/src/fields/field_matrix.d.ts +0 -19
- package/dist/types/src/fields/field_matrix.d.ts.map +1 -1
- package/dist/types/src/fields/field_note.d.ts +8 -23
- package/dist/types/src/fields/field_note.d.ts.map +1 -1
- package/dist/types/src/fields/field_textinput_removable.d.ts +2 -4
- package/dist/types/src/fields/field_textinput_removable.d.ts.map +1 -1
- package/dist/types/src/fields/field_variable_getter.d.ts +0 -19
- package/dist/types/src/fields/field_variable_getter.d.ts.map +1 -1
- package/dist/types/src/fields/field_vertical_separator.d.ts +0 -19
- package/dist/types/src/fields/field_vertical_separator.d.ts.map +1 -1
- package/dist/types/src/fields/scratch_field_angle.d.ts +0 -19
- package/dist/types/src/fields/scratch_field_angle.d.ts.map +1 -1
- package/dist/types/src/fields/scratch_field_dropdown.d.ts +0 -5
- package/dist/types/src/fields/scratch_field_dropdown.d.ts.map +1 -1
- package/dist/types/src/fields/scratch_field_number.d.ts +0 -19
- package/dist/types/src/fields/scratch_field_number.d.ts.map +1 -1
- package/dist/types/src/fields/scratch_field_variable.d.ts +4 -7
- package/dist/types/src/fields/scratch_field_variable.d.ts.map +1 -1
- package/dist/types/src/flyout_checkbox_icon.d.ts +2 -3
- package/dist/types/src/flyout_checkbox_icon.d.ts.map +1 -1
- package/dist/types/src/glows.d.ts +1 -3
- package/dist/types/src/glows.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +50 -55
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/procedures.d.ts +6 -8
- package/dist/types/src/procedures.d.ts.map +1 -1
- package/dist/types/src/recyclable_block_flyout_inflater.d.ts +3 -5
- package/dist/types/src/recyclable_block_flyout_inflater.d.ts.map +1 -1
- package/dist/types/src/renderer/bowler_hat.d.ts +2 -3
- package/dist/types/src/renderer/bowler_hat.d.ts.map +1 -1
- package/dist/types/src/renderer/cat/cat_face.d.ts +6 -5
- package/dist/types/src/renderer/cat/cat_face.d.ts.map +1 -1
- package/dist/types/src/renderer/cat/constants.d.ts +2 -2
- package/dist/types/src/renderer/cat/constants.d.ts.map +1 -1
- package/dist/types/src/renderer/cat/drawer.d.ts +3 -4
- package/dist/types/src/renderer/cat/drawer.d.ts.map +1 -1
- package/dist/types/src/renderer/cat/path_object.d.ts +2 -3
- package/dist/types/src/renderer/cat/path_object.d.ts.map +1 -1
- package/dist/types/src/renderer/cat/render_info.d.ts +3 -4
- package/dist/types/src/renderer/cat/render_info.d.ts.map +1 -1
- package/dist/types/src/renderer/cat/renderer.d.ts +6 -7
- package/dist/types/src/renderer/cat/renderer.d.ts.map +1 -1
- package/dist/types/src/renderer/constants.d.ts +4 -4
- package/dist/types/src/renderer/constants.d.ts.map +1 -1
- package/dist/types/src/renderer/drawer.d.ts +5 -4
- package/dist/types/src/renderer/drawer.d.ts.map +1 -1
- package/dist/types/src/renderer/path_object.d.ts +1 -3
- package/dist/types/src/renderer/path_object.d.ts.map +1 -1
- package/dist/types/src/renderer/render_info.d.ts +3 -4
- package/dist/types/src/renderer/render_info.d.ts.map +1 -1
- package/dist/types/src/renderer/renderer.d.ts +8 -15
- package/dist/types/src/renderer/renderer.d.ts.map +1 -1
- package/dist/types/src/scratch_block_paster.d.ts +0 -5
- package/dist/types/src/scratch_block_paster.d.ts.map +1 -1
- package/dist/types/src/scratch_blocks_utils.d.ts +0 -20
- package/dist/types/src/scratch_blocks_utils.d.ts.map +1 -1
- package/dist/types/src/scratch_comment_bubble.d.ts +1 -4
- package/dist/types/src/scratch_comment_bubble.d.ts.map +1 -1
- package/dist/types/src/scratch_comment_icon.d.ts +2 -3
- package/dist/types/src/scratch_comment_icon.d.ts.map +1 -1
- package/dist/types/src/scratch_connection_checker.d.ts +0 -5
- package/dist/types/src/scratch_connection_checker.d.ts.map +1 -1
- package/dist/types/src/scratch_continuous_category.d.ts +5 -5
- package/dist/types/src/scratch_continuous_category.d.ts.map +1 -1
- package/dist/types/src/scratch_continuous_toolbox.d.ts +3 -6
- package/dist/types/src/scratch_continuous_toolbox.d.ts.map +1 -1
- package/dist/types/src/scratch_dragger.d.ts +3 -12
- package/dist/types/src/scratch_dragger.d.ts.map +1 -1
- package/dist/types/src/scratch_insertion_marker_previewer.d.ts +0 -5
- package/dist/types/src/scratch_insertion_marker_previewer.d.ts.map +1 -1
- package/dist/types/src/scratch_variable_map.d.ts +0 -5
- package/dist/types/src/scratch_variable_map.d.ts.map +1 -1
- package/dist/types/src/scratch_variable_model.d.ts +1 -2
- package/dist/types/src/scratch_variable_model.d.ts.map +1 -1
- package/dist/types/src/scratch_zoom_controls.d.ts +4 -6
- package/dist/types/src/scratch_zoom_controls.d.ts.map +1 -1
- package/dist/types/src/shadows.d.ts +2 -2
- package/dist/types/src/shadows.d.ts.map +1 -1
- package/dist/types/src/status_indicator_label.d.ts +4 -6
- package/dist/types/src/status_indicator_label.d.ts.map +1 -1
- package/dist/types/src/status_indicator_label_flyout_inflater.d.ts +1 -6
- package/dist/types/src/status_indicator_label_flyout_inflater.d.ts.map +1 -1
- package/dist/types/src/variables.d.ts +4 -8
- package/dist/types/src/variables.d.ts.map +1 -1
- package/dist/types/src/xml.d.ts +2 -3
- package/dist/types/src/xml.d.ts.map +1 -1
- package/dist/types/tests/jsunit/block_test.d.ts.map +1 -1
- package/dist/types/tests/jsunit/connection_db_test.d.ts.map +1 -1
- package/dist/types/tests/jsunit/connection_test.d.ts.map +1 -1
- package/dist/types/tests/jsunit/event_test.d.ts.map +1 -1
- package/dist/types/tests/jsunit/extensions_test.d.ts.map +1 -1
- package/dist/types/tests/jsunit/field_number_test.d.ts.map +1 -1
- package/dist/types/tests/jsunit/field_test.d.ts.map +1 -1
- package/dist/types/tests/jsunit/field_variable_getter_test.d.ts.map +1 -1
- package/dist/types/tests/jsunit/field_variable_test.d.ts.map +1 -1
- package/dist/types/tests/jsunit/gesture_test.d.ts.map +1 -1
- package/dist/types/tests/jsunit/input_test.d.ts +1 -0
- package/dist/types/tests/jsunit/input_test.d.ts.map +1 -1
- package/dist/types/tests/jsunit/json_test.d.ts.map +1 -1
- package/dist/types/tests/jsunit/names_test.d.ts.map +1 -1
- package/dist/types/tests/jsunit/procedure_test.d.ts.map +1 -1
- package/dist/types/tests/jsunit/scratch_block_comment_test.d.ts.map +1 -1
- package/dist/types/tests/jsunit/svg_test.d.ts.map +1 -1
- package/dist/types/tests/jsunit/test_utilities.d.ts.map +1 -1
- package/dist/types/tests/jsunit/utils_test.d.ts.map +1 -1
- package/dist/types/tests/jsunit/variable_map_test.d.ts.map +1 -1
- package/dist/types/tests/jsunit/variable_model_test.d.ts.map +1 -1
- package/dist/types/tests/jsunit/widget_div_test.d.ts.map +1 -1
- package/dist/types/tests/jsunit/workspace_comment_test.d.ts.map +1 -1
- package/dist/types/tests/jsunit/workspace_test.d.ts.map +1 -1
- package/dist/types/tests/jsunit/workspace_undo_redo_test.d.ts.map +1 -1
- package/dist/types/tests/jsunit/xml_test.d.ts.map +1 -1
- package/dist/types/tests/workspace_svg/workspace_svg_test.d.ts.map +1 -1
- package/eslint.config.mjs +69 -0
- package/i18n/create_scratch_msgs.js +44 -45
- package/i18n/js_to_json.js +40 -32
- package/i18n/json_to_js.js +37 -37
- package/i18n/sync_tx_translations.js +64 -65
- package/i18n/test_scratch_msgs.js +66 -63
- package/msg/js/en.js +289 -287
- package/msg/json/en.json +284 -284
- package/msg/messages.js +289 -287
- package/msg/scratch_msgs.js +22959 -22970
- package/package.json +13 -10
- package/prettier.config.mjs +3 -0
- package/release.config.js +7 -7
- package/renovate.json5 +7 -9
- package/src/block_reporting.ts +15 -18
- package/src/blocks/colour.ts +12 -15
- package/src/blocks/control.ts +167 -177
- package/src/blocks/data.ts +225 -292
- package/src/blocks/event.ts +121 -123
- package/src/blocks/looks.ts +165 -167
- package/src/blocks/math.ts +44 -46
- package/src/blocks/matrix.ts +11 -13
- package/src/blocks/motion.ts +151 -153
- package/src/blocks/note.ts +11 -13
- package/src/blocks/operators.ts +158 -160
- package/src/blocks/procedures.ts +488 -536
- package/src/blocks/sensing.ts +163 -165
- package/src/blocks/sound.ts +58 -60
- package/src/blocks/text.ts +10 -12
- package/src/blocks/vertical_extensions.ts +86 -102
- package/src/checkable_continuous_flyout.ts +25 -42
- package/src/checkbox_bubble.ts +83 -100
- package/src/colours.ts +35 -37
- package/src/constants.ts +22 -29
- package/src/context_menu_items.ts +56 -81
- package/src/css.ts +3 -4
- package/src/data_category.ts +136 -250
- package/src/events/events_block_comment_base.ts +21 -31
- package/src/events/events_block_comment_change.ts +21 -42
- package/src/events/events_block_comment_collapse.ts +22 -43
- package/src/events/events_block_comment_create.ts +29 -46
- package/src/events/events_block_comment_delete.ts +10 -19
- package/src/events/events_block_comment_move.ts +27 -52
- package/src/events/events_block_comment_resize.ts +28 -55
- package/src/events/events_block_drag_end.ts +16 -26
- package/src/events/events_block_drag_outside.ts +12 -22
- package/src/events/events_scratch_variable_create.ts +33 -56
- package/src/fields/field_colour_slider.ts +173 -228
- package/src/fields/field_matrix.ts +200 -269
- package/src/fields/field_note.ts +272 -377
- package/src/fields/field_textinput_removable.ts +25 -40
- package/src/fields/field_variable_getter.ts +26 -31
- package/src/fields/field_vertical_separator.ts +19 -24
- package/src/fields/scratch_field_angle.ts +150 -186
- package/src/fields/scratch_field_dropdown.ts +15 -19
- package/src/fields/scratch_field_number.ts +123 -180
- package/src/fields/scratch_field_variable.ts +52 -73
- package/src/flyout_checkbox_icon.ts +18 -28
- package/src/glows.ts +51 -58
- package/src/index.ts +119 -133
- package/src/procedures.ts +144 -211
- package/src/recyclable_block_flyout_inflater.ts +14 -25
- package/src/renderer/bowler_hat.ts +6 -8
- package/src/renderer/cat/cat_face.ts +98 -99
- package/src/renderer/cat/constants.ts +67 -87
- package/src/renderer/cat/drawer.ts +21 -27
- package/src/renderer/cat/path_object.ts +3 -5
- package/src/renderer/cat/render_info.ts +5 -8
- package/src/renderer/cat/renderer.ts +11 -15
- package/src/renderer/constants.ts +34 -49
- package/src/renderer/drawer.ts +35 -51
- package/src/renderer/path_object.ts +13 -15
- package/src/renderer/render_info.ts +36 -56
- package/src/renderer/renderer.ts +16 -29
- package/src/scratch_block_paster.ts +12 -20
- package/src/scratch_blocks_utils.ts +4 -7
- package/src/scratch_comment_bubble.ts +70 -101
- package/src/scratch_comment_icon.ts +74 -123
- package/src/scratch_connection_checker.ts +22 -17
- package/src/scratch_continuous_category.ts +24 -28
- package/src/scratch_continuous_toolbox.ts +20 -27
- package/src/scratch_dragger.ts +54 -86
- package/src/scratch_insertion_marker_previewer.ts +6 -11
- package/src/scratch_variable_map.ts +5 -12
- package/src/scratch_variable_model.ts +4 -11
- package/src/scratch_zoom_controls.ts +101 -156
- package/src/shadows.ts +32 -37
- package/src/status_indicator_label.ts +54 -67
- package/src/status_indicator_label_flyout_inflater.ts +11 -21
- package/src/variables.ts +89 -138
- package/src/xml.ts +21 -35
- package/tsconfig.json +2 -6
- package/types/continuous-toolbox.d.ts +1 -1
- package/dist/main.mjs.LICENSE.txt +0 -163
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @license
|
|
3
2
|
* Copyright 2026 Scratch Foundation
|
|
4
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
4
|
*/
|
|
6
|
-
|
|
7
|
-
import * as Blockly from "blockly/core";
|
|
5
|
+
import * as Blockly from 'blockly/core'
|
|
8
6
|
|
|
9
7
|
/**
|
|
10
8
|
* Scratch-specific zoom controls that use separate SVG files for each button
|
|
@@ -13,112 +11,80 @@ import * as Blockly from "blockly/core";
|
|
|
13
11
|
* default vs. high-contrast), enabling per-mode icon designs.
|
|
14
12
|
*/
|
|
15
13
|
export class ScratchZoomControls implements Blockly.IPositionable {
|
|
16
|
-
id =
|
|
14
|
+
id = 'zoomControls'
|
|
17
15
|
|
|
18
|
-
private boundEvents: Blockly.browserEvents.Data[] = []
|
|
16
|
+
private boundEvents: Blockly.browserEvents.Data[] = []
|
|
19
17
|
|
|
20
|
-
private svgGroup: SVGGElement | null = null
|
|
21
|
-
private zoomInGroup: SVGGElement | null = null
|
|
22
|
-
private zoomOutGroup: SVGGElement | null = null
|
|
23
|
-
private zoomResetGroup: SVGGElement | null = null
|
|
18
|
+
private svgGroup: SVGGElement | null = null
|
|
19
|
+
private zoomInGroup: SVGGElement | null = null
|
|
20
|
+
private zoomOutGroup: SVGGElement | null = null
|
|
21
|
+
private zoomResetGroup: SVGGElement | null = null
|
|
24
22
|
|
|
25
23
|
/** Rendered width and height of each button, in SVG units. */
|
|
26
|
-
private readonly SIZE = 36
|
|
24
|
+
private readonly SIZE = 36
|
|
27
25
|
|
|
28
26
|
/** Gap between zoom in and zoom out buttons. */
|
|
29
|
-
private readonly SMALL_SPACING = 4
|
|
27
|
+
private readonly SMALL_SPACING = 4
|
|
30
28
|
|
|
31
29
|
/** Gap between zoom in/out group and zoom reset button. */
|
|
32
|
-
private readonly LARGE_SPACING = 12
|
|
30
|
+
private readonly LARGE_SPACING = 12
|
|
33
31
|
|
|
34
32
|
/** Distance from the workspace edge, vertical axis. */
|
|
35
|
-
private readonly MARGIN_VERTICAL = 20
|
|
33
|
+
private readonly MARGIN_VERTICAL = 20
|
|
36
34
|
|
|
37
35
|
/** Distance from the workspace edge, horizontal axis. */
|
|
38
|
-
private readonly MARGIN_HORIZONTAL = 20
|
|
36
|
+
private readonly MARGIN_HORIZONTAL = 20
|
|
39
37
|
|
|
40
|
-
private left = 0
|
|
41
|
-
private top = 0
|
|
42
|
-
private initialized = false
|
|
38
|
+
private left = 0
|
|
39
|
+
private top = 0
|
|
40
|
+
private initialized = false
|
|
43
41
|
|
|
44
42
|
constructor(private readonly workspace: Blockly.WorkspaceSvg) {}
|
|
45
43
|
|
|
46
44
|
/**
|
|
47
45
|
* Creates the zoom controls DOM.
|
|
48
|
-
*
|
|
49
46
|
* @returns The root SVG group element.
|
|
50
47
|
*/
|
|
51
48
|
createDom(): SVGGElement {
|
|
52
|
-
this.svgGroup = Blockly.utils.dom.createSvgElement(
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
this.zoomOutGroup = this.createButtonGroup(
|
|
60
|
-
"blocklyZoomOut",
|
|
61
|
-
`${media}zoom-out.svg`
|
|
62
|
-
);
|
|
63
|
-
this.svgGroup.appendChild(this.zoomOutGroup);
|
|
49
|
+
this.svgGroup = Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.G, {})
|
|
50
|
+
|
|
51
|
+
const media = this.workspace.options.pathToMedia
|
|
52
|
+
|
|
53
|
+
this.zoomOutGroup = this.createButtonGroup('blocklyZoomOut', `${media}zoom-out.svg`)
|
|
54
|
+
this.svgGroup.appendChild(this.zoomOutGroup)
|
|
64
55
|
this.boundEvents.push(
|
|
65
|
-
Blockly.browserEvents.conditionalBind(
|
|
66
|
-
|
|
67
|
-
"pointerdown",
|
|
68
|
-
null,
|
|
69
|
-
this.zoom.bind(this, -1)
|
|
70
|
-
)
|
|
71
|
-
);
|
|
56
|
+
Blockly.browserEvents.conditionalBind(this.zoomOutGroup, 'pointerdown', null, this.zoom.bind(this, -1)),
|
|
57
|
+
)
|
|
72
58
|
|
|
73
|
-
this.zoomInGroup = this.createButtonGroup(
|
|
74
|
-
|
|
75
|
-
`${media}zoom-in.svg`
|
|
76
|
-
);
|
|
77
|
-
this.svgGroup.appendChild(this.zoomInGroup);
|
|
59
|
+
this.zoomInGroup = this.createButtonGroup('blocklyZoomIn', `${media}zoom-in.svg`)
|
|
60
|
+
this.svgGroup.appendChild(this.zoomInGroup)
|
|
78
61
|
this.boundEvents.push(
|
|
79
|
-
Blockly.browserEvents.conditionalBind(
|
|
80
|
-
|
|
81
|
-
"pointerdown",
|
|
82
|
-
null,
|
|
83
|
-
this.zoom.bind(this, 1)
|
|
84
|
-
)
|
|
85
|
-
);
|
|
62
|
+
Blockly.browserEvents.conditionalBind(this.zoomInGroup, 'pointerdown', null, this.zoom.bind(this, 1)),
|
|
63
|
+
)
|
|
86
64
|
|
|
87
65
|
if (this.workspace.isMovable()) {
|
|
88
66
|
// Only add zoom reset if the workspace is movable — if it isn't,
|
|
89
67
|
// zooming to center could push blocks off the visible edges.
|
|
90
|
-
this.zoomResetGroup = this.createButtonGroup(
|
|
91
|
-
|
|
92
|
-
`${media}zoom-reset.svg`
|
|
93
|
-
);
|
|
94
|
-
this.svgGroup.appendChild(this.zoomResetGroup);
|
|
68
|
+
this.zoomResetGroup = this.createButtonGroup('blocklyZoomReset', `${media}zoom-reset.svg`)
|
|
69
|
+
this.svgGroup.appendChild(this.zoomResetGroup)
|
|
95
70
|
this.boundEvents.push(
|
|
96
|
-
Blockly.browserEvents.conditionalBind(
|
|
97
|
-
|
|
98
|
-
"pointerdown",
|
|
99
|
-
null,
|
|
100
|
-
this.resetZoom.bind(this)
|
|
101
|
-
)
|
|
102
|
-
);
|
|
71
|
+
Blockly.browserEvents.conditionalBind(this.zoomResetGroup, 'pointerdown', null, this.resetZoom.bind(this)),
|
|
72
|
+
)
|
|
103
73
|
}
|
|
104
74
|
|
|
105
|
-
return this.svgGroup
|
|
75
|
+
return this.svgGroup
|
|
106
76
|
}
|
|
107
77
|
|
|
108
78
|
/**
|
|
109
79
|
* Creates an SVG group containing one zoom button image.
|
|
110
|
-
*
|
|
111
80
|
* @param extraClass Additional CSS class to add alongside `blocklyZoom`.
|
|
112
81
|
* @param imageHref URL of the SVG icon to display.
|
|
113
82
|
* @returns The button group element.
|
|
114
83
|
*/
|
|
115
|
-
private createButtonGroup(
|
|
116
|
-
extraClass: string,
|
|
117
|
-
imageHref: string
|
|
118
|
-
): SVGGElement {
|
|
84
|
+
private createButtonGroup(extraClass: string, imageHref: string): SVGGElement {
|
|
119
85
|
const group = Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.G, {
|
|
120
86
|
class: `blocklyZoom ${extraClass}`,
|
|
121
|
-
})
|
|
87
|
+
})
|
|
122
88
|
|
|
123
89
|
const image = Blockly.utils.dom.createSvgElement(
|
|
124
90
|
Blockly.utils.Svg.IMAGE,
|
|
@@ -126,15 +92,11 @@ export class ScratchZoomControls implements Blockly.IPositionable {
|
|
|
126
92
|
width: this.SIZE,
|
|
127
93
|
height: this.SIZE,
|
|
128
94
|
},
|
|
129
|
-
group
|
|
130
|
-
)
|
|
131
|
-
image.setAttributeNS(
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
imageHref
|
|
135
|
-
);
|
|
136
|
-
|
|
137
|
-
return group;
|
|
95
|
+
group,
|
|
96
|
+
)
|
|
97
|
+
image.setAttributeNS(Blockly.utils.dom.XLINK_NS, 'xlink:href', imageHref)
|
|
98
|
+
|
|
99
|
+
return group
|
|
138
100
|
}
|
|
139
101
|
|
|
140
102
|
/** Registers this component with the workspace's ComponentManager. */
|
|
@@ -143,57 +105,49 @@ export class ScratchZoomControls implements Blockly.IPositionable {
|
|
|
143
105
|
component: this,
|
|
144
106
|
weight: 2,
|
|
145
107
|
capabilities: [Blockly.ComponentManager.Capability.POSITIONABLE],
|
|
146
|
-
})
|
|
147
|
-
this.initialized = true
|
|
108
|
+
})
|
|
109
|
+
this.initialized = true
|
|
148
110
|
}
|
|
149
111
|
|
|
150
112
|
/** Removes this component from the DOM and ComponentManager. */
|
|
151
113
|
dispose() {
|
|
152
|
-
this.workspace.getComponentManager().removeComponent(
|
|
114
|
+
this.workspace.getComponentManager().removeComponent('zoomControls')
|
|
153
115
|
if (this.svgGroup) {
|
|
154
|
-
Blockly.utils.dom.removeNode(this.svgGroup)
|
|
116
|
+
Blockly.utils.dom.removeNode(this.svgGroup)
|
|
155
117
|
}
|
|
156
118
|
for (const event of this.boundEvents) {
|
|
157
|
-
Blockly.browserEvents.unbind(event)
|
|
119
|
+
Blockly.browserEvents.unbind(event)
|
|
158
120
|
}
|
|
159
|
-
this.boundEvents.length = 0
|
|
121
|
+
this.boundEvents.length = 0
|
|
160
122
|
}
|
|
161
123
|
|
|
162
124
|
/**
|
|
163
125
|
* Returns the bounding rectangle of the zoom controls in pixels relative to
|
|
164
126
|
* the Blockly injection div.
|
|
127
|
+
* @returns The bounding rectangle, or null if not yet positioned.
|
|
165
128
|
*/
|
|
166
129
|
getBoundingRectangle(): Blockly.utils.Rect | null {
|
|
167
|
-
let height = this.SMALL_SPACING + 2 * this.SIZE
|
|
130
|
+
let height = this.SMALL_SPACING + 2 * this.SIZE
|
|
168
131
|
if (this.zoomResetGroup) {
|
|
169
|
-
height += this.LARGE_SPACING + this.SIZE
|
|
132
|
+
height += this.LARGE_SPACING + this.SIZE
|
|
170
133
|
}
|
|
171
|
-
return new Blockly.utils.Rect(
|
|
172
|
-
this.top,
|
|
173
|
-
this.top + height,
|
|
174
|
-
this.left,
|
|
175
|
-
this.left + this.SIZE
|
|
176
|
-
);
|
|
134
|
+
return new Blockly.utils.Rect(this.top, this.top + height, this.left, this.left + this.SIZE)
|
|
177
135
|
}
|
|
178
136
|
|
|
179
137
|
/**
|
|
180
138
|
* Positions the zoom controls in the corner opposite the toolbox, bumping
|
|
181
139
|
* down (or up) to avoid overlapping other positioned UI elements.
|
|
140
|
+
* @param metrics The current workspace UI metrics.
|
|
141
|
+
* @param savedPositions Bounding rectangles of already-placed UI elements to avoid overlapping.
|
|
182
142
|
*/
|
|
183
|
-
position(
|
|
184
|
-
|
|
185
|
-
savedPositions: Blockly.utils.Rect[]
|
|
186
|
-
) {
|
|
187
|
-
if (!this.initialized) return;
|
|
143
|
+
position(metrics: Blockly.MetricsManager.UiMetrics, savedPositions: Blockly.utils.Rect[]) {
|
|
144
|
+
if (!this.initialized) return
|
|
188
145
|
|
|
189
|
-
const cornerPosition = Blockly.uiPosition.getCornerOppositeToolbox(
|
|
190
|
-
this.workspace,
|
|
191
|
-
metrics
|
|
192
|
-
);
|
|
146
|
+
const cornerPosition = Blockly.uiPosition.getCornerOppositeToolbox(this.workspace, metrics)
|
|
193
147
|
|
|
194
|
-
let height = this.SMALL_SPACING + 2 * this.SIZE
|
|
148
|
+
let height = this.SMALL_SPACING + 2 * this.SIZE
|
|
195
149
|
if (this.zoomResetGroup) {
|
|
196
|
-
height += this.LARGE_SPACING + this.SIZE
|
|
150
|
+
height += this.LARGE_SPACING + this.SIZE
|
|
197
151
|
}
|
|
198
152
|
|
|
199
153
|
const startRect = Blockly.uiPosition.getStartPositionRect(
|
|
@@ -202,108 +156,99 @@ export class ScratchZoomControls implements Blockly.IPositionable {
|
|
|
202
156
|
this.MARGIN_HORIZONTAL,
|
|
203
157
|
this.MARGIN_VERTICAL,
|
|
204
158
|
metrics,
|
|
205
|
-
this.workspace
|
|
206
|
-
)
|
|
159
|
+
this.workspace,
|
|
160
|
+
)
|
|
207
161
|
|
|
208
|
-
const verticalPosition = cornerPosition.vertical
|
|
162
|
+
const verticalPosition = cornerPosition.vertical
|
|
209
163
|
const bumpDirection =
|
|
210
164
|
verticalPosition === Blockly.uiPosition.verticalPosition.TOP
|
|
211
165
|
? Blockly.uiPosition.bumpDirection.DOWN
|
|
212
|
-
: Blockly.uiPosition.bumpDirection.UP
|
|
166
|
+
: Blockly.uiPosition.bumpDirection.UP
|
|
213
167
|
|
|
214
168
|
const positionRect = Blockly.uiPosition.bumpPositionRect(
|
|
215
169
|
startRect,
|
|
216
170
|
this.MARGIN_VERTICAL,
|
|
217
171
|
bumpDirection,
|
|
218
|
-
savedPositions
|
|
219
|
-
)
|
|
172
|
+
savedPositions,
|
|
173
|
+
)
|
|
220
174
|
|
|
221
175
|
// Zoom in and zoom out are always adjacent (small gap); reset has extra visual separation (large gap).
|
|
222
176
|
// The layout mirrors between corners so the button nearest the corner stays anchored there.
|
|
223
177
|
if (verticalPosition === Blockly.uiPosition.verticalPosition.TOP) {
|
|
224
178
|
// Top corner: reset nearest the corner (top), zoom out, zoom in furthest.
|
|
225
179
|
if (this.zoomResetGroup) {
|
|
226
|
-
this.zoomResetGroup.setAttribute(
|
|
227
|
-
const zoomOutY = this.LARGE_SPACING + this.SIZE
|
|
228
|
-
this.zoomOutGroup?.setAttribute(
|
|
229
|
-
const zoomInY = zoomOutY + this.SMALL_SPACING + this.SIZE
|
|
230
|
-
this.zoomInGroup?.setAttribute(
|
|
180
|
+
this.zoomResetGroup.setAttribute('transform', 'translate(0, 0)')
|
|
181
|
+
const zoomOutY = this.LARGE_SPACING + this.SIZE
|
|
182
|
+
this.zoomOutGroup?.setAttribute('transform', `translate(0, ${zoomOutY})`)
|
|
183
|
+
const zoomInY = zoomOutY + this.SMALL_SPACING + this.SIZE
|
|
184
|
+
this.zoomInGroup?.setAttribute('transform', `translate(0, ${zoomInY})`)
|
|
231
185
|
} else {
|
|
232
|
-
this.zoomOutGroup?.setAttribute(
|
|
233
|
-
const zoomInY = this.SMALL_SPACING + this.SIZE
|
|
234
|
-
this.zoomInGroup?.setAttribute(
|
|
186
|
+
this.zoomOutGroup?.setAttribute('transform', 'translate(0, 0)')
|
|
187
|
+
const zoomInY = this.SMALL_SPACING + this.SIZE
|
|
188
|
+
this.zoomInGroup?.setAttribute('transform', `translate(0, ${zoomInY})`)
|
|
235
189
|
}
|
|
236
190
|
} else {
|
|
237
191
|
// Bottom corner (default): zoom in furthest from corner (top), zoom out,
|
|
238
192
|
// reset nearest the corner (bottom).
|
|
239
|
-
this.zoomInGroup?.setAttribute(
|
|
240
|
-
const zoomOutY = this.SMALL_SPACING + this.SIZE
|
|
241
|
-
this.zoomOutGroup?.setAttribute(
|
|
193
|
+
this.zoomInGroup?.setAttribute('transform', 'translate(0, 0)')
|
|
194
|
+
const zoomOutY = this.SMALL_SPACING + this.SIZE
|
|
195
|
+
this.zoomOutGroup?.setAttribute('transform', `translate(0, ${zoomOutY})`)
|
|
242
196
|
if (this.zoomResetGroup) {
|
|
243
|
-
const zoomResetY = zoomOutY + this.LARGE_SPACING + this.SIZE
|
|
244
|
-
this.zoomResetGroup.setAttribute(
|
|
197
|
+
const zoomResetY = zoomOutY + this.LARGE_SPACING + this.SIZE
|
|
198
|
+
this.zoomResetGroup.setAttribute('transform', `translate(0, ${zoomResetY})`)
|
|
245
199
|
}
|
|
246
200
|
}
|
|
247
201
|
|
|
248
|
-
this.top = positionRect.top
|
|
249
|
-
this.left = positionRect.left
|
|
250
|
-
this.svgGroup?.setAttribute(
|
|
251
|
-
"transform",
|
|
252
|
-
`translate(${this.left}, ${this.top})`
|
|
253
|
-
);
|
|
202
|
+
this.top = positionRect.top
|
|
203
|
+
this.left = positionRect.left
|
|
204
|
+
this.svgGroup?.setAttribute('transform', `translate(${this.left}, ${this.top})`)
|
|
254
205
|
}
|
|
255
206
|
|
|
256
207
|
/**
|
|
257
208
|
* Handles zoom in / zoom out button clicks.
|
|
258
|
-
*
|
|
259
209
|
* @param amount Positive to zoom in, negative to zoom out.
|
|
260
210
|
* @param e The pointer event.
|
|
261
211
|
*/
|
|
262
212
|
private zoom(amount: number, e: PointerEvent) {
|
|
263
|
-
this.workspace.markFocused()
|
|
264
|
-
this.workspace.zoomCenter(amount)
|
|
265
|
-
this.fireZoomEvent()
|
|
266
|
-
Blockly.Touch.clearTouchIdentifier()
|
|
267
|
-
e.stopPropagation()
|
|
268
|
-
e.preventDefault()
|
|
213
|
+
this.workspace.markFocused()
|
|
214
|
+
this.workspace.zoomCenter(amount)
|
|
215
|
+
this.fireZoomEvent()
|
|
216
|
+
Blockly.Touch.clearTouchIdentifier()
|
|
217
|
+
e.stopPropagation()
|
|
218
|
+
e.preventDefault()
|
|
269
219
|
}
|
|
270
220
|
|
|
271
221
|
/**
|
|
272
222
|
* Handles zoom reset button clicks. Animates back to the starting scale and
|
|
273
223
|
* re-centers the workspace.
|
|
274
|
-
*
|
|
275
224
|
* @param e The pointer event.
|
|
276
225
|
*/
|
|
277
226
|
private resetZoom(e: PointerEvent) {
|
|
278
|
-
this.workspace.markFocused()
|
|
227
|
+
this.workspace.markFocused()
|
|
279
228
|
|
|
280
229
|
// Compute the zoom amount needed to get from currentScale back to
|
|
281
230
|
// startScale using the workspace's configured speed:
|
|
282
231
|
// targetScale = currentScale * speed^amount
|
|
283
232
|
// amount = log_speed(targetScale / currentScale)
|
|
284
|
-
const targetScale = this.workspace.options.zoomOptions.startScale
|
|
285
|
-
const currentScale = this.workspace.scale
|
|
286
|
-
const speed = this.workspace.options.zoomOptions.scaleSpeed
|
|
287
|
-
const amount = Math.log(targetScale / currentScale) / Math.log(speed)
|
|
288
|
-
|
|
289
|
-
this.workspace.beginCanvasTransition()
|
|
290
|
-
this.workspace.zoomCenter(amount)
|
|
291
|
-
this.workspace.scrollCenter()
|
|
292
|
-
setTimeout(this.workspace.endCanvasTransition.bind(this.workspace), 500)
|
|
293
|
-
|
|
294
|
-
this.fireZoomEvent()
|
|
295
|
-
Blockly.Touch.clearTouchIdentifier()
|
|
296
|
-
e.stopPropagation()
|
|
297
|
-
e.preventDefault()
|
|
233
|
+
const targetScale = this.workspace.options.zoomOptions.startScale
|
|
234
|
+
const currentScale = this.workspace.scale
|
|
235
|
+
const speed = this.workspace.options.zoomOptions.scaleSpeed
|
|
236
|
+
const amount = Math.log(targetScale / currentScale) / Math.log(speed)
|
|
237
|
+
|
|
238
|
+
this.workspace.beginCanvasTransition()
|
|
239
|
+
this.workspace.zoomCenter(amount)
|
|
240
|
+
this.workspace.scrollCenter()
|
|
241
|
+
setTimeout(this.workspace.endCanvasTransition.bind(this.workspace), 500)
|
|
242
|
+
|
|
243
|
+
this.fireZoomEvent()
|
|
244
|
+
Blockly.Touch.clearTouchIdentifier()
|
|
245
|
+
e.stopPropagation()
|
|
246
|
+
e.preventDefault()
|
|
298
247
|
}
|
|
299
248
|
|
|
300
249
|
/** Fires a zoom controls click event for external listeners. */
|
|
301
250
|
private fireZoomEvent() {
|
|
302
|
-
const event = new (Blockly.Events.get(Blockly.Events.CLICK))(
|
|
303
|
-
|
|
304
|
-
this.workspace.id,
|
|
305
|
-
"zoom_controls"
|
|
306
|
-
);
|
|
307
|
-
Blockly.Events.fire(event);
|
|
251
|
+
const event = new (Blockly.Events.get(Blockly.Events.CLICK))(null, this.workspace.id, 'zoom_controls')
|
|
252
|
+
Blockly.Events.fire(event)
|
|
308
253
|
}
|
|
309
254
|
}
|
package/src/shadows.ts
CHANGED
|
@@ -1,65 +1,60 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @license
|
|
3
2
|
* Copyright 2024 Google LLC
|
|
4
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
4
|
*/
|
|
6
|
-
|
|
7
|
-
import
|
|
8
|
-
import { Colours } from "./colours";
|
|
5
|
+
import * as Blockly from 'blockly/core'
|
|
6
|
+
import { Colours } from './colours'
|
|
9
7
|
|
|
10
8
|
/**
|
|
11
9
|
* Creates an SVG filter to apply drop shadows to blocks being dragged and
|
|
12
10
|
* inserts it into the DOM.
|
|
11
|
+
* @param workspace The workspace whose SVG will receive the filter definition.
|
|
13
12
|
*/
|
|
14
13
|
export function buildShadowFilter(workspace: Blockly.WorkspaceSvg) {
|
|
15
|
-
const svg = workspace.getParentSvg()
|
|
16
|
-
const defs = Blockly.utils.dom.createSvgElement(
|
|
17
|
-
Blockly.utils.Svg.DEFS,
|
|
18
|
-
{},
|
|
19
|
-
svg
|
|
20
|
-
);
|
|
14
|
+
const svg = workspace.getParentSvg()
|
|
15
|
+
const defs = Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.DEFS, {}, svg)
|
|
21
16
|
// Adjust these width/height, x/y properties to stop the shadow from clipping
|
|
22
17
|
const dragShadowFilter = Blockly.utils.dom.createSvgElement(
|
|
23
|
-
|
|
18
|
+
'filter',
|
|
24
19
|
{
|
|
25
|
-
id:
|
|
26
|
-
height:
|
|
27
|
-
width:
|
|
28
|
-
y:
|
|
29
|
-
x:
|
|
20
|
+
id: 'blocklyDragShadowFilter',
|
|
21
|
+
height: '140%',
|
|
22
|
+
width: '140%',
|
|
23
|
+
y: '-20%',
|
|
24
|
+
x: '-20%',
|
|
30
25
|
},
|
|
31
|
-
defs
|
|
32
|
-
)
|
|
26
|
+
defs,
|
|
27
|
+
)
|
|
33
28
|
Blockly.utils.dom.createSvgElement(
|
|
34
|
-
|
|
29
|
+
'feGaussianBlur',
|
|
35
30
|
{
|
|
36
|
-
in:
|
|
37
|
-
stdDeviation:
|
|
31
|
+
in: 'SourceAlpha',
|
|
32
|
+
stdDeviation: '6',
|
|
38
33
|
},
|
|
39
|
-
dragShadowFilter
|
|
40
|
-
)
|
|
34
|
+
dragShadowFilter,
|
|
35
|
+
)
|
|
41
36
|
const componentTransfer = Blockly.utils.dom.createSvgElement(
|
|
42
|
-
|
|
43
|
-
{ result:
|
|
44
|
-
dragShadowFilter
|
|
45
|
-
)
|
|
37
|
+
'feComponentTransfer',
|
|
38
|
+
{ result: 'offsetBlur' },
|
|
39
|
+
dragShadowFilter,
|
|
40
|
+
)
|
|
46
41
|
// Shadow opacity is specified in the adjustable colour library,
|
|
47
42
|
// since the darkness of the shadow largely depends on the workspace colour.
|
|
48
43
|
Blockly.utils.dom.createSvgElement(
|
|
49
|
-
|
|
44
|
+
'feFuncA',
|
|
50
45
|
{
|
|
51
|
-
type:
|
|
46
|
+
type: 'linear',
|
|
52
47
|
slope: Colours.dragShadowOpacity,
|
|
53
48
|
},
|
|
54
|
-
componentTransfer
|
|
55
|
-
)
|
|
49
|
+
componentTransfer,
|
|
50
|
+
)
|
|
56
51
|
Blockly.utils.dom.createSvgElement(
|
|
57
|
-
|
|
52
|
+
'feComposite',
|
|
58
53
|
{
|
|
59
|
-
in:
|
|
60
|
-
in2:
|
|
61
|
-
operator:
|
|
54
|
+
in: 'SourceGraphic',
|
|
55
|
+
in2: 'offsetBlur',
|
|
56
|
+
operator: 'over',
|
|
62
57
|
},
|
|
63
|
-
dragShadowFilter
|
|
64
|
-
)
|
|
58
|
+
dragShadowFilter,
|
|
59
|
+
)
|
|
65
60
|
}
|