Java tutorial
/* * Copyright 2013, 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.cgxlib.xq.client.plugins.effects; /* * #%L * CGXlib * %% * Copyright (C) 2016 CGXlib (http://www.cgxlib.com) * %% * 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. * #L% Code is originally from gwtquery, and modified by CGXlib team. */ import com.cgxlib.xq.client.Properties; import com.cgxlib.xq.client.plugins.Effects.GQAnimation; import com.cgxlib.xq.client.plugins.effects.ClipAnimation.Action; import com.cgxlib.xq.client.plugins.effects.ClipAnimation.Corner; import com.cgxlib.xq.client.plugins.effects.ClipAnimation.Direction; import com.cgxlib.xq.client.plugins.effects.Fx.TransitFx; import com.google.gwt.dom.client.Element; import com.google.gwt.regexp.shared.MatchResult; import com.google.gwt.user.client.Timer; import java.util.List; import static com.cgxlib.xq.client.XQ.$; import static com.cgxlib.xq.client.XQ.$$; import static com.cgxlib.xq.client.plugins.effects.ClipAnimation.getNormalizedValue; /** * Animation effects on any numeric CSS3 property or transformation * using CSS3 transitions. */ public class TransitionsAnimation extends PropertiesAnimation { protected Transitions t; protected int delay = 0; private String oldTransitionValue; public static TransitFx computeFxProp(Element e, String key, String val, boolean hidden) { Transitions g = $(e).as(Transitions.Transitions); String unit = REGEX_NON_PIXEL_ATTRS.test(key) ? "" : "px"; if ("toggle".equals(val)) { val = hidden ? "show" : "hide"; } if ("show".equals(val) && !hidden || "hide".equals(val) && hidden) { return null; } if (hidden) { g.show(); } String cur = g.css(key, true); String trsStart = cur.matches("auto|initial") ? "" : cur, trsEnd = trsStart; if ("show".equals(val)) { g.saveCssAttrs(key); if (trsStart.isEmpty()) { trsStart = "0"; } if (REGEX_SCALE_ATTRS.test(key)) { trsEnd = "1"; } } else if ("hide".equals(val)) { g.saveCssAttrs(key); if (trsStart.isEmpty() && REGEX_SCALE_ATTRS.test(key)) { trsStart = "1"; } trsEnd = "0"; } else { MatchResult parts = REGEX_SYMBOL_NUMBER_UNIT.exec(val); if (parts != null) { String part1 = parts.getGroup(1); String part2 = parts.getGroup(2); String part3 = parts.getGroup(3); trsEnd = "" + Double.parseDouble(part2); if (part3 != null && !part3.isEmpty()) { unit = part3; } if (trsStart.isEmpty()) { trsStart = REGEX_SCALE_ATTRS.test(key) ? "1" : "0"; } if (part1 != null && !part1.isEmpty()) { double n = "-=".equals(part1) ? -1 : 1; double st = 0; MatchResult sparts = REGEX_SYMBOL_NUMBER_UNIT.exec(trsStart); if (sparts != null) { st = Double.parseDouble(sparts.getGroup(2)); unit = sparts.getGroup(3) == null || sparts.getGroup(3).isEmpty() ? unit : sparts.getGroup(3); } trsStart = "" + st; double en = Double.parseDouble(trsEnd); trsEnd = "" + (st + n * en); } // Deal with non px units like "%" if (!unit.isEmpty() && !"px".equals(unit) && trsStart.matches(NUMBER)) { double start = Double.parseDouble(trsStart); if (start != 0) { double to = Double.parseDouble(trsEnd); g.css(key, to + unit); start = to * start / g.cur(key, true); trsStart = "" + start; g.css(key, start + unit); } } } else { trsStart = ""; trsEnd = val; if (trsStart.isEmpty()) { trsStart = REGEX_SCALE_ATTRS.test(key) ? "1" : "0"; } } } if (trsStart.matches(NUMBER)) { trsStart += unit; } if (trsEnd.matches(NUMBER)) { trsEnd += unit; } return new TransitFx(key, val, trsStart, trsEnd, unit); } @Override public GQAnimation setProperties(Properties p) { delay = p.getInt("delay"); return super.setProperties(p); } @Override public GQAnimation setElement(Element elem) { e = elem; g = t = $(elem).as(Transitions.Transitions); return this; } public TransitionsAnimation setDelay(int delay) { this.delay = delay; return this; } public Properties getFxProperties(boolean isStart) { Properties p = $$(); for (int i = 0; i < effects.length(); i++) { TransitFx fx = (TransitFx) effects.get(i); String val = isStart ? fx.transitStart : fx.transitEnd; if (!val.isEmpty()) { p.set(fx.cssprop, val); } } return p; } @Override protected Fx getFx(Element e, String key, String val, boolean hidden) { return Transitions.invalidTransitionNamesRegex.test(key) ? null : computeFxProp(e, key, val, hidden); } @Override public void onUpdate(double progress) { } @Override public void onComplete() { t.css(Transitions.transition, oldTransitionValue); super.onComplete(); } public void run(int duration) { // Calculate all Fx values for this animation onStart(); // Compute initial properties Properties p = getFxProperties(true); t.css(p); // Some browsers need re-flow after setting initial properties (FF 24.4.0). t.offset(); // Compute final properties p = getFxProperties(false); // Save old transition value oldTransitionValue = t.css(Transitions.transition); // Set new transition value String newTransitionValue = ""; List<String> transProps = Transitions.filterTransitionPropertyNames(p); String attribs = duration + "ms" + " " + easing + " " + delay + "ms"; for (String s : transProps) { newTransitionValue += (newTransitionValue.isEmpty() ? "" : ", ") + s + " " + attribs; } t.css(Transitions.transition, newTransitionValue); // Set new css properties so as the element is animated t.css(p); // Wait until transition has finished to run finish animation and dequeue new Timer() { public void run() { onComplete(); } }.schedule(delay + duration); } /** * TransitionAnimation with Clip capabilities. */ public static class TransitionsClipAnimation extends TransitionsAnimation { private Action action; private Corner corner; private Direction direction; private Action currentAction; @Override public GQAnimation setProperties(Properties p) { corner = Corner.CENTER; try { corner = Corner.valueOf(getNormalizedValue("clip-origin", p)); } catch (Exception e) { } direction = Direction.BIDIRECTIONAL; try { direction = Direction.valueOf(getNormalizedValue("clip-direction", p)); } catch (Exception e) { } try { action = Action.valueOf(getNormalizedValue("clip-action", p)); } catch (Exception e) { } return super.setProperties(p); } public void onStart() { boolean hidden = !t.isVisible(); super.onStart(); if (action == null) { return; } currentAction = action != Action.TOGGLE ? action : hidden ? Action.SHOW : Action.HIDE; int bit = currentAction == Action.HIDE ? 1 : 0; String originX = "left", originY = "top"; int scaleXini = 0 ^ bit, scaleYini = scaleXini; int scaleXend = 1 ^ bit, scaleYend = scaleXend; if (direction == Direction.VERTICAL) { scaleXini = scaleXend = 1; } if (direction == Direction.HORIZONTAL) { scaleYini = scaleYend = 1; } if (corner == Corner.CENTER) { originX = originY = "center"; } if (corner == Corner.TOP_RIGHT || corner == Corner.BOTTOM_RIGHT) { originX = "right"; } if (corner == Corner.BOTTOM_LEFT || corner == Corner.BOTTOM_RIGHT) { originY = "bottom"; } t.show().css("transformOrigin", originX + " " + originY); effects.add(new TransitFx("scale", "", scaleXini + " " + scaleYini, scaleXend + " " + scaleYend, "")); } @Override public void onComplete() { super.onComplete(); if (action == null) { return; } if (currentAction == Action.HIDE) { t.hide(); } t.css("transformOrigin", ""); t.css("transform", ""); } } }