File "block_animations.js"
Full path: /usr/home/mndrn/domains/mndrn.ru/public_html/block-hill/blockly/core/block_animations.js
File size: 6.37 KiB (6526 bytes)
MIME-type: text/plain
Charset: utf-8
/**
* @license
* Copyright 2018 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @fileoverview Methods animating a block on connection and disconnection.
* @author [email protected] (Rachel Fenichel)
*/
'use strict';
goog.provide('Blockly.blockAnimations');
goog.require('Blockly.utils.dom');
goog.require('Blockly.utils.Svg');
/**
* PID of disconnect UI animation. There can only be one at a time.
* @type {number}
* @private
*/
Blockly.blockAnimations.disconnectPid_ = 0;
/**
* SVG group of wobbling block. There can only be one at a time.
* @type {Element}
* @private
*/
Blockly.blockAnimations.disconnectGroup_ = null;
/**
* Play some UI effects (sound, animation) when disposing of a block.
* @param {!Blockly.BlockSvg} block The block being disposed of.
* @package
*/
Blockly.blockAnimations.disposeUiEffect = function(block) {
var workspace = block.workspace;
var svgGroup = block.getSvgRoot();
workspace.getAudioManager().play('delete');
var xy = workspace.getSvgXY(svgGroup);
// Deeply clone the current block.
var clone = svgGroup.cloneNode(true);
clone.translateX_ = xy.x;
clone.translateY_ = xy.y;
clone.setAttribute('transform', 'translate(' + xy.x + ',' + xy.y + ')');
workspace.getParentSvg().appendChild(clone);
clone.bBox_ = clone.getBBox();
// Start the animation.
Blockly.blockAnimations.disposeUiStep_(clone, workspace.RTL, new Date,
workspace.scale);
};
/**
* Animate a cloned block and eventually dispose of it.
* This is a class method, not an instance method since the original block has
* been destroyed and is no longer accessible.
* @param {!Element} clone SVG element to animate and dispose of.
* @param {boolean} rtl True if RTL, false if LTR.
* @param {!Date} start Date of animation's start.
* @param {number} workspaceScale Scale of workspace.
* @private
*/
Blockly.blockAnimations.disposeUiStep_ = function(clone, rtl, start,
workspaceScale) {
var ms = new Date - start;
var percent = ms / 150;
if (percent > 1) {
Blockly.utils.dom.removeNode(clone);
} else {
var x = clone.translateX_ +
(rtl ? -1 : 1) * clone.bBox_.width * workspaceScale / 2 * percent;
var y = clone.translateY_ + clone.bBox_.height * workspaceScale * percent;
var scale = (1 - percent) * workspaceScale;
clone.setAttribute('transform', 'translate(' + x + ',' + y + ')' +
' scale(' + scale + ')');
setTimeout(Blockly.blockAnimations.disposeUiStep_, 10, clone, rtl, start,
workspaceScale);
}
};
/**
* Play some UI effects (sound, ripple) after a connection has been established.
* @param {!Blockly.BlockSvg} block The block being connected.
* @package
*/
Blockly.blockAnimations.connectionUiEffect = function(block) {
var workspace = block.workspace;
var scale = workspace.scale;
workspace.getAudioManager().play('click');
if (scale < 1) {
return; // Too small to care about visual effects.
}
// Determine the absolute coordinates of the inferior block.
var xy = workspace.getSvgXY(block.getSvgRoot());
// Offset the coordinates based on the two connection types, fix scale.
if (block.outputConnection) {
xy.x += (block.RTL ? 3 : -3) * scale;
xy.y += 13 * scale;
} else if (block.previousConnection) {
xy.x += (block.RTL ? -23 : 23) * scale;
xy.y += 3 * scale;
}
var ripple = Blockly.utils.dom.createSvgElement(
Blockly.utils.Svg.CIRCLE,
{
'cx': xy.x,
'cy': xy.y,
'r': 0,
'fill': 'none',
'stroke': '#888',
'stroke-width': 10
},
workspace.getParentSvg());
// Start the animation.
Blockly.blockAnimations.connectionUiStep_(ripple, new Date, scale);
};
/**
* Expand a ripple around a connection.
* @param {!SVGElement} ripple Element to animate.
* @param {!Date} start Date of animation's start.
* @param {number} scale Scale of workspace.
* @private
*/
Blockly.blockAnimations.connectionUiStep_ = function(ripple, start, scale) {
var ms = new Date - start;
var percent = ms / 150;
if (percent > 1) {
Blockly.utils.dom.removeNode(ripple);
} else {
ripple.setAttribute('r', percent * 25 * scale);
ripple.style.opacity = 1 - percent;
Blockly.blockAnimations.disconnectPid_ = setTimeout(
Blockly.blockAnimations.connectionUiStep_, 10, ripple, start, scale);
}
};
/**
* Play some UI effects (sound, animation) when disconnecting a block.
* @param {!Blockly.BlockSvg} block The block being disconnected.
* @package
*/
Blockly.blockAnimations.disconnectUiEffect = function(block) {
block.workspace.getAudioManager().play('disconnect');
if (block.workspace.scale < 1) {
return; // Too small to care about visual effects.
}
// Horizontal distance for bottom of block to wiggle.
var DISPLACEMENT = 10;
// Scale magnitude of skew to height of block.
var height = block.getHeightWidth().height;
var magnitude = Math.atan(DISPLACEMENT / height) / Math.PI * 180;
if (!block.RTL) {
magnitude *= -1;
}
// Start the animation.
Blockly.blockAnimations.disconnectUiStep_(
block.getSvgRoot(), magnitude, new Date);
};
/**
* Animate a brief wiggle of a disconnected block.
* @param {!SVGElement} group SVG element to animate.
* @param {number} magnitude Maximum degrees skew (reversed for RTL).
* @param {!Date} start Date of animation's start.
* @private
*/
Blockly.blockAnimations.disconnectUiStep_ = function(group, magnitude, start) {
var DURATION = 200; // Milliseconds.
var WIGGLES = 3; // Half oscillations.
var ms = new Date - start;
var percent = ms / DURATION;
if (percent > 1) {
group.skew_ = '';
} else {
var skew = Math.round(
Math.sin(percent * Math.PI * WIGGLES) * (1 - percent) * magnitude);
group.skew_ = 'skewX(' + skew + ')';
Blockly.blockAnimations.disconnectGroup_ = group;
Blockly.blockAnimations.disconnectPid_ =
setTimeout(Blockly.blockAnimations.disconnectUiStep_, 10, group,
magnitude, start);
}
group.setAttribute('transform', group.translate_ + group.skew_);
};
/**
* Stop the disconnect UI animation immediately.
* @package
*/
Blockly.blockAnimations.disconnectUiStop = function() {
if (Blockly.blockAnimations.disconnectGroup_) {
clearTimeout(Blockly.blockAnimations.disconnectPid_);
var group = Blockly.blockAnimations.disconnectGroup_;
group.skew_ = '';
group.setAttribute('transform', group.translate_);
Blockly.blockAnimations.disconnectGroup_ = null;
}
};