All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.gwt.query.client.plugins.effects.PropertiesAnimation Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2011, The gwtquery team.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.google.gwt.query.client.plugins.effects;

import com.google.gwt.dom.client.Element;
import com.google.gwt.query.client.GQuery;
import com.google.gwt.query.client.js.JsObjectArray;
import com.google.gwt.query.client.plugins.Effects;
import com.google.gwt.query.client.plugins.Effects.GQAnimation;
import com.google.gwt.query.client.plugins.effects.Fx.ColorFx;
import com.google.gwt.query.client.plugins.effects.Fx.ColorFx.BorderColorFx;
import com.google.gwt.regexp.shared.MatchResult;
import com.google.gwt.regexp.shared.RegExp;

/**
 * Animation effects on any numeric CSS property.
 */
public class PropertiesAnimation extends GQAnimation {

  /**
   * Easing method to use.
   */
  public interface Easing {
    double interpolate(double progress);

    /**
     * @deprecated use EasingCurve.linear instead
     */
    Easing LINEAR = EasingCurve.linear;

    /**
     * @deprecated use EasingCurve.swing instead
     */
    Easing SWING = EasingCurve.swing;
  }

  /**
   * This is a collection of most popular curves used in web animations
   * implemented using the Bezier Curve instead of a different algorithm per
   * animation.
   *
   * The toString() method returns the string parameter which can be used
   * for CSS3 transition-timing-function properties, example:
   * 

   transition-timing-function: ease;
   transition-timing-function: cubic-bezier(0, 0, 1, 1);

   * 
* * This enum can be used with customized transitions in this way: *

    $("#foo").animate($$("{top:'500px',left:'500px'}"), 400, EasingCurve.custom.with(.02,.01,.47,1));

   * 
* */ public static enum EasingCurve implements Easing { linear(0, 0, 1, 1) { public double interpolate(double p) { return p; } public String toString() { return "linear"; } }, ease(0.25, 0.1, 0.25, 1) { public String toString() { return "ease"; } }, easeIn(0.42, 0, 1, 1) { public String toString() { return "ease-in"; } }, easeOut(0, 0, 0.58, 1) { public String toString() { return "ease-out"; } }, easeInOut(0.42, 0, 0.58, 1) { public String toString() { return "ease-in-out"; } }, snap(0, 1, .5, 1), swing(.02, .01, .47, 1), easeInCubic(.550, .055, .675, .190), easeOutCubic(.215, .61, .355, 1), easeInOutCubic(.645, .045, .355, 1), easeInCirc(.6, .04, .98, .335), easeOutCirc(.075, .82, .165, 1), easeInOutCirc(.785, .135, .15, .86), easeInExpo(.95, .05, .795, .035), easeOutExpo(.19, 1, .22, 1), easeInOutExpo(1, 0, 0, 1), easeInQuad(.55, .085, .68, .53), easeOutQuad(.25, .46, .45, .94), easeInOutQuad(.455, .03, .515, .955), easeInQuart(.895, .03, .685, .22), easeOutQuart(.165, .84, .44, 1), easeInOutQuart(.77, 0, .175, 1), easeInQuint(.755, .05, .855, .06), easeOutQuint(.23, 1, .32, 1), easeInOutQuint(.86, 0, .07, 1), easeInSine(.47, 0, .745, .715), easeOutSine(.39, .575, .565, 1), easeInOutSine(.445, .05, .55, .95), easeInBack(.6, -.28, .735, .045), easeOutBack(.175, .885, .32, 1.275), easeInOutBack(.68, -.55, .265, 1.55), custom(0, 0, 1, 1); private Bezier c = new Bezier(0, 0, 1, 1); EasingCurve(double x1, double y1, double x2, double y2) { with(x1, y1, x2, y2); } public Easing with(double x1, double y1, double x2, double y2) { c = new Bezier(x1, y1, x2, y2); return this; } public double interpolate(double progress) { return c.f(progress); } public String toString() { return "cubic-bezier(" + c + ")"; } } protected static final String[] ATTRS_TO_SAVE = new String[] {"overflow"}; protected static final String NUMBER = "[\\d+-.]+"; protected static final String UNIT = "[a-z%]+"; private static final RegExp REGEX_NUMBER_UNIT = RegExp.compile("^(" + NUMBER + ")(.*)?$"); protected static final RegExp REGEX_SYMBOL_NUMBER_UNIT = RegExp.compile("^([+-]=)?(" + NUMBER + ")(" + UNIT + ")?$"); protected static final RegExp REGEX_SCALE_ATTRS = RegExp.compile("scale|opacity"); protected static final RegExp REGEX_NON_PIXEL_ATTRS = RegExp.compile("scale|opacity" + "|z-?index|font-?weight|zoom|line-?height|rotat|skew|perspect|^\\$", "i"); private static final RegExp REGEX_COLOR_ATTR = RegExp.compile(".*color$", "i"); private static final RegExp REGEX_BORDERCOLOR = RegExp.compile("^bordercolor$", "i"); private static final RegExp REGEX_BACKGROUNDCOLOR = RegExp.compile("^backgroundcolor$", "i"); public static Fx computeFxProp(Element e, String key, String val, boolean hidden) { if (REGEX_COLOR_ATTR.test(key)) { return computeFxColorProp(e, key, val); } return computeFxNumericProp(e, key, val, hidden); } private static Fx computeFxColorProp(Element e, String key, String val) { if (REGEX_BORDERCOLOR.test(key)) { return new BorderColorFx(e, val); } String initialColor = null; if (REGEX_BACKGROUNDCOLOR.test(key)) { // find the first parent having a background-color value (other than // transparent) Element current = e; while ((initialColor == null || initialColor.length() == 0 || initialColor .equals("transparent")) && current != null) { initialColor = GQuery.$(current).css(key, false); current = !"body".equalsIgnoreCase(current.getTagName()) ? current.getParentElement() : null; } if (initialColor == null || initialColor.length() == 0 || initialColor.equals("transparent")) { initialColor = "white"; } } else { initialColor = GQuery.$(e).css(key, true); } return new ColorFx(key, initialColor, val); } public static Fx computeFxNumericProp(Element e, String key, String val, boolean hidden) { GQuery g = Effects.$(e); String unit = ""; if ("toggle".equals(val)) { val = hidden ? "show" : "hide"; } if (("show".equals(val) && !hidden) || ("hide").equals(val) && hidden) { return null; } if (hidden) { g.show(); } // If key starts with $ we animate node attributes, otherwise css properties double cur; String rkey = null; if (key.startsWith("$")) { rkey = key.substring(1).toLowerCase(); String attr = g.attr(rkey); MatchResult parts = REGEX_NUMBER_UNIT.exec(attr); if (parts != null) { String p1 = parts.getGroup(1); String p2 = parts.getGroup(2); cur = Double.parseDouble(p1); unit = p2 == null ? "" : p2; } else { cur = g.cur(key, true); key = rkey; } } else { cur = g.cur(key, true); } double start = cur, end = start; if ("show".equals(val)) { g.saveCssAttrs(key); start = 0; unit = REGEX_NON_PIXEL_ATTRS.test(key) ? "" : "px"; } else if ("hide".equals(val)) { g.saveCssAttrs(key); end = 0; unit = REGEX_NON_PIXEL_ATTRS.test(key) ? "" : "px"; } else { MatchResult parts = REGEX_SYMBOL_NUMBER_UNIT.exec(val); if (parts != null) { String p1 = parts.getGroup(1); String p2 = parts.getGroup(2); String p3 = parts.getGroup(3); end = Double.parseDouble(p2); if (rkey == null) { unit = REGEX_NON_PIXEL_ATTRS.test(key) ? "" : // p3 == null || p3.isEmpty() ? "px" : p3; if (!"px".equals(unit)) { double to = end == 0 ? 1 : end; g.css(key, to + unit); start = to * start / g.cur(key, true); g.css(key, start + unit); } } else if (p3 != null && !p3.isEmpty()) { unit = p3; } if (p1 != null && !p1.isEmpty()) { end = (("-=".equals(p1) ? -1 : 1) * end) + start; } } } return new Fx(key, val, start, end, unit, rkey); } protected JsObjectArray effects; @Override public void onCancel() { Boolean jumpToEnd = Effects.$(e).data(Effects.JUMP_TO_END, Boolean.class); if (jumpToEnd != null && jumpToEnd) { onComplete(); } else { g.dequeue(); g.restoreCssAttrs(ATTRS_TO_SAVE); } } @Override public void onComplete() { super.onComplete(); for (int i = 0; effects != null && i < effects.length(); i++) { Fx fx = effects.get(i); if ("hide".equals(fx.value)) { g.hide(); g.restoreCssAttrs(fx.cssprop); } else if ("show".equals(fx.value)) { g.show(); g.restoreCssAttrs(fx.cssprop); } } g.restoreCssAttrs(ATTRS_TO_SAVE); g.each(funcs); g.dequeue(); } @Override public void onStart() { effects = JsObjectArray.create(); boolean resize = false; boolean move = false; boolean hidden = !g.isVisible(); Fx fx; // g.show(); for (String key : prps.keys()) { String val = prps.getStr(key); if ((fx = getFx(e, key, val, hidden)) != null) { effects.add(fx); resize = resize || "height".equals(key) || "width".equals(key); move = move || "top".equals(key) || "left".equals(key); } } g.saveCssAttrs(ATTRS_TO_SAVE); if (resize) { g.css("overflow", "hidden"); } if (move && !g.css("position", true).matches("absolute|relative|fixed")) { g.css("position", "relative"); } super.onStart(); } protected Fx getFx(Element e, String key, String val, boolean hidden) { return computeFxProp(e, key, val, hidden); } @Override public void onUpdate(double progress) { for (int i = 0; i < effects.length(); i++) { effects.get(i).applyValue(g, progress); } } @Override protected double interpolate(double progress) { return easing.interpolate(progress); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy