Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you create a custom neon animation in Dart

In Polymer you can create neon-animations like their already built 'fade-in-animation'. You would implement the Polymer.NeonAnimationBehavior like this

<script>
  Polymer({
    is: 'fade-in-animation',
    behaviors: [
      Polymer.NeonAnimationBehavior
    ],
    configure: function(config) {
      var node = config.node;
      this._effect = new KeyframeEffect(node, [
        {'opacity': '0'},
        {'opacity': '1'}
      ], this.timingFromConfig(config));
      return this._effect;
    }
  });
</script>

I could create something similar to that and just provide the configure function, which returns a KeyframeEffect. I tried reproducing this in Polymer Dart 1.0

@HtmlImport('diagonal-left.html')
library wellington.elements.animation.diagonal_left;

import 'dart:html';

import 'package:web_components/web_components.dart';
import 'package:polymer/polymer.dart';

import 'package:polymer_elements/neon_animation_behavior.dart';

@CustomElement('diagonal-left')
class DiagonalLeft extends PolymerElement with NeonAnimationBehavior {
  KeyframeEffect _effect;

  configure(config) {
    var node = config.node;
    if (config.transformOrigin) {
      setPrefixedProperty(node, 'transformOrigin', config.transformOrigin);
    } else {
      setPrefixedProperty(node, 'transformOrigin', '0 75%');
    }
    _effect = new KeyframeEffect(node, [
      {'transform': 'none'},
      {'transform': 'translateX(-100%)'}
    ], timingFromConfig(config));

    return _effect;
  }

  DiagonalLeft.created() : super.created();
}

with the HTMLImport importing this

<script type="application/dart" src="diagonal_left.dart"></script>

I try importing this, and putting this in the animationConfig

@property
Map get animationConfig =>  {
  'entry': [
  {
    'name': 'fade-in-animation',
    'node': this,
    'timing': {'delay': 500, 'duration': 1000}
  },
  {
    'name': 'scale-up-animation',
    'node': this,
    'timing': {'duration': 2000}
  }],
  'exit': [{
    'name': 'fade-out-animation',
    'node': this,
    'timing': {'delay': 500, 'duration': 1000}
  },
  {
    'name': 'slide-left-animation',
    'node': this,
    'timing': {'duration': 1000}
  },
  {
    'name': 'diagonal-left',
    'node': this
  }]
};

and all I get is a message in the browser console saying

neon-animated-pages: diagonal-left not found!

What am I doing wrong? In other words, how can I create a custom animation for use in neon-animations in Polymer Dart 1.0?

UPDATE:

I've found the reason it was failing to find the custom animation I had created. Surprised no one noticed my mistake. I was using

@CustomElement('diagonal-left')

which is the old pre Polymer Dart 1.0 way of registering an element. It should be instead

@PolymerRegister('diagonal-left')

Now it's able to find my animation, but that only gave me another error in Dartium

VM4374:1 ORIGINAL EXCEPTION: V8 Exception(anonymous function) @ VM4374:1
VM4374:1 ORIGINAL STACKTRACE:(anonymous function) @ VM4374:1
VM4374:1 #0      JsFunction._apply (dart:js:1490)
#1      JsFunction.apply (dart:js:1488)
#2      BrowserDomAdapter.setProperty (package:angular2/src/platform/browser/browser_adapter.dart:140:20)
#3      DomRenderer.setElementProperty (package:angular2/src/platform/dom/dom_renderer.dart:190:9)
#4      DebugDomRenderer.setElementProperty (package:angular2/src/core/debug/debug_renderer.dart:127:10)
#5      AppView.notifyOnBinding (package:angular2/src/core/linker/view.dart:211:23)
#6      AbstractChangeDetector.notifyDispatcher (package:angular2/src/core/change_detection/abstract_change_detector.dart:280:21)
#7      _WaterfrontView_0.detectChangesInRecordsInternal (package:wellington/views/waterfront_view/waterfront_view.template.dart:66:20)
#8      AbstractChangeDetector.detectChangesInRecords (package:angular2/src/core/change_detection/abstract_change_detector.dart:151:12)
#9      AbstractChangeDetector.runDetectChanges (package:angular2/src/core/change_detection/abstract_change_detector.dart:125:10)
#10     AbstractChangeDetector._detectChangesInViewChildren (package:angular2/src/core/change_detection/abstract_change_detector.dart:244:12)
#11     AbstractChangeDetector.runDetectChanges (package:angular2/src/core/change_detection/abstract_change_detector.dart:128:10)
#12     AbstractChangeDetector._detectChangesInViewChildren (package:angular2/src/core/change_detection/abstract_change_detector.dart:244:12)
#13     AbstractChangeDetector.runDetectChanges (package:angular2/src/core/change_detection/abstract_change_detector.dart:128:10)
#14     AbstractChangeDetector.detectChanges (package:angular2/src/core/change_detection/abstract_change_detector.dart:111:10)
#15     ChangeDetectorRef_.detectChanges (package:angular2/src/core/change_detection/change_detector_ref.dart:209:14)
#16     ApplicationRef_.tick.<anonymous closure> (package:angular2/src/core/application_ref.dart:512:63)
#17     List.forEach (dart:core-patch/growable_array.dart:258)
#18     ApplicationRef_.tick (package:angular2/src/core/application_ref.dart:512:32)
#19     ApplicationRef_.ApplicationRef_.<anonymous closure>.<anonymous closure> (package:angular2/src/core/application_ref.dart:410:16)
#20     _rootRun (dart:async/zone.dart:1150)
#21     _ZoneDelegate.run (dart:async/zone.dart:693)
#22     NgZoneImpl._run (package:angular2/src/core/zone/ng_zone_impl.dart:150:21)
#23     _CustomZone.run (dart:async/zone.dart:1026)
#24     _CustomZone.runGuarded (dart:async/zone.dart:924)
#25     NgZoneImpl.runInner (package:angular2/src/core/zone/ng_zone_impl.dart:121:23)
#26     NgZone.run (package:angular2/src/core/zone/ng_zone.dart:219:27)
#27     ApplicationRef_.ApplicationRef_.<anonymous closure> (package:angular2/src/core/application_ref.dart:409:20)
#28     _RootZone.runUnaryGuarded (dart:async/zone.dart:1338)
#29     _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:331)
#30     _BufferingStreamSubscription._add (dart:async/stream_impl.dart:258)
#31     _SyncBroadcastStreamController._sendData (dart:async/broadcast_stream_controller.dart:386)
#32     _BroadcastStreamController.add (dart:async/broadcast_stream_controller.dart:261)
#33     EventEmitter.emit (package:angular2/src/facade/async.dart:95:17)
#34     NgZone._checkStable (package:angular2/src/core/zone/ng_zone.dart:146:34)
#35     NgZone.NgZone.<anonymous closure> (package:angular2/src/core/zone/ng_zone.dart:129:16)
#36     NgZoneImpl._run (package:angular2/src/core/zone/ng_zone_impl.dart:152:14)
#37     NgZoneImpl._runUnary (package:angular2/src/core/zone/ng_zone_impl.dart:157:7)
#38     _CustomZone.runUnary (dart:async/zone.dart:1037)
#39     _CustomZone.runUnaryGuarded (dart:async/zone.dart:932)
#40     _CustomZone.bindUnaryCallback.<anonymous closure> (dart:async/zone.dart:961)
#41     _Timer._Timer.<anonymous closure> (dart:html:49206)

and when run through pub serve I get the following in Chrome

EXCEPTION: NoSuchMethodError: method not found: 'configure' (animation.configure is not a function) in [selected in WaterfrontView@7:40]  html_dart2js.dart:3351
EXCEPTION: NoSuchMethodError: method not found: 'configure' (animation.configure is not a function) in [selected in WaterfrontView@7:40]
ORIGINAL EXCEPTION: NoSuchMethodError: method not found: 'configure' (animation.configure is not a function)
ORIGINAL STACKTRACE:

TypeError: animation.configure is not a function
at HTMLElement._configureAnimationEffects (index.html?_ijt=j7c5fphk4jffr92eaclvnf00al:20326)
at HTMLElement.playAnimation (index.html?_ijt=j7c5fphk4jffr92eaclvnf00al:20362)
at HTMLElement._selectedChanged (index.html?_ijt=j7c5fphk4jffr92eaclvnf00al:20572)
at HTMLElement._complexObserverEffect (index.html?_ijt=j7c5fphk4jffr92eaclvnf00al:7749)
at HTMLElement._effectEffects (index.html?_ijt=j7c5fphk4jffr92eaclvnf00al:7496)
at HTMLElement._propertySetter (index.html?_ijt=j7c5fphk4jffr92eaclvnf00al:7473)
at HTMLElement.setter (index.html?_ijt=j7c5fphk4jffr92eaclvnf00al:7582)
at eval (eval at F (js_dart2js.dart:358), <anonymous>:1:39)
at h2.bt (js_dart2js.dart:387)
at h2.aC (js_dart2js.dart:392)
aE @ html_dart2js.dart:3351
(anonymous function) @ exception_handler.dart:80
dart.cI.$3 @ exception_handler.dart:91
dart.yu.$1 @ application_ref.dart:262
dart.xS.$0 @ ng_zone_impl.dart:157
dart.nY @ zone.dart:1150
dart.xN.fj @ zone.dart:693
dart.xN.lB @ ng_zone_impl.dart:157
(anonymous function) @ VM202:2
bP @ zone.dart:1037
bQ @ zone.dart:932
W @ stream_impl.dart:331
dart.ey.ay @ stream_impl.dart:258
W @ broadcast_stream_controller.dart:386
$1 @ broadcast_stream_controller.dart:261
dart.xN.lz @ ng_zone_impl.dart:190
(anonymous function) @ VM198:2
aq @ zone.dart:1005
ai @ zone.dart:926
dart.ug.$1 @ ng_zone_impl.dart:121
bQ @ zone.dart:1338
W @ stream_impl.dart:331
dart.ey.ay @ stream_impl.dart:258
W @ broadcast_stream_controller.dart:386
eH @ broadcast_stream_controller.dart:261
$0 @ ng_zone.dart:129
dart.xN.fj @ ng_zone_impl.dart:152
dart.xN.lB @ ng_zone_impl.dart:157
(anonymous function) @ VM202:2
bP @ zone.dart:1037
bQ @ zone.dart:932
dart.Ar.$1 @ zone.dart:961
dart.zF.$0 @ isolate_helper.dart:1396
$0 @ js_helper.dart:2408
bz @ isolate_helper.dart:462
d9 @ isolate_helper.dart:54
dart.HW @ js_helper.dart:2408
(anonymous function) @ js_helper.dart:2430

Which is telling me the dart method configure(config) is not being converted/wrapped into a JS function. Is there something I can do to fix this and get a custom dart animation to work in Polymer? And yes this is Polymer being run in a Angular 2 app, which means I am forced to use shadowroot.

UPDATE 2:

I encountered an error in the version of Chrome I was using, which relates to this bug https://github.com/Polymer/core-animation/pull/28. I found I needed to update to the latest polymer_elements 1.0.0-rc.9. Now I'm back to square one with the error being

neon-animated-pages: diagonal-left not found!

Oh well so much for progress.

like image 719
James Hurford Avatar asked Nov 08 '22 17:11

James Hurford


1 Answers

I have yet again answered my own question. The only method I can get to work is to write the animation in JS, and then wrap it in a Polymer Dart wrapper. The easiest way is to use the custom_element_apigen. The problem is that's not working with the current Dart version, due to changes in pub. There is a pull request that answers that problem, but in the meantime you'll have to do it manually. I mimic the way custom_element_apigen does things.

JavaScript version in lib/src/test-animation/test-animation.html

<link rel="import" href="../../../../packages/polymer/polymer.html">
<link rel="import" href="../../../../packages/polymer_elements/src/neon-animation/neon-animation-behavior.html">
<link rel="import" href="../../../../packages/polymer_elements/src/neon-animation/web-animations.html">


<script>

    Polymer({

        is: 'test-animation',

        behaviors: [
            Polymer.NeonAnimationBehavior
        ],

        configure: function(config) {
            var node = config.node;

            node.style.perspective = "600px";
            node.style.backfaceVisibility = "hidden";
            node.style.transformStyle = "preserve-3d";
            node.style.transition = "transform 1s";
            node.style.position = "absolute";


            this._effect = new KeyframeEffect(node, [
                {'transform': 'rotateY(-20deg)'},
                {'transform': 'rotateY(-40deg)'},
                {'transform': 'rotateY(-60deg)'},
                {'transform': 'rotateY(-80deg)'},
                {'transform': 'rotateY(-100deg)'},
                {'transform': 'rotateY(-120deg)'},
                {'transform': 'rotateY(-140deg)'},
                {'transform': 'rotateY(-160deg)'},
                {'transform': 'rotateY(-180deg)'},
                {'transform': 'rotateY(0deg)'}
            ], this.timingFromConfig(config));

            return this._effect;
        }

    });

</script>

Create a nodart html file lib/test_animation_nodart.html

<link rel="import" href="src/test-animation/test-animation.html">
<link rel="import" href="../../packages/polymer_elements/neon_animation_behavior_nodart.html">

Create the dart polymer html wrapper lib/test_animation.html. You actually don't need this file, but custom_element_apigen creates it, so I leave it in.

<link rel="import" href="test_animation_nodart.html">

<script type="application/dart" src="test_animation.dart"></script>

And then finally the dart wrapper lib test_animation.dart

@HtmlImport('test_animation_nodart.html')
library family_tree.lib.src.test_animation.test_animation;

import 'dart:html';
import 'package:web_components/web_components.dart';
import 'package:polymer_interop/polymer_interop.dart';
import 'package:polymer_elements/neon_animation_behavior.dart';


@CustomElementProxy('test-animation')
class TestAnimation extends HtmlElement with CustomElementProxyMixin, PolymerBase, NeonAnimationBehavior {
  TestAnimation.created() : super.created();
}

You should now be able to include this in your neon animation element, in the animationConfig field. See this answer on how to do this.

This isn't the answer I was hoping for, but it works.

like image 136
James Hurford Avatar answered Nov 29 '22 15:11

James Hurford