Skip to content
This repository was archived by the owner on Mar 13, 2018. It is now read-only.

Commit d4ed6d4

Browse files
author
Yvonne Yip
committed
css-to-webanimations: css keyframe parsing demo
1 parent 6783c7b commit d4ed6d4

File tree

4 files changed

+227
-74
lines changed

4 files changed

+227
-74
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
<polymer-element name="css-keyframe-parser" attributes="styleRoot">
2+
<script>
3+
(function() {
4+
5+
var Parser = function(cssText) {
6+
this.cssText = cssText;
7+
}
8+
9+
Parser.prototype = {
10+
match: function(re) {
11+
var m = re.exec(this.cssText);
12+
if (m) {
13+
var offset = this.cssText.indexOf(m[0]) + m[0].length;
14+
this.cssText = this.cssText.slice(offset);
15+
}
16+
return m;
17+
},
18+
open: function() {
19+
this.match(/^\s*{\s*/);
20+
},
21+
close: function() {
22+
this.match(/^\s*}\s*/);
23+
},
24+
parseDeclarations: function() {
25+
var declarations = {};
26+
var d;
27+
do {
28+
d = this.match(/^\s*([\w-]+)\s*:\s*(.+);\s*/);
29+
if (d) {
30+
declarations[d[1]] = d[2];
31+
}
32+
} while (d);
33+
return declarations;
34+
},
35+
parseKeyframes: function() {
36+
var keyframes = [];
37+
var m;
38+
do {
39+
m = this.match(/^\s*(from|to|[0-9]+%)\s*/);
40+
if (m) {
41+
var offset;
42+
if (m[1] === 'from') {
43+
offset = 0;
44+
} else if (m[1] === 'to') {
45+
offset = 1;
46+
} else {
47+
offset = Math.min(1, parseInt(m) / 100);
48+
}
49+
this.open();
50+
var frame = this.parseDeclarations();
51+
frame.offset = offset;
52+
keyframes.push(frame);
53+
this.close();
54+
}
55+
} while (m);
56+
return keyframes;
57+
},
58+
parseAtKeyframeRules: function(rules) {
59+
rules = rules || [];
60+
var rule;
61+
do {
62+
var rule = this.match(/@keyframes ([\w-]+)/);
63+
if (rule) {
64+
this.open();
65+
rules.push({
66+
name: rule[1],
67+
keyframes: this.parseKeyframes()
68+
});
69+
this.close();
70+
}
71+
} while (rule);
72+
return rules;
73+
}
74+
};
75+
76+
function getAnimations(node) {
77+
var rules = [];
78+
var styles = node.localName === 'style' ? [node] : node.querySelectorAll('style');
79+
styles.forEach(function(s) {
80+
if (s.textContent) {
81+
var parser = new Parser(s.textContent);
82+
parser.parseAtKeyframeRules(rules);
83+
}
84+
});
85+
return rules;
86+
}
87+
88+
Polymer('css-keyframe-parser', {
89+
styleRoot: null,
90+
enteredDocument: function() {
91+
this.styleRootChanged();
92+
},
93+
styleRootChanged: function() {
94+
if (!this.styleRoot) {
95+
var top = this;
96+
do {
97+
top = top.parentNode;
98+
} while (!top.host && top !== document);
99+
this.styleRoot = top;
100+
}
101+
},
102+
parse: function() {
103+
this.keyframeRules = getAnimations(this.styleRoot);
104+
}
105+
});
106+
})();
107+
</script>
108+
</polymer-element>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
<link href="../../../polymer-elements/polymer-animation/web-animations.html" rel="import">
2+
<link href="../../../polymer-elements/polymer-flex-layout/polymer-flex-layout.html" rel="import">
3+
<link href="../../../more-elements/ace-element/ace-element.html" rel="import">
4+
<link href="css-keyframe-parser.html" rel="import">
5+
<polymer-element name="css-to-webanimations-demo" attributes="duration">
6+
<template>
7+
<style>
8+
.ace-container {
9+
position: relative;
10+
width: 50%;
11+
height: 100%;
12+
}
13+
.right {
14+
padding: 10px;
15+
}
16+
#animated {
17+
width: 40px;
18+
height: 40px;
19+
background: orange;
20+
}
21+
</style>
22+
<style id="style">
23+
@keyframes fade-in-out {
24+
0% {
25+
opacity: 1;
26+
}
27+
50% {
28+
opacity: 0.3;
29+
}
30+
100% {
31+
opacity: 1;
32+
}
33+
}
34+
@keyframes move {
35+
from {
36+
transform: translate3d(0,0,0);
37+
}
38+
to {
39+
transform: translate3d(1200%, 0, 0);
40+
}
41+
}
42+
</style>
43+
<css-keyframe-parser id="parser" styleRoot="{{$.style}}"></css-keyframe-parser>
44+
<polymer-flex-layout></polymer-flex-layout>
45+
<div class="ace-container">
46+
<ace-element id="ace" value="{{$.style.textContent}}"></ace-element>
47+
</div>
48+
<div class="right" flex>
49+
<h1>CSS Keyframes to Web Animations</h1>
50+
<p>
51+
<button on-click="syncAction">Sync</button>
52+
</p>
53+
<p>
54+
<label>
55+
Duration: <input value="{{duration}}">
56+
</label>
57+
<label>
58+
Group:
59+
<input id="seq" name="group" type="radio" checked> Seq
60+
<input id="par" name="group" type="radio"> Par
61+
</label>
62+
<br>
63+
<button on-click="runAction">Run</button>
64+
</p>
65+
<p>Animations:</p>
66+
<p>
67+
<template repeat="{{$.parser.keyframeRules}}">
68+
<input type="checkbox"> {{name}}<br>
69+
</template>
70+
</p>
71+
<p>Demo:</p>
72+
<div id="animated"></div>
73+
</div>
74+
</template>
75+
<script>
76+
Polymer('css-to-webanimations-demo', {
77+
duration: 1,
78+
enteredDocument: function() {
79+
this.$.parser.parse();
80+
},
81+
syncAction: function() {
82+
this.$.style.textContent = this.$.ace.editorValue;
83+
this.$.parser.parse();
84+
},
85+
runAction: function() {
86+
var checkboxes = this.shadowRoot.querySelectorAll('input[type="checkbox"]');
87+
var animations = [];
88+
checkboxes.forEach(function(cb) {
89+
if (cb.checked) {
90+
animations.push(new Animation(this.$.animated,
91+
new KeyframeAnimationEffect(cb.templateInstance.model.keyframes),
92+
{duration: this.duration}));
93+
}
94+
}.bind(this));
95+
if (animations.length === 1) {
96+
document.timeline.play(animations[0]);
97+
} else if (animations.length > 1) {
98+
if (this.$.seq.checked) {
99+
document.timeline.play(new SeqGroup(animations));
100+
} else {
101+
document.timeline.play(new ParGroup(animations));
102+
}
103+
}
104+
}
105+
});
106+
</script>
107+
</polymer-element>

yvonne/css-to-webanimations/css-to-webanimations-el.html

-72
This file was deleted.
+12-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,20 @@
11
<!doctype html>
22
<html>
33
<head>
4-
<link href="css-to-webanimations-el.html" rel="import">
4+
<link href="css-to-webanimations-demo.html" rel="import">
55
<script src="../../../polymer/polymer.js"></script>
6+
<style>
7+
body {
8+
margin: 0;
9+
padding: 0;
10+
}
11+
html, body, css-to-webanimations-demo {
12+
width: 100%;
13+
height: 100%;
14+
}
15+
</style>
616
</head>
717
<body>
8-
<css-to-webanimations-el></css-to-webanimations-el>
18+
<css-to-webanimations-demo></css-to-webanimations-demo>
919
</body>
1020
</html>

0 commit comments

Comments
 (0)