Skip to content

Instantly share code, notes, and snippets.

@pstjvn
Last active November 3, 2016 11:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pstjvn/ad56fee0f840d2fd520793019c17e75a to your computer and use it in GitHub Desktop.
Save pstjvn/ad56fee0f840d2fd520793019c17e75a to your computer and use it in GitHub Desktop.
[1:35:22 PM]: ==> {"id":"1","method":"server.setSubscriptions","params":{"subscriptions":["STATUS"]}}
[1:35:22 PM]: ==> {"id":"2","method":"analysis.setAnalysisRoots","params":{"included":["/home/pstj/Documents/Projects/dart/svg-animation"],"excluded":[]}}
[1:35:22 PM]: ==> {"id":"3","method":"analysis.updateContent","params":{"files":{"/home/pstj/Documents/Projects/dart/svg-animation/lib/svg_animation.dart":{"type":"add","content":"library svg_animation;\n\nimport 'dart:html' as html;\nimport 'dart:svg' show PathElement, SvgElement;\nimport 'dart:async';\n\n/// Helper class to store information about a path element in the SVG element.\n///\n/// The class handles nuances of the SVG displaying, for example some paths\n/// do not report correctly the length and cannot be ainmated or report length\n/// of 0 but resetting the dash offset is not hiding them, so we abstract that\n/// and hide it in this implementation.\nclass PathInfo {\n final PathElement element;\n final int length;\n bool _isVisible = true;\n double _offset = 0.0;\n\n PathInfo(path)\n : element = path,\n length = path.getTotalLength() {\n element.style.setProperty('strokeDasharray', '$length $length');\n }\n\n /// Allows to abstract how we deal with the difference in browsers displaying\n /// dash offsets or the whole length when the path is wih length 0 but is\n /// still being displayed.\n _setVisible(bool shouldBeVisible) {\n if (shouldBeVisible != _isVisible) {\n _isVisible = shouldBeVisible;\n element.style.display = _isVisible ? '' : 'none';\n }\n }\n\n set offset(double o) {\n if (o != _offset) {\n _offset = o;\n _setVisible(_offset != length);\n element.style.setProperty('strokeDashoffset', _offset.toString());\n }\n }\n}\n\n/// Helper class to help organize the information about the SVG element needed\n/// for animations.\nclass SvgInfo {\n final SvgElement element;\n List<PathInfo> paths;\n int pathLength = 0;\n\n SvgInfo(this.element) {\n element.querySelectorAll('path').forEach((path) {\n paths.add(new PathInfo(path));\n pathLength += paths.last.length;\n });\n }\n\n set drawingProgress(double progress) {\n var desiredLength = (progress / 1) * pathLength;\n var len...
[1:35:22 PM]: ==> {"id":"4","method":"analysis.setPriorityFiles","params":{"files":["/home/pstj/Documents/Projects/dart/svg-animation/lib/svg_animation.dart"]}}
[1:35:23 PM]: <== {"event":"server.connected","params":{"version":"1.17.0","pid":31038,"sessionId":""}}
[1:35:23 PM]: <== {"id":"1"}
[1:35:23 PM]: <== {"event":"server.status","params":{"pub":{"isListingPackageDirs":true}}}
[1:35:23 PM]: <== {"event":"server.status","params":{"pub":{"isListingPackageDirs":false}}}
[1:35:23 PM]: <== {"id":"2"}
[1:35:23 PM]: <== {"id":"3","result":{}}
[1:35:23 PM]: <== {"id":"4"}
[1:35:23 PM]: <== {"event":"server.status","params":{"analysis":{"isAnalyzing":true}}}
[1:35:23 PM]: <== {"event":"analysis.errors","params":{"file":"/home/pstj/Documents/Projects/dart/svg-animation/lib/svg_animation.dart","errors":[]}}
[1:35:23 PM]: ==> {"id":"5","method":"analysis.updateContent","params":{"files":{"/home/pstj/Documents/Projects/dart/svg-animation/lib/svg_animation.dart":{"type":"change","edits":[{"offset":1526,"length":0,"replacement":"\n ","id":""}]}}}}
[1:35:23 PM]: <== {"id":"5","result":{}}
[1:35:23 PM]: <== {"event":"analysis.errors","params":{"file":"/home/pstj/Documents/Projects/dart/svg-animation/lib/svg_animation.dart","errors":[]}}
[1:35:23 PM]: <== {"event":"analysis.errors","params":{"file":"/home/pstj/Documents/Projects/dart/svg-animation/lib/svg_animation.dart","errors":[]}}
[1:35:23 PM]: <== {"event":"analysis.errors","params":{"file":"/home/pstj/Documents/Projects/dart/svg-animation/lib/svg_animation.dart","errors":[]}}
[1:35:23 PM]: <== {"event":"analysis.errors","params":{"file":"/home/pstj/Documents/Projects/dart/svg-animation/web/main.dart","errors":[]}}
[1:35:23 PM]: <== {"event":"analysis.errors","params":{"file":"/home/pstj/Documents/Projects/dart/svg-animation/web/main.dart","errors":[]}}
[1:35:23 PM]: <== {"event":"analysis.errors","params":{"file":"/home/pstj/Documents/Projects/dart/svg-animation/web/main.dart","errors":[]}}
[1:35:23 PM]: <== {"event":"analysis.errors","params":{"file":"/home/pstj/Documents/Projects/dart/svg-animation/web/index.html","errors":[]}}
[1:35:23 PM]: <== {"event":"analysis.errors","params":{"file":"/home/pstj/Documents/Projects/dart/svg-animation/.analysis_options","errors":[]}}
[1:35:23 PM]: <== {"event":"server.status","params":{"analysis":{"isAnalyzing":false}}}
[1:35:25 PM]: ==> {"id":"6","method":"analysis.updateContent","params":{"files":{"/home/pstj/Documents/Projects/dart/svg-animation/lib/svg_animation.dart":{"type":"change","edits":[{"offset":1531,"length":0,"replacement":"p","id":""}]}}}}
[1:35:25 PM]: ==> {"id":"7","method":"completion.getSuggestions","params":{"file":"/home/pstj/Documents/Projects/dart/svg-animation/lib/svg_animation.dart","offset":1532}}
[1:35:25 PM]: <== {"id":"6","result":{}}
[1:35:25 PM]: <== {"id":"7","result":{"id":"0"}}
[1:35:25 PM]: ==> {"id":"8","method":"analysis.updateContent","params":{"files":{"/home/pstj/Documents/Projects/dart/svg-animation/lib/svg_animation.dart":{"type":"change","edits":[{"offset":1532,"length":0,"replacement":"a","id":""}]}}}}
[1:35:25 PM]: <== {"event":"completion.results","params":{"id":"0","replacementOffset":1531,"replacementLength":1,"results":[{"kind":"INVOCATION","relevance":1000,"completion":"html.DivElement","selectionOffset":15,"selectionLength":0,"isDeprecated":false,"isPotential":false,"docSummary":"A generic container for content on an HTML page;\ncorresponds to the &lt;div&gt; tag.","docComplete":"A generic container for content on an HTML page;\ncorresponds to the &lt;div&gt; tag.\n\nThe [DivElement] is a generic container and does not have any semantic\nsignificance. It is functionally similar to [SpanElement].\n\nThe [DivElement] is a block-level element, as opposed to [SpanElement],\nwhich is an inline-level element.\n\nExample usage:\n\n DivElement div = new DivElement();\n div.text = 'Here's my new DivElem\n document.body.elements.add(elem);\n\nSee also:\n\n* [HTML `<div>` element](http://www.w3.org/TR/html-markup/div.html) from W3C.\n* [Block-level element](http://www.w3.org/TR/CSS2/visuren.html#block-boxes) from W3C.\n* [Inline-level element](http://www.w3.org/TR/CSS2/visuren.html#inline-boxes) from W3C.","element":{"kind":"CLASS","name":"DivElement","location":{"file":"/usr/lib/dart/lib/html/dartium/html_dartium.dart","offset":345978,"length":10,"startLine":10096,"startColumn":7},"flags":0}},{"kind":"INVOCATION","relevance":1000,"completion":"html.NavigatorID","selectionOffset":16,"selectionLength":0,"isDeprecated":false,"isPotential":false,"element":{"kind":"CLASS","name":"NavigatorID","location":{"file":"/usr/lib/dart/lib/html/dartium/html_dartium.dart","offset":946902,"length":11,"startLine":27347,"startColumn":16},"flags":1}},{"kind":"INVOCATION","relevance":1000,"completion":"html.TextInputElementBase","selectionOffset":25,"selectionLength":0,"isDeprecated":false,"isPotential":false,"docSummary":"Base interface for all inputs which involve text editing.","docComplete":"Base interface for all inputs which involve text editing.","element":{"kind":"CLASS","name":"TextI...
[1:35:25 PM]: <== {"event":"server.status","params":{"analysis":{"isAnalyzing":true}}}
[1:35:25 PM]: <== {"id":"8","result":{}}
[1:35:25 PM]: <== {"event":"analysis.errors","params":{"file":"/home/pstj/Documents/Projects/dart/svg-animation/lib/svg_animation.dart","errors":[{"severity":"ERROR","type":"SYNTACTIC_ERROR","location":{"file":"/home/pstj/Documents/Projects/dart/svg-animation/lib/svg_animation.dart","offset":1531,"length":2,"startLine":52,"startColumn":5},"message":"Expected to find ';'","code":"expected_token","hasFix":true},{"severity":"WARNING","type":"STATIC_WARNING","location":{"file":"/home/pstj/Documents/Projects/dart/svg-animation/lib/svg_animation.dart","offset":1531,"length":2,"startLine":52,"startColumn":5},"message":"Undefined name 'pa'","code":"undefined_identifier","hasFix":true}]}}
[1:35:25 PM]: <== {"event":"analysis.errors","params":{"file":"/home/pstj/Documents/Projects/dart/svg-animation/lib/svg_animation.dart","errors":[{"severity":"ERROR","type":"SYNTACTIC_ERROR","location":{"file":"/home/pstj/Documents/Projects/dart/svg-animation/lib/svg_animation.dart","offset":1531,"length":2,"startLine":52,"startColumn":5},"message":"Expected to find ';'","code":"expected_token","hasFix":true},{"severity":"WARNING","type":"STATIC_WARNING","location":{"file":"/home/pstj/Documents/Projects/dart/svg-animation/lib/svg_animation.dart","offset":1531,"length":2,"startLine":52,"startColumn":5},"message":"Undefined name 'pa'","code":"undefined_identifier","hasFix":true}]}}
[1:35:25 PM]: ==> {"id":"9","method":"edit.getFixes","params":{"file":"/home/pstj/Documents/Projects/dart/svg-animation/lib/svg_animation.dart","offset":1531}}
[1:35:25 PM]: ==> {"id":"10","method":"edit.getFixes","params":{"file":"/home/pstj/Documents/Projects/dart/svg-animation/lib/svg_animation.dart","offset":1531}}
[1:35:25 PM]: <== {"id":"9","result":{"fixes":[{"error":{"severity":"ERROR","type":"SYNTACTIC_ERROR","location":{"file":"/home/pstj/Documents/Projects/dart/svg-animation/lib/svg_animation.dart","offset":1531,"length":2,"startLine":52,"startColumn":5},"message":"Expected to find ';'","code":"expected_token","hasFix":true},"fixes":[{"message":"Insert ';'","edits":[{"file":"/home/pstj/Documents/Projects/dart/svg-animation/lib/svg_animation.dart","fileStamp":3,"edits":[{"offset":1533,"length":0,"replacement":";"}]}],"linkedEditGroups":[]}]},{"error":{"severity":"WARNING","type":"STATIC_WARNING","location":{"file":"/home/pstj/Documents/Projects/dart/svg-animation/lib/svg_animation.dart","offset":1531,"length":2,"startLine":52,"startColumn":5},"message":"Undefined name 'pa'","code":"undefined_identifier","hasFix":true},"fixes":[{"message":"Create getter 'pa'","edits":[{"file":"/home/pstj/Documents/Projects/dart/svg-animation/lib/svg_animation.dart","fileStamp":3,"edits":[{"offset":1675,"length":0,"replacement":"\n\n get pa => null;"}]}],"linkedEditGroups":[{"positions":[{"file":"/home/pstj/Documents/Projects/dart/svg-animation/lib/svg_animation.dart","offset":1683},{"file":"/home/pstj/Documents/Projects/dart/svg-animation/lib/svg_animation.dart","offset":1531}],"length":2,"suggestions":[]}]},{"message":"Create local variable 'pa'","edits":[{"file":"/home/pstj/Documents/Projects/dart/svg-animation/lib/svg_animation.dart","fileStamp":3,"edits":[{"offset":1531,"length":0,"replacement":"var pa;\n "}]}],"linkedEditGroups":[{"positions":[{"file":"/home/pstj/Documents/Projects/dart/svg-animation/lib/svg_animation.dart","offset":1535},{"file":"/home/pstj/Documents/Projects/dart/svg-animation/lib/svg_animation.dart","offset":1543}],"length":2,"suggestions":[]}]},{"message":"Create field 'pa'","edits":[{"file":"/home/pstj/Documents/Projects/dart/svg-animation/lib/svg_animation.dart","fileStamp":3,"edits":[{"offset":1499,"length":0,"replacement":"\n\n var pa;"}]}],"linkedEditGroups":[{"posit...
[1:35:25 PM]: <== {"id":"10","result":{"fixes":[{"error":{"severity":"ERROR","type":"SYNTACTIC_ERROR","location":{"file":"/home/pstj/Documents/Projects/dart/svg-animation/lib/svg_animation.dart","offset":1531,"length":2,"startLine":52,"startColumn":5},"message":"Expected to find ';'","code":"expected_token","hasFix":true},"fixes":[{"message":"Insert ';'","edits":[{"file":"/home/pstj/Documents/Projects/dart/svg-animation/lib/svg_animation.dart","fileStamp":3,"edits":[{"offset":1533,"length":0,"replacement":";"}]}],"linkedEditGroups":[]}]},{"error":{"severity":"WARNING","type":"STATIC_WARNING","location":{"file":"/home/pstj/Documents/Projects/dart/svg-animation/lib/svg_animation.dart","offset":1531,"length":2,"startLine":52,"startColumn":5},"message":"Undefined name 'pa'","code":"undefined_identifier","hasFix":true},"fixes":[{"message":"Create getter 'pa'","edits":[{"file":"/home/pstj/Documents/Projects/dart/svg-animation/lib/svg_animation.dart","fileStamp":3,"edits":[{"offset":1675,"length":0,"replacement":"\n\n get pa => null;"}]}],"linkedEditGroups":[{"positions":[{"file":"/home/pstj/Documents/Projects/dart/svg-animation/lib/svg_animation.dart","offset":1683},{"file":"/home/pstj/Documents/Projects/dart/svg-animation/lib/svg_animation.dart","offset":1531}],"length":2,"suggestions":[]}]},{"message":"Create local variable 'pa'","edits":[{"file":"/home/pstj/Documents/Projects/dart/svg-animation/lib/svg_animation.dart","fileStamp":3,"edits":[{"offset":1531,"length":0,"replacement":"var pa;\n "}]}],"linkedEditGroups":[{"positions":[{"file":"/home/pstj/Documents/Projects/dart/svg-animation/lib/svg_animation.dart","offset":1535},{"file":"/home/pstj/Documents/Projects/dart/svg-animation/lib/svg_animation.dart","offset":1543}],"length":2,"suggestions":[]}]},{"message":"Create field 'pa'","edits":[{"file":"/home/pstj/Documents/Projects/dart/svg-animation/lib/svg_animation.dart","fileStamp":3,"edits":[{"offset":1499,"length":0,"replacement":"\n\n var pa;"}]}],"linkedEditGroups":[{"posi...
[1:35:26 PM]: <== {"event":"analysis.errors","params":{"file":"/home/pstj/Documents/Projects/dart/svg-animation/lib/svg_animation.dart","errors":[{"severity":"ERROR","type":"SYNTACTIC_ERROR","location":{"file":"/home/pstj/Documents/Projects/dart/svg-animation/lib/svg_animation.dart","offset":1531,"length":2,"startLine":52,"startColumn":5},"message":"Expected to find ';'","code":"expected_token","hasFix":true},{"severity":"WARNING","type":"STATIC_WARNING","location":{"file":"/home/pstj/Documents/Projects/dart/svg-animation/lib/svg_animation.dart","offset":1531,"length":2,"startLine":52,"startColumn":5},"message":"Undefined name 'pa'","code":"undefined_identifier","hasFix":true}]}}
[1:35:26 PM]: <== {"event":"server.status","params":{"analysis":{"isAnalyzing":false}}}
[1:35:26 PM]: ==> {"id":"11","method":"edit.getFixes","params":{"file":"/home/pstj/Documents/Projects/dart/svg-animation/lib/svg_animation.dart","offset":1531}}
[1:35:26 PM]: <== {"id":"11","result":{"fixes":[{"error":{"severity":"ERROR","type":"SYNTACTIC_ERROR","location":{"file":"/home/pstj/Documents/Projects/dart/svg-animation/lib/svg_animation.dart","offset":1531,"length":2,"startLine":52,"startColumn":5},"message":"Expected to find ';'","code":"expected_token","hasFix":true},"fixes":[{"message":"Insert ';'","edits":[{"file":"/home/pstj/Documents/Projects/dart/svg-animation/lib/svg_animation.dart","fileStamp":3,"edits":[{"offset":1533,"length":0,"replacement":";"}]}],"linkedEditGroups":[]}]},{"error":{"severity":"WARNING","type":"STATIC_WARNING","location":{"file":"/home/pstj/Documents/Projects/dart/svg-animation/lib/svg_animation.dart","offset":1531,"length":2,"startLine":52,"startColumn":5},"message":"Undefined name 'pa'","code":"undefined_identifier","hasFix":true},"fixes":[{"message":"Create getter 'pa'","edits":[{"file":"/home/pstj/Documents/Projects/dart/svg-animation/lib/svg_animation.dart","fileStamp":3,"edits":[{"offset":1675,"length":0,"replacement":"\n\n get pa => null;"}]}],"linkedEditGroups":[{"positions":[{"file":"/home/pstj/Documents/Projects/dart/svg-animation/lib/svg_animation.dart","offset":1683},{"file":"/home/pstj/Documents/Projects/dart/svg-animation/lib/svg_animation.dart","offset":1531}],"length":2,"suggestions":[]}]},{"message":"Create local variable 'pa'","edits":[{"file":"/home/pstj/Documents/Projects/dart/svg-animation/lib/svg_animation.dart","fileStamp":3,"edits":[{"offset":1531,"length":0,"replacement":"var pa;\n "}]}],"linkedEditGroups":[{"positions":[{"file":"/home/pstj/Documents/Projects/dart/svg-animation/lib/svg_animation.dart","offset":1535},{"file":"/home/pstj/Documents/Projects/dart/svg-animation/lib/svg_animation.dart","offset":1543}],"length":2,"suggestions":[]}]},{"message":"Create field 'pa'","edits":[{"file":"/home/pstj/Documents/Projects/dart/svg-animation/lib/svg_animation.dart","fileStamp":3,"edits":[{"offset":1499,"length":0,"replacement":"\n\n var pa;"}]}],"linkedEditGroups":[{"posi...
library svg_animation;
import 'dart:html' as html show window;
import 'dart:svg' show PathElement, SvgElement;
import 'dart:async';
/// Helper class to store information about a path element in the SVG element.
///
/// The class handles nuances of the SVG displaying, for example some paths
/// do not report correctly the length and cannot be ainmated or report length
/// of 0 but resetting the dash offset is not hiding them, so we abstract that
/// and hide it in this implementation.
class PathInfo {
final PathElement element;
final int length;
bool _isVisible = true;
double _offset = 0.0;
PathInfo(path)
: element = path,
length = path.getTotalLength() {
element.style.setProperty('strokeDasharray', '$length $length');
}
/// Allows to abstract how we deal with the difference in browsers displaying
/// dash offsets or the whole length when the path is wih length 0 but is
/// still being displayed.
_setVisible(bool shouldBeVisible) {
if (shouldBeVisible != _isVisible) {
_isVisible = shouldBeVisible;
element.style.display = _isVisible ? '' : 'none';
}
}
set offset(double o) {
if (o != _offset) {
_offset = o;
_setVisible(_offset != length);
element.style.setProperty('strokeDashoffset', _offset.toString());
}
}
}
/// Helper class to help organize the information about the SVG element needed
/// for animations.
class SvgInfo {
final SvgElement element;
List<PathInfo> paths;
int pathLength = 0;
SvgInfo(this.element) {
element.querySelectorAll('path').forEach((path) {
paths.add(new PathInfo(path));
pathLength += paths.last.length;
});
}
set drawingProgress(double progress) {
var desiredLength = (progress / 1) * pathLength;
var len = 0;
paths.forEach((PathInfo path) {
if (len + path.length <= desiredLength) {
path.offset = 0.0;
} else if (len + path.length > desiredLength && len < desiredLength) {
path.offset = path.length - (desiredLength - len);
} else {
path.offset = path.length.toDouble();
}
});
}
}
/// Define the type used as callback in the animation class.
typedef void _AnimationCallback(double progress);
/// Helper class for animation, simpler and possibly faster than
/// the polyfilled WebAnimation class.
class _Animation {
final _AnimationCallback _callback;
Duration _duration;
double _startTime;
bool _isPlaying = false;
bool _isWaiting = false;
double _progress = 1.0;
_Animation(this._duration, this._callback);
/// Direct setter for the progress. It will emit the new progress value
/// asyncronously with RAF.
///
/// If animation is currently playing it will be stopped.
set progress(double p) {
_isPlaying = false;
_progress = p;
_tick();
}
void play() {
if (!_isPlaying) {
_isPlaying = true;
if (_progress != 1.0) {
_startTime = html.window.performance.now() -
(_duration.inMilliseconds * _progress);
} else {
_progress = 0.0;
_startTime = html.window.performance.now();
}
_tick();
}
}
/// Alias to make better API.
void resume() => play();
void pause() {
_isPlaying = false;
}
void stop() {
progress = 1.0;
}
Future _tick() async {
if (_isWaiting) return; // avoid extra work;
_isWaiting = true;
var ts = await html.window.animationFrame;
_isWaiting = false;
// If we are still playing the animation, advance the progress to match
// the current time
if (_isPlaying) {
_progress = (ts - _startTime) / _duration.inMilliseconds;
if (_progress >= 1.0) {
_isPlaying = false;
_progress = 1.0;
} else {
_tick();
}
}
_callback(_progress);
}
}
class SvgDrawing {
_Animation _animation = null;
SvgElement _svg;
int _duration = 3000;
List<PathInfo> _paths = null;
double _totalPathLength = 0.0;
SvgDrawing(this._svg) {
if (_svg != null) {
// Setup animation used to drive the repaints.
_animation = new _Animation(
new Duration(milliseconds: _duration), _setCompleteness);
// setup SVG path elements
_setupSvgSubElements();
// repaint initial state
completeness = 1.0;
}
}
_setupSvgSubElements() {}
void _setCompleteness(double compl) {
var desiredLength = (compl / 1) * _totalPathLength;
var len = 0;
_paths.forEach((PathInfo path) {
if (len + path.length <= desiredLength) {
// We need to show this whole path
path.element.style.display = '';
} else if (len + path.length > desiredLength && len < desiredLength) {
// we need to show this path partially
path.element.style.display = '';
} else {
// we need to hide this path
path.element.style.display = 'none';
}
len += path.length;
});
}
/// Allows to directly set the completeness (i.e. the progressof the drawing)
/// from outside.
///
/// This is will reset the animation (i.e. stop it).
///
/// Note that the reflection in the drawing is asyncronous, so if you have
/// the progress set and then you want to start the animation from the
/// beginning you will need first call completeness = 0.0 and then play();
void set completeness(double compl) {
_animation.progress = compl;
}
void play() {
completeness = 0.0;
_animation.play();
}
void pause() => _animation.pause();
void resume() => _animation.resume();
void stop() => _animation.stop();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment