From 038bbbd5cec19404bf055127d4fab1647dd4abbb Mon Sep 17 00:00:00 2001 From: Filip Barl Date: Fri, 4 Aug 2017 11:59:27 +0200 Subject: [PATCH] Added a semitransparent layer over the background nodes. --- client/app/scripts/charts/edge.js | 4 +- client/app/scripts/charts/node-container.js | 13 ++--- .../scripts/charts/nodes-chart-elements.js | 23 ++++++-- client/app/scripts/components/node-details.js | 1 + client/app/scripts/constants/animation.js | 2 +- client/app/styles/_base.scss | 55 +++++++++++-------- client/app/styles/_contrast-overrides.scss | 2 + client/app/styles/_variables.scss | 2 + 8 files changed, 63 insertions(+), 39 deletions(-) diff --git a/client/app/scripts/charts/edge.js b/client/app/scripts/charts/edge.js index 7d31aae8a..276f2aa09 100644 --- a/client/app/scripts/charts/edge.js +++ b/client/app/scripts/charts/edge.js @@ -14,9 +14,9 @@ class Edge extends React.Component { } render() { - const { id, path, highlighted, blurred, focused, thickness, source, target } = this.props; + const { id, path, highlighted, focused, thickness, source, target } = this.props; const shouldRenderMarker = (focused || highlighted) && (source !== target); - const className = classNames('edge', { highlighted, blurred }); + const className = classNames('edge', { highlighted }); return ( ( +const transformedNode = (otherProps, { x, y, k }) => ( // NOTE: Controlling blurring and transform from here seems to re-render // faster than adding a CSS class and controlling it from there. - + ); export default class NodeContainer extends React.PureComponent { render() { - const { dx, dy, isAnimated, scale, blurred, contrastMode } = this.props; - const nodeBlurOpacity = contrastMode ? 0.6 : 0.25; - const forwardedProps = omit(this.props, 'dx', 'dy', 'isAnimated', 'scale', 'blurred'); - const opacity = blurred ? nodeBlurOpacity : 1; + const { dx, dy, isAnimated, scale } = this.props; + const forwardedProps = omit(this.props, 'dx', 'dy', 'isAnimated', 'scale'); if (!isAnimated) { // Show static node for optimized rendering - return transformedNode(forwardedProps, { x: dx, y: dy, k: scale, opacity }); + return transformedNode(forwardedProps, { x: dx, y: dy, k: scale }); } return ( @@ -33,7 +31,6 @@ export default class NodeContainer extends React.PureComponent { x: spring(dx, NODES_SPRING_ANIMATION_CONFIG), y: spring(dy, NODES_SPRING_ANIMATION_CONFIG), k: spring(scale, NODES_SPRING_ANIMATION_CONFIG), - opacity: spring(opacity, NODES_SPRING_ANIMATION_CONFIG), }}> {interpolated => transformedNode(forwardedProps, interpolated)} diff --git a/client/app/scripts/charts/nodes-chart-elements.js b/client/app/scripts/charts/nodes-chart-elements.js index c1479ff83..551b83557 100644 --- a/client/app/scripts/charts/nodes-chart-elements.js +++ b/client/app/scripts/charts/nodes-chart-elements.js @@ -1,6 +1,7 @@ import React from 'react'; +import classNames from 'classnames'; import { connect } from 'react-redux'; -import { Map as makeMap, List as makeList } from 'immutable'; +import { fromJS, Map as makeMap, List as makeList } from 'immutable'; import NodeContainer from './node-container'; import EdgeContainer from './edge-container'; @@ -152,7 +153,6 @@ class NodesChartElements extends React.Component { matches={node.get('matches')} networks={node.get('networks')} metric={node.get('metric')} - blurred={node.get('blurred')} focused={node.get('focused')} highlighted={node.get('highlighted')} shape={node.get('shape')} @@ -183,7 +183,6 @@ class NodesChartElements extends React.Component { waypoints={edge.get('points')} highlighted={edge.get('highlighted')} focused={edge.get('focused')} - blurred={edge.get('blurred')} scale={edge.get('scale')} isAnimated={isAnimated} /> @@ -191,6 +190,16 @@ class NodesChartElements extends React.Component { } renderElement(element) { + if (element.get('overlay')) { + const className = classNames('nodes-overlay', { active: element.get('active') }); + return ( + + ); + } // This heuristics is not ideal but it works. return element.get('points') ? this.renderEdge(element) : this.renderNode(element); } @@ -213,6 +222,11 @@ class NodesChartElements extends React.Component { .map(this.edgeScaleDecorator) .groupBy(this.edgeDisplayLayer); + // const orderedElements = makeList([ + // edges, + // nodes, + // ]).flatten(true); + // NOTE: The elements need to be arranged into a single array outside // of DOM structure for React rendering engine to do smart rearrangements // without unnecessary re-rendering of the elements themselves. So e.g. @@ -220,6 +234,7 @@ class NodesChartElements extends React.Component { const orderedElements = makeList([ edges.get(BLURRED_EDGES_LAYER, makeList()), nodes.get(BLURRED_NODES_LAYER, makeList()), + fromJS([{ overlay: true, active: !!nodes.get(BLURRED_NODES_LAYER) }]), edges.get(NORMAL_EDGES_LAYER, makeList()), nodes.get(NORMAL_NODES_LAYER, makeList()), edges.get(HIGHLIGHTED_EDGES_LAYER, makeList()), @@ -242,7 +257,7 @@ function mapStateToProps(state) { hasSelectedNode: hasSelectedNodeFn(state), layoutNodes: layoutNodesSelector(state), layoutEdges: layoutEdgesSelector(state), - isAnimated: !graphExceedsComplexityThreshSelector(state), + isAnimated: false && !graphExceedsComplexityThreshSelector(state), highlightedNodeIds: highlightedNodeIdsSelector(state), highlightedEdgeIds: highlightedEdgeIdsSelector(state), selectedNetworkNodesIds: selectedNetworkNodesIdsSelector(state), diff --git a/client/app/scripts/components/node-details.js b/client/app/scripts/components/node-details.js index 6feafe0d0..bd0386424 100644 --- a/client/app/scripts/components/node-details.js +++ b/client/app/scripts/components/node-details.js @@ -151,6 +151,7 @@ class NodeDetails extends React.Component { } renderDetails() { + console.log('render details'); const { details, nodeControlStatus, nodeMatches = makeMap() } = this.props; const showControls = details.controls && details.controls.length > 0; const nodeColor = getNodeColorDark(details.rank, details.label, details.pseudo); diff --git a/client/app/scripts/constants/animation.js b/client/app/scripts/constants/animation.js index 895b5f5f4..edc3a2ad0 100644 --- a/client/app/scripts/constants/animation.js +++ b/client/app/scripts/constants/animation.js @@ -1,3 +1,3 @@ -export const NODES_SPRING_ANIMATION_CONFIG = { stiffness: 80, damping: 20, precision: 0.1 }; +export const NODES_SPRING_ANIMATION_CONFIG = { stiffness: 200, damping: 25, precision: 1 }; export const NODES_SPRING_FAST_ANIMATION_CONFIG = { stiffness: 800, damping: 50, precision: 1 }; diff --git a/client/app/styles/_base.scss b/client/app/styles/_base.scss index adda36df4..97a51ce0f 100644 --- a/client/app/styles/_base.scss +++ b/client/app/styles/_base.scss @@ -27,15 +27,18 @@ } .colorable { - transition: background-color .3s $base-ease; + transition: none; + // transition: background-color .3s $base-ease; } .palable { - transition: all .2s $base-ease; + transition: none; + // transition: all .2s $base-ease; } .hideable { - transition: opacity .5s $base-ease; + transition: none; + // transition: opacity .5s $base-ease; } .blinkable { @@ -259,7 +262,7 @@ margin-bottom: 15px; z-index: 2001; - transition: all .15s $base-ease; + // transition: all .15s $base-ease; overflow: hidden; height: 0; @@ -411,6 +414,16 @@ } +.nodes-overlay { + // transition: opacity 2.5s $base-ease; + pointer-events: none; + opacity: 0; + + &.active { + opacity: $node-elements-in-background-opacity; + } +} + .nodes-chart, .nodes-resources { &-error, &-loading { @@ -439,7 +452,7 @@ } &-loading &-error-icon-container { - @extend .blinkable; + // @extend .blinkable; } &-loading { @@ -468,7 +481,7 @@ } .nodes-chart-elements .node { - transition: opacity .2s $base-ease; + // transition: opacity .2s $base-ease; text-align: center; .node-label { @@ -562,12 +575,6 @@ } .edge { - transition: opacity .5s $base-ease; - - &.blurred { - opacity: $edge-opacity-blurred; - } - .link { fill: none; stroke: $edge-color; @@ -628,7 +635,7 @@ fill: none; stroke-opacity: 1; stroke-width: $node-border-stroke-width; - transition: stroke-opacity 0.333s $base-ease, fill 0.333s $base-ease; + // transition: stroke-opacity 0.333s $base-ease, fill 0.333s $base-ease; } &.metrics .border { @@ -700,7 +707,7 @@ right: $details-window-padding-left; top: 100px; bottom: 48px; - transition: transform 0.33333s cubic-bezier(0,0,0.21,1), margin-top .15s $base-ease; + // transition: transform 0.33333s cubic-bezier(0,0,0.21,1), margin-top .15s $base-ease; } } @@ -848,7 +855,7 @@ color: $white; &-icon { - @extend .blinkable; + // @extend .blinkable; margin-right: 0.5em; } } @@ -1237,7 +1244,7 @@ left: 10px; bottom: 10px; right: 0; - transition: transform 0.5s cubic-bezier(0.230, 1.000, 0.320, 1.000); + // transition: transform 0.5s cubic-bezier(0.230, 1.000, 0.320, 1.000); @extend .shadow-2; } @@ -1397,7 +1404,7 @@ } .error { - animation: blinking 2.0s 60 $base-ease; // blink for 2 minutes + // animation: blinking 2.0s 60 $base-ease; // blink for 2 minutes color: $text-secondary-color; } @@ -1421,7 +1428,7 @@ } &.status-loading { - animation: blinking 2.0s 150 $base-ease; // keep blinking for 5 minutes + // animation: blinking 2.0s 150 $base-ease; // keep blinking for 5 minutes text-transform: none; color: $text-color; } @@ -1530,7 +1537,7 @@ } &-info { - @extend .blinkable; + // @extend .blinkable; display: block; margin-top: 5px; text-align: right; @@ -1618,7 +1625,7 @@ display: inline-block; position: relative; width: 10em; - transition: width 0.3s 0s $base-ease; + // transition: width 0.3s 0s $base-ease; &-wrapper { flex: 0 1 20%; @@ -1638,7 +1645,7 @@ color: $text-tertiary-color; top: 0; opacity: 0; - transition: transform 0.3s 0s $base-ease, opacity 0.3s 0s $base-ease; + // transition: transform 0.3s 0s $base-ease, opacity 0.3s 0s $base-ease; text-align: left; } @@ -1665,7 +1672,7 @@ &-hint { font-size: 0.8rem; text-transform: uppercase; - transition: opacity 0.3s 0.5s $base-ease; + // transition: opacity 0.3s 0.5s $base-ease; opacity: 1; } } @@ -1703,7 +1710,7 @@ &-focused &-label-hint, &-pinned &-label-hint, &-filled &-label-hint { - transition: opacity 0.1s 0s $base-ease; + // transition: opacity 0.1s 0s $base-ease; opacity: 0; } @@ -1712,7 +1719,7 @@ &-pinned &-hint { opacity: 1; transform: translate3d(0, 2.75em, 0); - transition: transform 0.3s 0.3s $base-ease, opacity 0.3s 0.3s $base-ease; + // transition: transform 0.3s 0.3s $base-ease, opacity 0.3s 0.3s $base-ease; } &-focused &-input-field, diff --git a/client/app/styles/_contrast-overrides.scss b/client/app/styles/_contrast-overrides.scss index 310f79166..94339a0f7 100644 --- a/client/app/styles/_contrast-overrides.scss +++ b/client/app/styles/_contrast-overrides.scss @@ -12,6 +12,8 @@ $text-darker-color: darken($text-color, 20%); $white: white; $edge-color: black; +$node-elements-in-background-opacity: 0.4; + $node-highlight-shadow-opacity: 0.4; $node-highlight-stroke-opacity: 0.5; $node-highlight-stroke-width: 0.16; diff --git a/client/app/styles/_variables.scss b/client/app/styles/_variables.scss index ac30c5d25..b6e7205c8 100644 --- a/client/app/styles/_variables.scss +++ b/client/app/styles/_variables.scss @@ -31,6 +31,8 @@ $border-radius: 4px; $terminal-header-height: 44px; +$node-elements-in-background-opacity: 0.75; + $node-highlight-shadow-opacity: 0.5; $node-highlight-stroke-opacity: 0.4; $node-highlight-stroke-width: 0.04;