Last active
December 29, 2015 09:59
-
-
Save oreshinya/7653921 to your computer and use it in GitHub Desktop.
step-startなどのstep実行用のkeyframeからlinearでstep実行っぽく見せるkeyframeの生成
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| require 'sass' | |
| BASE_SCSS_LOAD_PATH = './assets/www/app/stylesheets/main.css.scss' | |
| KEYFRAMES_OUTPUT_PATH = "./assets/www/app/stylesheets/android_keyframes.css.scss" | |
| class Sass::Tree::Visitors::ToArray < Sass::Tree::Visitors::Base | |
| protected | |
| def initialize | |
| @array = [] | |
| end | |
| def visit(node, parent = false) | |
| if node_name(parent) == "root" | |
| @media = "all" | |
| end | |
| method = "visit_#{node_name(node)}" | |
| if self.respond_to?(method, true) | |
| self.send(method, node) | |
| else | |
| visit_children(node) | |
| end | |
| @array | |
| end | |
| def visit_children(parent) | |
| parent.children.map {|c| visit(c, parent)} | |
| end | |
| def visit_root(node) | |
| visit_children(node) | |
| end | |
| def visit_media(node) | |
| @media = node.query.join('') | |
| visit_children(node) | |
| end | |
| def visit_rule(node) | |
| @selector = node.rule[0] | |
| visit_children(node) | |
| end | |
| def visit_prop(node) | |
| return unless node.value | |
| @array << { | |
| media: @media, | |
| selector: @selector, | |
| property: node.name[0], | |
| value: node.value.to_sass | |
| } | |
| end | |
| end | |
| class Sass::Tree::Node | |
| def to_a | |
| Sass::Tree::Visitors::ToArray.visit(self) | |
| end | |
| end | |
| # step-startが登録されているkeyframeを抽出する -webkit-animation-nameなどにわけて書いてる場合 => 一旦非対応 | |
| #key_names = [] | |
| #engine = Sass::Engine.for_file('./assets/www/app/stylesheets/main.css.scss', {:syntax => :scss}) | |
| #scss_array = engine.to_tree.to_a | |
| #animation_selectors = [] | |
| #scss_array.each do |a| | |
| # animation_selectors << a if a[:property] == "-webkit-animation-name" | |
| #end | |
| #scss_array.each do |a| | |
| # animation_selectors.each do |s| | |
| # if s[:selector] == a[:selector] && a[:property] == "-webkit-animation-timing-function" && a[:value].include?("step") | |
| # key_names << s[:value] | |
| # end | |
| # end | |
| #end | |
| #p key_names.flatten | |
| # step-startが登録されているkeyframeを抽出する -webkit-animation記法 | |
| engine = Sass::Engine.for_file(BASE_SCSS_LOAD_PATH, {:syntax => :scss}) | |
| scss_array = engine.to_tree.to_a | |
| scss_using_step = scss_array.select do |a| | |
| a[:value].include?("step") | |
| end | |
| key_names_using_step = scss_using_step.map do |scss| | |
| match = scss[:value].scan(/^.*? /) | |
| match << scss[:value].scan(/,.*? /) | |
| match << scss[:value].scan(/, .*? /) | |
| end.flatten.map do |str| | |
| key_name = str.gsub(/ /, "").gsub(/,/, "") | |
| next if key_name == "" | |
| key_name | |
| end.uniq | |
| p key_names_using_step | |
| # android用keyframesの出力のためのデータ整形 | |
| results = [] | |
| engine = Sass::Engine.for_file(BASE_SCSS_LOAD_PATH, {:syntax => :scss}) | |
| tree = engine.to_tree | |
| tree.each do |node| | |
| if node.class == Sass::Tree::DirectiveNode && node.name == "@-webkit-keyframes" && key_names_using_step.include?(node.value[1]) | |
| data = {name: node.name, key_name: node.value[1], frames: {}} | |
| node.children.each do |c_node| | |
| data[:frames][c_node.rule[0].to_s] = [] if c_node.respond_to?(:rule) | |
| if c_node.has_children | |
| c_node.children.each do |cc_node| | |
| property_value = nil | |
| if cc_node.respond_to?(:name) | |
| if cc_node.class == Sass::Tree::PropNode | |
| property_value = cc_node.name[0] + ": " + cc_node.value.to_sass | |
| elsif cc_node.class == Sass::Tree::MixinNode | |
| property_value = "@include " + cc_node.name + "("+cc_node.args.join(",")+")" | |
| end | |
| data[:frames][c_node.rule[0].to_s] << property_value if !property_value.nil? | |
| end | |
| end | |
| end | |
| end | |
| results << data | |
| end | |
| end | |
| p results | |
| # android_keyframes.css.scssの生成 以下のscriptはstep-end用のkeyframesが生成されるようになってる | |
| # データは以下のような感じ | |
| #[{:name=>"@-webkit-keyframes", :key_name=>"\"display_tap_action\"", :frames=>{"0%"=>["bg_image_set(50px,50px,\"../../img/icon/display_tap_action_1@2x.png\")"], "25%"=>["bg_image_set(50px,50px,\"../../img/icon/display_tap_action_2@2x.png\")"], "50%"=>["bg_image_set(50px,50px,\"../../img/icon/display_tap_action_3@2x.png\")"], "75%"=>["bg_image_set(50px,50px,\"../../img/icon/display_tap_action_4@2x.png\")"], "100%"=>["bg_image_set(50px,50px,\"../../img/icon/display_tap_action_5@2x.png\")"]}}] | |
| scss_string = "" | |
| results.each do |result| | |
| str = "#{result[:name]} #{result[:key_name]} {\n" | |
| result[:frames].keys.each_cons(2) do |key, next_key| | |
| str += " #{key} {\n" | |
| result[:frames][key].each do |property_value| | |
| str += " #{property_value};\n" | |
| end | |
| str += " }\n" | |
| if next_key == "to" | |
| next_key_f = 100.0 | |
| else | |
| next_key_f = next_key.gsub(/%/, "").to_f | |
| end | |
| next_key_f = next_key_f - 0.0001 | |
| key_for_step = next_key_f.to_s + "%" | |
| str += " #{key_for_step} {\n" | |
| result[:frames][key].each do |property_value| | |
| str += " #{property_value};\n" | |
| end | |
| str += " }\n" | |
| end | |
| key = result[:frames].keys[-1] | |
| str += " #{key} {\n" | |
| result[:frames][key].each do |property_value| | |
| str += " #{property_value};\n" | |
| end | |
| str += " }\n" | |
| str += "}\n" | |
| scss_string += str | |
| end | |
| File.open(KEYFRAMES_OUTPUT_PATH, "w") do |file| | |
| file.puts scss_string | |
| end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment