/** * Copyright 2010 The ForPlay Authors * * 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 forplay.html; import com.google.gwt.dom.client.Element; import com.google.gwt.dom.client.Style.Display; import com.google.gwt.dom.client.Style.Position; import com.google.gwt.dom.client.Style.Visibility; import forplay.core.AbstractLayer; class HtmlLayerDom extends AbstractLayer { private static final float EPSILON = 0.001f; private static final String[] PREFIXES = new String[] {"Moz", "webkit", "ms", "O"}; private static String transformName, transformOriginName; private static String translateSuffix; private static boolean supports3d; static { int i = 0; for (; i < PREFIXES.length; ++i) { String prefix = PREFIXES[i]; if (hasStyle(prefix + "Transform")) { transformName = prefix + "Transform"; transformOriginName = prefix + "TransformOrigin"; break; } } // Fallback: Assume 'transform' will work. if (i == PREFIXES.length) { transformName = "transform"; transformOriginName = "transformOrigin"; } // Hack: Only WebKit seems to support matrix3d supports3d = "webkitTransform".equals(transformName); // Hack: FF4 appears to require a 'px' suffix on the translation components // of the matrix. translateSuffix = ("MozTransform".equals(transformName)) ? "px" : ""; } private static native boolean hasStyle(String name) /*-{ return (document.body.style[name] !== undefined); }-*/; private final Element elem; HtmlLayerDom(Element elem) { super(); this.elem = elem; elem.getStyle().setPosition(Position.ABSOLUTE); elem.getStyle().setVisibility(Visibility.HIDDEN); elem.getStyle().setProperty(transformOriginName, "0 0"); } @Override public void setAlpha(float alpha) { if (this.alpha != alpha) { super.setAlpha(alpha); elem.getStyle().setOpacity(this.alpha); } } @Override public void setVisible(boolean visible) { super.setVisible(visible); elem.getStyle().setDisplay(visible ? Display.BLOCK : Display.NONE); } public void setOrigin(float x, float y) { super.setOrigin(x, y); } Element element() { return elem; } void update() { if (!isSet(Flag.SHOWN)) { setFlag(Flag.SHOWN, true); elem.getStyle().setVisibility(Visibility.VISIBLE); } float m00 = transform.m00(); float m01 = transform.m01(); float m10 = transform.m10(); float m11 = transform.m11(); float m20 = transform.tx(); float m21 = transform.ty(); String matrix; if (supports3d) { matrix = "matrix3d(" + // css(m00) + "," + css(m01) + ",0,0," + // css(m10) + "," + css(m11) + ",0,0," + // "0,0,1,0," + // xlate(m20) + "," + xlate(m21) + ",0,1" + // ")"; } else { matrix = "matrix(" + // css(m00) + "," + css(m01) + "," + // css(m10) + "," + css(m11) + ", " + // xlate(m20) + "," + xlate(m21) + // ")"; } matrix += " translate(" + css(-originX) + "px," + css(-originY) + "px)"; elem.getStyle().setProperty(transformName, matrix); } private String xlate(float x) { return css(x) + translateSuffix; } private String css(float x) { // This is necessary because CSS transforms don't accept the floating point // form 1.00e1, which is what you naturally get from very small (or large) // floating point values. return (Math.abs(x) < EPSILON) ? "0" : Float.toString(x); } }