Bug 436418, patch D: SVG/SMIL animateMotion - reftests & mochitests.
--HG-- rename : layout/reftests/svg/smil/lime.svg => layout/reftests/svg/smil/motion/lime.svg
|
@ -45,13 +45,18 @@ include $(DEPTH)/config/autoconf.mk
|
|||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
_TEST_FILES = \
|
||||
db_smilAnimateMotion.js \
|
||||
db_smilCSSFromBy.js \
|
||||
db_smilCSSFromTo.js \
|
||||
db_smilCSSPaced.js \
|
||||
db_smilCSSPropertyList.js \
|
||||
db_smilMappedAttrList.js \
|
||||
smilAnimateMotionValueLists.js \
|
||||
smilTestUtils.js \
|
||||
smilXHR_helper.svg \
|
||||
test_smilAnimateMotion.xhtml \
|
||||
test_smilAnimateMotionInvalidValues.xhtml \
|
||||
test_smilAnimateMotionOverrideRules.xhtml \
|
||||
test_smilChangeAfterFrozen.xhtml \
|
||||
test_smilContainerBinding.xhtml \
|
||||
test_smilCrossContainer.xhtml \
|
||||
|
|
|
@ -0,0 +1,286 @@
|
|||
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=2 sw=2 sts=2 et: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (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.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla SMIL Test Code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* the Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Daniel Holbert <dholbert@mozilla.com> (original author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
/* testcase data for <animateMotion> */
|
||||
|
||||
// Fake motion 'attribute', to satisfy testing code that expects an attribute.
|
||||
var gMotionAttr = new AdditiveAttribute(SMILUtil.getMotionFakeAttributeName(),
|
||||
"XML", "rect");
|
||||
|
||||
// CTM-summary-definitions, for re-use by multiple testcase bundles below.
|
||||
var _reusedCTMLists = {
|
||||
pacedBasic: { ctm0: [100, 200, 0],
|
||||
ctm1_6: [105, 205, 0],
|
||||
ctm1_3: [110, 210, 0],
|
||||
ctm2_3: [120, 220, 0],
|
||||
ctm1: [130, 210, 0]
|
||||
},
|
||||
pacedR60: { ctm0: [100, 200, Math.PI/3],
|
||||
ctm1_6: [105, 205, Math.PI/3],
|
||||
ctm1_3: [110, 210, Math.PI/3],
|
||||
ctm2_3: [120, 220, Math.PI/3],
|
||||
ctm1: [130, 210, Math.PI/3]
|
||||
},
|
||||
pacedRAuto: { ctm0: [100, 200, Math.PI/4],
|
||||
ctm1_6: [105, 205, Math.PI/4],
|
||||
ctm1_3: [110, 210, Math.PI/4],
|
||||
ctm2_3: [120, 220, Math.PI/4],
|
||||
ctm1: [130, 210, -Math.PI/4]
|
||||
},
|
||||
pacedRAutoReverse : { ctm0: [100, 200, 5*Math.PI/4],
|
||||
ctm1_6: [105, 205, 5*Math.PI/4],
|
||||
ctm1_3: [110, 210, 5*Math.PI/4],
|
||||
ctm2_3: [120, 220, 5*Math.PI/4],
|
||||
ctm1: [130, 210, 3*Math.PI/4]
|
||||
},
|
||||
|
||||
discreteBasic : { ctm0: [100, 200, 0],
|
||||
ctm1_6: [100, 200, 0],
|
||||
ctm1_3: [120, 220, 0],
|
||||
ctm2_3: [130, 210, 0],
|
||||
ctm1: [130, 210, 0]
|
||||
},
|
||||
discreteRAuto : { ctm0: [100, 200, Math.PI/4],
|
||||
ctm1_6: [100, 200, Math.PI/4],
|
||||
ctm1_3: [120, 220, Math.PI/4],
|
||||
ctm2_3: [130, 210, -Math.PI/4],
|
||||
ctm1: [130, 210, -Math.PI/4]
|
||||
},
|
||||
justMoveBasic : { ctm0: [40, 80, 0],
|
||||
ctm1_6: [40, 80, 0],
|
||||
ctm1_3: [40, 80, 0],
|
||||
ctm2_3: [40, 80, 0],
|
||||
ctm1: [40, 80, 0]
|
||||
},
|
||||
justMoveR60 : { ctm0: [40, 80, Math.PI/3],
|
||||
ctm1_6: [40, 80, Math.PI/3],
|
||||
ctm1_3: [40, 80, Math.PI/3],
|
||||
ctm2_3: [40, 80, Math.PI/3],
|
||||
ctm1: [40, 80, Math.PI/3]
|
||||
},
|
||||
justMoveRAuto : { ctm0: [40, 80, Math.atan(2)],
|
||||
ctm1_6: [40, 80, Math.atan(2)],
|
||||
ctm1_3: [40, 80, Math.atan(2)],
|
||||
ctm2_3: [40, 80, Math.atan(2)],
|
||||
ctm1: [40, 80, Math.atan(2)]
|
||||
},
|
||||
justMoveRAutoReverse : { ctm0: [40, 80, Math.PI + Math.atan(2)],
|
||||
ctm1_6: [40, 80, Math.PI + Math.atan(2)],
|
||||
ctm1_3: [40, 80, Math.PI + Math.atan(2)],
|
||||
ctm2_3: [40, 80, Math.PI + Math.atan(2)],
|
||||
ctm1: [40, 80, Math.PI + Math.atan(2)]
|
||||
},
|
||||
nullMoveBasic : { ctm0: [0, 0, 0],
|
||||
ctm1_6: [0, 0, 0],
|
||||
ctm1_3: [0, 0, 0],
|
||||
ctm2_3: [0, 0, 0],
|
||||
ctm1: [0, 0, 0]
|
||||
},
|
||||
nullMoveRAutoReverse : { ctm0: [0, 0, Math.PI],
|
||||
ctm1_6: [0, 0, Math.PI],
|
||||
ctm1_3: [0, 0, Math.PI],
|
||||
ctm2_3: [0, 0, Math.PI],
|
||||
ctm1: [0, 0, Math.PI]
|
||||
},
|
||||
};
|
||||
|
||||
var gMotionBundles =
|
||||
[
|
||||
// Bundle to test basic functionality (using default calcMode='paced')
|
||||
new TestcaseBundle(gMotionAttr, [
|
||||
// Basic paced-mode (default) test, with values/mpath/path
|
||||
new AnimMotionTestcase({ "values": "100, 200; 120, 220; 130, 210" },
|
||||
_reusedCTMLists.pacedBasic),
|
||||
new AnimMotionTestcase({ "path": "M100 200 L120 220 L130 210" },
|
||||
_reusedCTMLists.pacedBasic),
|
||||
new AnimMotionTestcase({ "mpath": "M100 200 L120 220 L130 210" },
|
||||
_reusedCTMLists.pacedBasic),
|
||||
|
||||
// ..and now with rotate=constant value in degrees
|
||||
new AnimMotionTestcase({ "values": "100,200; 120,220; 130, 210",
|
||||
"rotate": "60" },
|
||||
_reusedCTMLists.pacedR60),
|
||||
new AnimMotionTestcase({ "path": "M100 200 L120 220 L130 210",
|
||||
"rotate": "60" },
|
||||
_reusedCTMLists.pacedR60),
|
||||
new AnimMotionTestcase({ "mpath": "M100 200 L120 220 L130 210",
|
||||
"rotate": "60" },
|
||||
_reusedCTMLists.pacedR60),
|
||||
|
||||
// ..and now with rotate=constant value in radians
|
||||
new AnimMotionTestcase({ "path": "M100 200 L120 220 L130 210",
|
||||
"rotate": "1.0471975512rad" }, // pi/3
|
||||
_reusedCTMLists.pacedR60),
|
||||
|
||||
// ..and now with rotate=auto
|
||||
new AnimMotionTestcase({ "values": "100,200; 120,220; 130, 210",
|
||||
"rotate": "auto" },
|
||||
_reusedCTMLists.pacedRAuto),
|
||||
new AnimMotionTestcase({ "path": "M100 200 L120 220 L130 210",
|
||||
"rotate": "auto" },
|
||||
_reusedCTMLists.pacedRAuto),
|
||||
new AnimMotionTestcase({ "mpath": "M100 200 L120 220 L130 210",
|
||||
"rotate": "auto" },
|
||||
_reusedCTMLists.pacedRAuto),
|
||||
|
||||
// ..and now with rotate=auto-reverse
|
||||
new AnimMotionTestcase({ "values": "100,200; 120,220; 130, 210",
|
||||
"rotate": "auto-reverse" },
|
||||
_reusedCTMLists.pacedRAutoReverse),
|
||||
new AnimMotionTestcase({ "path": "M100 200 L120 220 L130 210",
|
||||
"rotate": "auto-reverse" },
|
||||
_reusedCTMLists.pacedRAutoReverse),
|
||||
new AnimMotionTestcase({ "mpath": "M100 200 L120 220 L130 210",
|
||||
"rotate": "auto-reverse" },
|
||||
_reusedCTMLists.pacedRAutoReverse),
|
||||
|
||||
]),
|
||||
|
||||
// Bundle to test calcMode='discrete'
|
||||
new TestcaseBundle(gMotionAttr, [
|
||||
new AnimMotionTestcase({ "values": "100, 200; 120, 220; 130, 210",
|
||||
"calcMode": "discrete" },
|
||||
_reusedCTMLists.discreteBasic),
|
||||
new AnimMotionTestcase({ "path": "M100 200 L120 220 L130 210",
|
||||
"calcMode": "discrete" },
|
||||
_reusedCTMLists.discreteBasic),
|
||||
new AnimMotionTestcase({ "mpath": "M100 200 L120 220 L130 210",
|
||||
"calcMode": "discrete" },
|
||||
_reusedCTMLists.discreteBasic),
|
||||
// ..and now with rotate=auto
|
||||
new AnimMotionTestcase({ "values": "100, 200; 120, 220; 130, 210",
|
||||
"calcMode": "discrete",
|
||||
"rotate": "auto" },
|
||||
_reusedCTMLists.discreteRAuto),
|
||||
new AnimMotionTestcase({ "path": "M100 200 L120 220 L130 210",
|
||||
"calcMode": "discrete",
|
||||
"rotate": "auto" },
|
||||
_reusedCTMLists.discreteRAuto),
|
||||
new AnimMotionTestcase({ "mpath": "M100 200 L120 220 L130 210",
|
||||
"calcMode": "discrete",
|
||||
"rotate": "auto" },
|
||||
_reusedCTMLists.discreteRAuto),
|
||||
]),
|
||||
|
||||
// Bundle to test relative units ('em')
|
||||
new TestcaseBundle(gMotionAttr, [
|
||||
// First with unitless values from->by...
|
||||
new AnimMotionTestcase({ "from": "10, 10",
|
||||
"by": "30, 60" },
|
||||
{ ctm0: [10, 10, 0],
|
||||
ctm1_6: [15, 20, 0],
|
||||
ctm1_3: [20, 30, 0],
|
||||
ctm2_3: [30, 50, 0],
|
||||
ctm1: [40, 70, 0]
|
||||
}),
|
||||
// ... then add 'em' units (with 1em=10px) on half the values
|
||||
new AnimMotionTestcase({ "from": "1em, 10",
|
||||
"by": "30, 6em" },
|
||||
{ ctm0: [10, 10, 0],
|
||||
ctm1_6: [15, 20, 0],
|
||||
ctm1_3: [20, 30, 0],
|
||||
ctm2_3: [30, 50, 0],
|
||||
ctm1: [40, 70, 0]
|
||||
}),
|
||||
]),
|
||||
|
||||
// Bundle to test a path with just a "move" command and nothing else
|
||||
new TestcaseBundle(gMotionAttr, [
|
||||
new AnimMotionTestcase({ "values": "40, 80" },
|
||||
_reusedCTMLists.justMoveBasic),
|
||||
new AnimMotionTestcase({ "path": "M40 80" },
|
||||
_reusedCTMLists.justMoveBasic),
|
||||
new AnimMotionTestcase({ "mpath": "m40 80" },
|
||||
_reusedCTMLists.justMoveBasic),
|
||||
]),
|
||||
// ... and now with a fixed rotate-angle
|
||||
new TestcaseBundle(gMotionAttr, [
|
||||
new AnimMotionTestcase({ "values": "40, 80",
|
||||
"rotate": "60" },
|
||||
_reusedCTMLists.justMoveR60),
|
||||
new AnimMotionTestcase({ "path": "M40 80",
|
||||
"rotate": "60" },
|
||||
_reusedCTMLists.justMoveR60),
|
||||
new AnimMotionTestcase({ "mpath": "m40 80",
|
||||
"rotate": "60" },
|
||||
_reusedCTMLists.justMoveR60),
|
||||
]),
|
||||
// ... and now with 'auto' (should use the move itself as
|
||||
// our tangent angle, I think)
|
||||
new TestcaseBundle(gMotionAttr, [
|
||||
new AnimMotionTestcase({ "values": "40, 80",
|
||||
"rotate": "auto" },
|
||||
_reusedCTMLists.justMoveRAuto),
|
||||
new AnimMotionTestcase({ "path": "M40 80",
|
||||
"rotate": "auto" },
|
||||
_reusedCTMLists.justMoveRAuto),
|
||||
new AnimMotionTestcase({ "mpath": "m40 80",
|
||||
"rotate": "auto" },
|
||||
_reusedCTMLists.justMoveRAuto),
|
||||
]),
|
||||
// ... and now with 'auto-reverse'
|
||||
new TestcaseBundle(gMotionAttr, [
|
||||
new AnimMotionTestcase({ "values": "40, 80",
|
||||
"rotate": "auto-reverse" },
|
||||
_reusedCTMLists.justMoveRAutoReverse),
|
||||
new AnimMotionTestcase({ "path": "M40 80",
|
||||
"rotate": "auto-reverse" },
|
||||
_reusedCTMLists.justMoveRAutoReverse),
|
||||
new AnimMotionTestcase({ "mpath": "m40 80",
|
||||
"rotate": "auto-reverse" },
|
||||
_reusedCTMLists.justMoveRAutoReverse),
|
||||
]),
|
||||
// ... and now with a null move to make sure 'auto'/'auto-reverse' don't
|
||||
// blow up
|
||||
new TestcaseBundle(gMotionAttr, [
|
||||
new AnimMotionTestcase({ "values": "0, 0",
|
||||
"rotate": "auto" },
|
||||
_reusedCTMLists.nullMoveBasic),
|
||||
]),
|
||||
new TestcaseBundle(gMotionAttr, [
|
||||
new AnimMotionTestcase({ "values": "0, 0",
|
||||
"rotate": "auto-reverse" },
|
||||
_reusedCTMLists.nullMoveRAutoReverse),
|
||||
]),
|
||||
];
|
||||
|
||||
// XXXdholbert Add more tests:
|
||||
// - keyPoints/keyTimes
|
||||
// - paths with curves
|
||||
// - Control path with from/by/to
|
|
@ -0,0 +1,124 @@
|
|||
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=2 sw=2 sts=2 et: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (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.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla SMIL Test Code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* the Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Daniel Holbert <dholbert@mozilla.com> (original author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
/* Lists of valid & invalid values for the various <animateMotion> attributes */
|
||||
const gValidValues = [
|
||||
"10 10",
|
||||
" 10 10em ",
|
||||
"1 2 ; 3,4",
|
||||
"1,2;3,4",
|
||||
"0 0",
|
||||
"0,0",
|
||||
];
|
||||
|
||||
const gInvalidValues = [
|
||||
"10 10;", // We treat semicolon-terminated value-lists as failure cases
|
||||
"1 2 3",
|
||||
"1 2 3 4",
|
||||
"1,2;3,4 ,",
|
||||
",", ";", "a", "", " ",
|
||||
];
|
||||
|
||||
const gInvalidValuesTodo = [
|
||||
"1,2;3,4,",
|
||||
"1,,2",
|
||||
",1,2",
|
||||
];
|
||||
|
||||
const gValidRotate = [
|
||||
"10",
|
||||
"20.1",
|
||||
"30.5deg",
|
||||
"0.5rad",
|
||||
"auto",
|
||||
"auto-reverse"
|
||||
];
|
||||
|
||||
const gInvalidRotate = [
|
||||
" 10 ",
|
||||
" 10deg",
|
||||
"10 deg",
|
||||
"10deg ",
|
||||
"10 rad ",
|
||||
"aaa",
|
||||
" 10.1 ",
|
||||
];
|
||||
|
||||
const gValidToBy = [
|
||||
"0 0",
|
||||
"1em,2",
|
||||
"50.3em 0.2in"
|
||||
];
|
||||
|
||||
const gInvalidToBy = [
|
||||
"0 0 0",
|
||||
"0 0,0",
|
||||
"0,0,0",
|
||||
"1emm 2",
|
||||
"1 2;",
|
||||
" 1,2 ,",
|
||||
"abc",
|
||||
",",
|
||||
""
|
||||
];
|
||||
|
||||
const gInvalidToByTodo = [
|
||||
"1,,2",
|
||||
"1,2,",
|
||||
" 1,2",
|
||||
"1 2 "
|
||||
];
|
||||
|
||||
const gValidPath = [
|
||||
"m0 0 L30 30",
|
||||
"M20,20L10 10",
|
||||
"M20,20 L30, 30h20",
|
||||
"m50 50", "M50 50",
|
||||
"m0 0", "M0, 0"
|
||||
];
|
||||
|
||||
const gInvalidPath = [
|
||||
"m0 0 L30,,30",
|
||||
"M20 20em",
|
||||
"M20in 20",
|
||||
"h30",
|
||||
"L50 50",
|
||||
"abc",
|
||||
"M10 10 L50 50 abc",
|
||||
];
|
|
@ -39,6 +39,9 @@
|
|||
// Note: Class syntax roughly based on:
|
||||
// https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Inheritance
|
||||
const SVG_NS = "http://www.w3.org/2000/svg";
|
||||
const XLINK_NS = "http://www.w3.org/1999/xlink";
|
||||
|
||||
const MPATH_TARGET_ID = "smilTestUtilsTestingPath";
|
||||
|
||||
function extend(child, supertype)
|
||||
{
|
||||
|
@ -85,11 +88,16 @@ var SMILUtil =
|
|||
|
||||
getAttributeValue: function(elem, attr)
|
||||
{
|
||||
if (attr.attrName == SMILUtil.getMotionFakeAttributeName()) {
|
||||
// Fake motion "attribute" -- "computed value" is the element's CTM
|
||||
return elem.getCTM();
|
||||
}
|
||||
if (attr.attrType == "CSS") {
|
||||
return SMILUtil.getComputedStyleWrapper(elem, attr.attrName);
|
||||
} else if (attr.attrType == "XML") {
|
||||
}
|
||||
if (attr.attrType == "XML") {
|
||||
// XXXdholbert This is appropriate for mapped attributes, but not
|
||||
// for others.
|
||||
// for other attributes.
|
||||
return SMILUtil.getComputedStyleWrapper(elem, attr.attrName);
|
||||
}
|
||||
},
|
||||
|
@ -168,7 +176,82 @@ var SMILUtil =
|
|||
child = child.nextSibling;
|
||||
}
|
||||
},
|
||||
|
||||
getMotionFakeAttributeName : function() {
|
||||
return "_motion";
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
var CTMUtil =
|
||||
{
|
||||
CTM_COMPONENTS_ALL : ["a", "b", "c", "d", "e", "f"],
|
||||
CTM_COMPONENTS_ROTATE : ["a", "b", "c", "d" ],
|
||||
|
||||
// Function to generate a CTM Matrix from a "summary"
|
||||
// (a 3-tuple containing [tX, tY, theta])
|
||||
generateCTM : function(aCtmSummary)
|
||||
{
|
||||
if (!aCtmSummary || aCtmSummary.length != 3) {
|
||||
ok(false, "Unexpected CTM summary tuple length: " + aCtmSummary.length);
|
||||
}
|
||||
var tX = aCtmSummary[0];
|
||||
var tY = aCtmSummary[1];
|
||||
var theta = aCtmSummary[2];
|
||||
var cosTheta = Math.cos(theta);
|
||||
var sinTheta = Math.sin(theta);
|
||||
var newCtm = { a : cosTheta, c: -sinTheta, e: tX,
|
||||
b : sinTheta, d: cosTheta, f: tY };
|
||||
return newCtm;
|
||||
},
|
||||
|
||||
/// Helper for isCtmEqual
|
||||
isWithinDelta : function(aTestVal, aExpectedVal, aErrMsg, aIsTodo) {
|
||||
var testFunc = aIsTodo ? todo : ok;
|
||||
const delta = 0.000001; // allowing margin of error = 10^-6
|
||||
ok(aTestVal >= aExpectedVal - delta &&
|
||||
aTestVal <= aExpectedVal + delta,
|
||||
aErrMsg + " | got: " + aTestVal + ", expected: " + aExpectedVal);
|
||||
},
|
||||
|
||||
assertCTMEqual : function(aLeftCtm, aRightCtm, aComponentsToCheck,
|
||||
aErrMsg, aIsTodo) {
|
||||
var foundCTMDifference = false;
|
||||
for (var j in aComponentsToCheck) {
|
||||
var curComponent = aComponentsToCheck[j];
|
||||
if (!aIsTodo) {
|
||||
CTMUtil.isWithinDelta(aLeftCtm[curComponent], aRightCtm[curComponent],
|
||||
aErrMsg + " | component: " + curComponent, false);
|
||||
} else if (aLeftCtm[curComponent] != aRightCtm[curComponent]) {
|
||||
foundCTMDifference = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (aIsTodo) {
|
||||
todo(!foundCTMDifference, aErrMsg + " | (currently marked todo)");
|
||||
}
|
||||
},
|
||||
|
||||
assertCTMNotEqual : function(aLeftCtm, aRightCtm, aComponentsToCheck,
|
||||
aErrMsg, aIsTodo) {
|
||||
// CTM should not match initial one
|
||||
var foundCTMDifference = false;
|
||||
for (var j in aComponentsToCheck) {
|
||||
var curComponent = aComponentsToCheck[j];
|
||||
if (aLeftCtm[curComponent] != aRightCtm[curComponent]) {
|
||||
foundCTMDifference = true;
|
||||
break; // We found a difference, as expected. Success!
|
||||
}
|
||||
}
|
||||
|
||||
if (aIsTodo) {
|
||||
todo(foundCTMDifference, aErrMsg + " | (currently marked todo)");
|
||||
} else {
|
||||
ok(foundCTMDifference, aErrMsg);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
// Wrapper for timing information
|
||||
function SMILTimingData(aBegin, aDur)
|
||||
|
@ -685,6 +768,154 @@ AnimTestcasePaced.prototype =
|
|||
};
|
||||
extend(AnimTestcasePaced, AnimTestcase);
|
||||
|
||||
/*
|
||||
* A testcase for an <animateMotion> animation.
|
||||
*
|
||||
* @param aAttrValueHash A hash-map mapping attribute names to values.
|
||||
* Should include at least 'path', 'values', 'to'
|
||||
* or 'by' to describe the motion path.
|
||||
* @param aCtmMap A hash-map that contains summaries of the expected resulting
|
||||
* CTM at various points during the animation. The CTM is
|
||||
* summarized as a tuple of three numbers: [tX, tY, theta]
|
||||
(indicating a translate(tX,tY) followed by a rotate(theta))
|
||||
* - ctm0: The CTM summary at the start of the animation
|
||||
* - ctm1_6: The CTM summary at exactly 1/6 through animation
|
||||
* - ctm1_3: The CTM summary at exactly 1/3 through animation
|
||||
* - ctm2_3: The CTM summary at exactly 2/3 through animation
|
||||
* - ctm1: The CTM summary at the animation endpoint
|
||||
*
|
||||
* NOTE: For paced-mode animation (the default for animateMotion), the math
|
||||
* works out easiest if:
|
||||
* (a) our motion path has 3 points: vA, vB, vC
|
||||
* (b) dist(vB, vC) = 2 * dist(vA, vB)
|
||||
* (See discussion in header comment for AnimTestcasePaced.)
|
||||
*
|
||||
* @param aSkipReason If this test-case is known to currently fail, this
|
||||
* parameter should be a string explaining why.
|
||||
* Otherwise, this value should be null (or omitted).
|
||||
*/
|
||||
function AnimMotionTestcase(aAttrValueHash, aCtmMap, aSkipReason)
|
||||
{
|
||||
this.attrValueHash = aAttrValueHash;
|
||||
this.ctmMap = aCtmMap;
|
||||
this.skipReason = aSkipReason;
|
||||
if (this.ctmMap &&
|
||||
(!this.ctmMap.ctm0 ||
|
||||
!this.ctmMap.ctm1_6 ||
|
||||
!this.ctmMap.ctm1_3 ||
|
||||
!this.ctmMap.ctm2_3 ||
|
||||
!this.ctmMap.ctm1)) {
|
||||
ok(false, "This AnimMotionTestcase has an incomplete CTM map");
|
||||
}
|
||||
}
|
||||
AnimMotionTestcase.prototype =
|
||||
{
|
||||
// Member variables
|
||||
_animElementTagName : "animateMotion",
|
||||
|
||||
// Implementations of inherited methods that we need to override:
|
||||
// --------------------------------------------------------------
|
||||
setupAnimationElement : function(aAnimAttr, aTimeData, aIsFreeze)
|
||||
{
|
||||
var animElement = document.createElementNS(SVG_NS,
|
||||
this._animElementTagName);
|
||||
animElement.setAttribute("begin", aTimeData.getBeginTime());
|
||||
animElement.setAttribute("dur", aTimeData.getDur());
|
||||
if (aIsFreeze) {
|
||||
animElement.setAttribute("fill", "freeze");
|
||||
}
|
||||
for (var attrName in this.attrValueHash) {
|
||||
if (attrName == "mpath") {
|
||||
this.createPath(this.attrValueHash[attrName]);
|
||||
this.createMpath(animElement);
|
||||
} else {
|
||||
animElement.setAttribute(attrName, this.attrValueHash[attrName]);
|
||||
}
|
||||
}
|
||||
return animElement;
|
||||
},
|
||||
|
||||
createPath : function(aPathDescription)
|
||||
{
|
||||
var path = document.createElementNS(SVG_NS, "path");
|
||||
path.setAttribute("d", aPathDescription);
|
||||
path.setAttribute("id", MPATH_TARGET_ID);
|
||||
return SMILUtil.getSVGRoot().appendChild(path);
|
||||
},
|
||||
|
||||
createMpath : function(aAnimElement)
|
||||
{
|
||||
var mpath = document.createElementNS(SVG_NS, "mpath");
|
||||
mpath.setAttributeNS(XLINK_NS, "href", "#" + MPATH_TARGET_ID);
|
||||
return aAnimElement.appendChild(mpath);
|
||||
},
|
||||
|
||||
// Override inherited seekAndTest method since...
|
||||
// (a) it expects a computedValMap and we have a computed-CTM map instead
|
||||
// and (b) it expects we might have no effect (for non-animatable attrs)
|
||||
buildSeekList : function(aAnimAttr, aBaseVal, aTimeData, aIsFreeze)
|
||||
{
|
||||
var seekList = new Array();
|
||||
var msgPrefix = "CTM mismatch ";
|
||||
seekList.push([aTimeData.getBeginTime(),
|
||||
CTMUtil.generateCTM(this.ctmMap.ctm0),
|
||||
msgPrefix + "at start of animation"]);
|
||||
seekList.push([aTimeData.getFractionalTime(1/6),
|
||||
CTMUtil.generateCTM(this.ctmMap.ctm1_6),
|
||||
msgPrefix + "1/6 of the way through animation."]);
|
||||
seekList.push([aTimeData.getFractionalTime(1/3),
|
||||
CTMUtil.generateCTM(this.ctmMap.ctm1_3),
|
||||
msgPrefix + "1/3 of the way through animation."]);
|
||||
seekList.push([aTimeData.getFractionalTime(2/3),
|
||||
CTMUtil.generateCTM(this.ctmMap.ctm2_3),
|
||||
msgPrefix + "2/3 of the way through animation."]);
|
||||
|
||||
var finalMsg;
|
||||
var expectedEndVal;
|
||||
if (aIsFreeze) {
|
||||
expectedEndVal = CTMUtil.generateCTM(this.ctmMap.ctm1);
|
||||
finalMsg = aAnimAttr.attrName +
|
||||
": [freeze-mode] checking that final value is set ";
|
||||
} else {
|
||||
expectedEndVal = aBaseVal;
|
||||
finalMsg = aAnimAttr.attrName +
|
||||
": [remove-mode] checking that animation is cleared ";
|
||||
}
|
||||
seekList.push([aTimeData.getEndTime(),
|
||||
expectedEndVal, finalMsg + "at end of animation"]);
|
||||
seekList.push([aTimeData.getEndTime() + aTimeData.getDur(),
|
||||
expectedEndVal, finalMsg + "after end of animation"]);
|
||||
return seekList;
|
||||
},
|
||||
|
||||
// Override inherited seekAndTest method
|
||||
// (Have to use assertCTMEqual() instead of is() for comparison, to check each
|
||||
// component of the CTM and to allow for a small margin of error.)
|
||||
seekAndTest : function(aSeekList, aTargetElem, aTargetAttr)
|
||||
{
|
||||
var svg = document.getElementById("svg");
|
||||
for (var i in aSeekList) {
|
||||
var entry = aSeekList[i];
|
||||
SMILUtil.getSVGRoot().setCurrentTime(entry[0]);
|
||||
CTMUtil.assertCTMEqual(aTargetElem.getCTM(), entry[1],
|
||||
CTMUtil.CTM_COMPONENTS_ALL, entry[2], false);
|
||||
}
|
||||
},
|
||||
|
||||
// Override "runTest" method so we can remove any <path> element that we
|
||||
// created at the end of each test.
|
||||
runTest : function(aTargetElem, aTargetAttr, aTimeData, aIsFreeze)
|
||||
{
|
||||
AnimTestcase.prototype.runTest.apply(this,
|
||||
[aTargetElem, aTargetAttr, aTimeData, aIsFreeze]);
|
||||
var pathElem = document.getElementById(MPATH_TARGET_ID);
|
||||
if (pathElem) {
|
||||
SMILUtil.getSVGRoot().removeChild(pathElem);
|
||||
}
|
||||
}
|
||||
};
|
||||
extend(AnimMotionTestcase, AnimTestcase);
|
||||
|
||||
// MAIN METHOD
|
||||
function testBundleList(aBundleList, aTimingData)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=436418
|
||||
-->
|
||||
<head>
|
||||
<title>Test for animateMotion behavior</title>
|
||||
<script type="text/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="smilTestUtils.js"></script>
|
||||
<script type="text/javascript" src="db_smilAnimateMotion.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=436418">Mozilla Bug 436418</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="visibility: hidden">
|
||||
|
||||
<!-- NOTE: Setting font-size so we can test 'em' units -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
width="200px" height="200px" style="font-size: 500px"
|
||||
onload="this.pauseAnimations()">
|
||||
<!-- XXXdholbert Right now, 'em' conversions are correct if we set font-size
|
||||
on rect using the inline style attr. However, if we use 'font-size' attr,
|
||||
then 'em' units end up using the inherited font-size instead. Bug? -->
|
||||
<rect x="20" y="20" width="200" height="200" style="font-size: 10px"/>
|
||||
</svg>
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
<![CDATA[
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
function main()
|
||||
{
|
||||
if (!SMILUtil.isSMILEnabled()) {
|
||||
ok(false, "SMIL dosn't seem to be enabled");
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
}
|
||||
|
||||
// Start out with document paused
|
||||
var svg = SMILUtil.getSVGRoot();
|
||||
ok(svg.animationsPaused(), "should be paused by <svg> load handler");
|
||||
is(svg.getCurrentTime(), 0, "should be paused at 0 in <svg> load handler");
|
||||
|
||||
var timingData = new SMILTimingData(1.0, 6.0);
|
||||
testBundleList(gMotionBundles, timingData);
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
window.addEventListener("load", main, false);
|
||||
]]>
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,175 @@
|
|||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=436418
|
||||
-->
|
||||
<head>
|
||||
<title>Test for animateMotion acceptance of invalid values</title>
|
||||
<script type="text/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="smilTestUtils.js" />
|
||||
<script type="text/javascript" src="smilAnimateMotionValueLists.js" />
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=436418">Mozilla Bug 436418</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="visibility: hidden">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" id="svg"
|
||||
width="200px" height="200px"
|
||||
onload="this.pauseAnimations()">
|
||||
<rect id="rect" x="20" y="20" width="200" height="200"/>
|
||||
</svg>
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
<![CDATA[
|
||||
|
||||
// Constant strings (& string-arrays)
|
||||
const SVGNS = "http://www.w3.org/2000/svg";
|
||||
const XLINKNS = "http://www.w3.org/1999/xlink";
|
||||
|
||||
// Constant objects
|
||||
const gSvg = document.getElementById("svg");
|
||||
const gRect = document.getElementById("rect");
|
||||
const gUnAnimatedCTM = gRect.getCTM();
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
function createAnim()
|
||||
{
|
||||
var anim = document.createElementNS(SVGNS, "animateMotion");
|
||||
anim.setAttribute("dur", "2s");
|
||||
return gRect.appendChild(anim);
|
||||
}
|
||||
|
||||
function removeElem(aElem)
|
||||
{
|
||||
aElem.parentNode.removeChild(aElem);
|
||||
}
|
||||
|
||||
function testAttr(aAttrName, aAttrValueArray, aIsValid, aIsTodo)
|
||||
{
|
||||
var componentsToCheck;
|
||||
|
||||
for (var i in aAttrValueArray) {
|
||||
var curVal = aAttrValueArray[i];
|
||||
var anim = createAnim();
|
||||
anim.setAttribute(aAttrName, curVal);
|
||||
if (aAttrName == "rotate") {
|
||||
// Apply a diagonal translation (so rotate='auto' will have an effect)
|
||||
// and just test the rotation matrix components
|
||||
anim.setAttribute("values", "0 0; 50 50");
|
||||
componentsToCheck = CTMUtil.CTM_COMPONENTS_ROTATE;
|
||||
} else {
|
||||
// Apply a supplementary rotation to make sure that we don't apply it if
|
||||
// our value is rejected.
|
||||
anim.setAttribute("rotate", Math.PI/4);
|
||||
componentsToCheck = CTMUtil.CTM_COMPONENTS_ALL;
|
||||
}
|
||||
|
||||
var curCTM = gRect.getCTM();
|
||||
if (aIsValid) {
|
||||
var errMsg = "CTM should have changed when applying animateMotion " +
|
||||
"with '" + aAttrName + "' set to valid value '" + curVal + "'";
|
||||
CTMUtil.assertCTMNotEqual(curCTM, gUnAnimatedCTM, componentsToCheck,
|
||||
errMsg, aIsTodo);
|
||||
} else {
|
||||
var errMsg = "CTM should not have changed when applying animateMotion " +
|
||||
"with '" + aAttrName + "' set to invalid value '" + curVal + "'";
|
||||
CTMUtil.assertCTMEqual(curCTM, gUnAnimatedCTM, componentsToCheck,
|
||||
errMsg, aIsTodo);
|
||||
}
|
||||
removeElem(anim);
|
||||
}
|
||||
}
|
||||
|
||||
function createPath(aPathDescription)
|
||||
{
|
||||
var path = document.createElementNS(SVGNS, "path");
|
||||
path.setAttribute("d", aPathDescription);
|
||||
path.setAttribute("id", "thePath");
|
||||
return gSvg.appendChild(path);
|
||||
}
|
||||
|
||||
function createMpath(aAnimElement)
|
||||
{
|
||||
var mpath = document.createElementNS(SVGNS, "mpath");
|
||||
mpath.setAttributeNS(XLINKNS, "href", "#thePath");
|
||||
return aAnimElement.appendChild(mpath);
|
||||
}
|
||||
|
||||
function testMpathElem(aPathValueArray, aIsValid, aIsTodo)
|
||||
{
|
||||
for (var i in aPathValueArray) {
|
||||
var curVal = aPathValueArray[i];
|
||||
var anim = createAnim();
|
||||
var mpath = createMpath(anim);
|
||||
var path = createPath(curVal);
|
||||
|
||||
// Apply a supplementary rotation to make sure that we don't apply it if
|
||||
// our value is rejected.
|
||||
anim.setAttribute("rotate", Math.PI/4);
|
||||
componentsToCheck = CTMUtil.CTM_COMPONENTS_ALL;
|
||||
|
||||
if (aIsValid) {
|
||||
var errMsg = "CTM should have changed when applying animateMotion " +
|
||||
"with mpath linking to a path with valid value '" + curVal + "'";
|
||||
|
||||
CTMUtil.assertCTMNotEqual(gRect.getCTM(), gUnAnimatedCTM,
|
||||
componentsToCheck, errMsg, aIsTodo);
|
||||
} else {
|
||||
var errMsg = "CTM should not have changed when applying animateMotion " +
|
||||
"with mpath linking to a path with invalid value '" + curVal + "'";
|
||||
CTMUtil.assertCTMEqual(gRect.getCTM(), gUnAnimatedCTM,
|
||||
componentsToCheck, errMsg, aIsTodo);
|
||||
}
|
||||
removeElem(anim);
|
||||
removeElem(path);
|
||||
removeElem(mpath);
|
||||
}
|
||||
}
|
||||
|
||||
// Main Function
|
||||
function main()
|
||||
{
|
||||
if (!SMILUtil.isSMILEnabled()) {
|
||||
ok(false, "SMIL dosn't seem to be enabled");
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
}
|
||||
|
||||
// Start out with document paused
|
||||
var svg = SMILUtil.getSVGRoot();
|
||||
ok(svg.animationsPaused(), "should be paused by <svg> load handler");
|
||||
is(svg.getCurrentTime(), 0, "should be paused at 0 in <svg> load handler");
|
||||
|
||||
testAttr("values", gValidValues, true, false);
|
||||
testAttr("values", gInvalidValues, false, false);
|
||||
testAttr("values", gInvalidValuesTodo, false, true);
|
||||
|
||||
testAttr("rotate", gValidRotate, true, false);
|
||||
testAttr("rotate", gInvalidRotate, false, false);
|
||||
|
||||
testAttr("to", gValidToBy, true, false);
|
||||
testAttr("to", gInvalidToBy, false, false);
|
||||
testAttr("to", gInvalidToByTodo, false, true);
|
||||
|
||||
testAttr("by", gValidToBy, true, false);
|
||||
testAttr("by", gInvalidToBy, false, false);
|
||||
testAttr("by", gInvalidToByTodo, false, true);
|
||||
|
||||
testAttr("path", gValidPath, true, false);
|
||||
testAttr("path", gInvalidPath, false, false);
|
||||
|
||||
testMpathElem(gValidPath, true, false);
|
||||
testMpathElem(gInvalidPath, false, false);
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
window.addEventListener("load", main, false);
|
||||
]]>
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,222 @@
|
|||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=436418
|
||||
-->
|
||||
<head>
|
||||
<title>Test for overriding of path-defining attributes for animateMotion</title>
|
||||
<script type="text/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="smilTestUtils.js" />
|
||||
<script type="text/javascript" src="smilAnimateMotionValueLists.js" />
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=436418">Mozilla Bug 436418</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="visibility: hidden">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" id="svg"
|
||||
width="200px" height="200px"
|
||||
onload="this.pauseAnimations()">
|
||||
<!-- Paths for mpath to refer to -->
|
||||
<path id="validPathElem" d="M10 10 h-10"/>
|
||||
<path id="invalidPathElem" d="abc"/>
|
||||
|
||||
<!-- The rect whose motion is animated -->
|
||||
<rect id="rect" x="20" y="20" width="200" height="200"/>
|
||||
</svg>
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
<![CDATA[
|
||||
|
||||
// Constant strings (& string-arrays)
|
||||
const SVGNS = "http://www.w3.org/2000/svg";
|
||||
const XLINKNS = "http://www.w3.org/1999/xlink";
|
||||
|
||||
// Constant objects
|
||||
const gSvg = document.getElementById("svg");
|
||||
const gRect = document.getElementById("rect");
|
||||
const gUnAnimatedCTM = gRect.getCTM();
|
||||
|
||||
// Values for path-defining attributes, and their expected
|
||||
// CTMs halfway through the animation
|
||||
var gMpathValidTarget = "#validPathElem";
|
||||
var gMpathCTM = CTMUtil.generateCTM([ 5, 10, 0 ]);
|
||||
|
||||
var gMpathInvalidTargetA = "#invalidPathElem";
|
||||
var gMpathInvalidTargetB = "#nonExistentElem";
|
||||
|
||||
var gInvalidAttrValue = "i-am-invalid"; // Invalid for all tested attributes
|
||||
|
||||
var gPathValidValue = "M20 20 h10";
|
||||
var gPathCTM = CTMUtil.generateCTM([ 25, 20, 0 ]);
|
||||
|
||||
var gValuesValidValue = "30 30; 40 30"
|
||||
var gValuesCTM = CTMUtil.generateCTM([ 35, 30, 0 ]);
|
||||
|
||||
var gFromValidValue = "50 50";
|
||||
|
||||
var gByValidValue = "10 2";
|
||||
var gPureByCTM = CTMUtil.generateCTM([ 5, 1, 0 ]);
|
||||
var gFromByCTM = CTMUtil.generateCTM([ 55, 51, 0 ]);
|
||||
|
||||
var gToValidValue = "80 60";
|
||||
var gPureToCTM = CTMUtil.generateCTM([ 40, 30, 0 ]);
|
||||
var gFromToCTM = CTMUtil.generateCTM([ 65, 55, 0 ]);
|
||||
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
function createAnim()
|
||||
{
|
||||
var anim = document.createElementNS(SVGNS, "animateMotion");
|
||||
return gRect.appendChild(anim);
|
||||
}
|
||||
|
||||
function removeElem(aElem)
|
||||
{
|
||||
aElem.parentNode.removeChild(aElem);
|
||||
}
|
||||
|
||||
function createMpath(aAnimElement, aHrefVal)
|
||||
{
|
||||
var mpath = document.createElementNS(SVGNS, "mpath");
|
||||
mpath.setAttributeNS(XLINKNS, "href", aHrefVal);
|
||||
return aAnimElement.appendChild(mpath);
|
||||
}
|
||||
|
||||
function runTest() {
|
||||
// Start out with valid values for all path-defining attributes
|
||||
var attrSettings = {
|
||||
"mpath" : gMpathValidTarget,
|
||||
"path" : gPathValidValue,
|
||||
"values" : gValuesValidValue,
|
||||
"from" : gFromValidValue,
|
||||
"to" : gToValidValue,
|
||||
"by" : gByValidValue,
|
||||
};
|
||||
|
||||
// Test that <mpath> overrides everything below it
|
||||
testAttrSettings(attrSettings, gMpathCTM,
|
||||
"<mpath> should win");
|
||||
var mpathInvalidTargets = [gMpathInvalidTargetA, gMpathInvalidTargetB];
|
||||
for (var i in mpathInvalidTargets) {
|
||||
var curInvalidValue = mpathInvalidTargets[i];
|
||||
attrSettings["mpath"] = curInvalidValue;
|
||||
testAttrSettings(attrSettings, gUnAnimatedCTM,
|
||||
"invalid <mpath> should block animation");
|
||||
}
|
||||
delete attrSettings["mpath"];
|
||||
|
||||
// Test that 'path' overrides everything below it
|
||||
testAttrSettings(attrSettings, gPathCTM,
|
||||
"'path' should win vs all but mpath");
|
||||
attrSettings["path"] = gInvalidAttrValue;
|
||||
testAttrSettings(attrSettings, gUnAnimatedCTM,
|
||||
"invalid 'path' should block animation vs all but mpath");
|
||||
delete attrSettings["path"];
|
||||
|
||||
// Test that 'values' overrides everything below it
|
||||
testAttrSettings(attrSettings, gValuesCTM,
|
||||
"'values' should win vs from/by/to");
|
||||
attrSettings["values"] = gInvalidAttrValue;
|
||||
testAttrSettings(attrSettings, gUnAnimatedCTM,
|
||||
"invalid 'values' should block animation vs from/by/to");
|
||||
delete attrSettings["values"];
|
||||
|
||||
// Test that 'from' & 'to' overrides 'by'
|
||||
testAttrSettings(attrSettings, gFromToCTM,
|
||||
"'from/to' should win vs 'by'");
|
||||
attrSettings["to"] = gInvalidAttrValue;
|
||||
testAttrSettings(attrSettings, gUnAnimatedCTM,
|
||||
"invalid 'to' should block animation vs 'by'");
|
||||
delete attrSettings["to"];
|
||||
|
||||
// Test that 'from' & 'by' are effective
|
||||
testAttrSettings(attrSettings, gFromByCTM,
|
||||
"'from/by' should be visible");
|
||||
attrSettings["by"] = gInvalidAttrValue;
|
||||
testAttrSettings(attrSettings, gUnAnimatedCTM,
|
||||
"invalid 'by' should block animation");
|
||||
delete attrSettings["from"];
|
||||
|
||||
// REINSERT "to" & fix up "by" so we can test pure-"to" vs pure-"by"
|
||||
attrSettings["to"] = gToValidValue;
|
||||
attrSettings["by"] = gByValidValue;
|
||||
testAttrSettings(attrSettings, gPureToCTM,
|
||||
"pure-'to' should be effective & beat pure-'by'");
|
||||
attrSettings["to"] = gInvalidAttrValue;
|
||||
testAttrSettings(attrSettings, gUnAnimatedCTM,
|
||||
"invalid pure-'to' should block animation vs pure-'by'");
|
||||
delete attrSettings["to"];
|
||||
|
||||
// Test that pure-"by" is effective
|
||||
testAttrSettings(attrSettings, gPureByCTM,
|
||||
"pure-by should be visible");
|
||||
attrSettings["by"] = gInvalidAttrValue;
|
||||
testAttrSettings(attrSettings, gUnAnimatedCTM,
|
||||
"invalid 'by' should block animation");
|
||||
delete attrSettings["by"];
|
||||
|
||||
// Make sure that our hash is empty now.
|
||||
for (var unexpectedKey in attrSettings) {
|
||||
ok(false, "Unexpected mapping remains in attrSettings: " +
|
||||
unexpectedKey + "-->" + unexpectedValue);
|
||||
}
|
||||
}
|
||||
|
||||
function testAttrSettings(aAttrValueHash, aExpectedCTM, aErrMsg)
|
||||
{
|
||||
var isDebug = false; // XXdholbert
|
||||
!isDebug || todo(false, "ENTERING testAttrSettings");
|
||||
// Set up animateMotion element
|
||||
var animElement = document.createElementNS(SVGNS, "animateMotion");
|
||||
animElement.setAttribute("dur", "2s");
|
||||
for (var attrName in aAttrValueHash) {
|
||||
!isDebug || todo(false, "setting '" + attrName +"' to '" +
|
||||
aAttrValueHash[attrName] +"'");
|
||||
if (attrName == "mpath") {
|
||||
createMpath(animElement, aAttrValueHash[attrName]);
|
||||
} else {
|
||||
animElement.setAttribute(attrName, aAttrValueHash[attrName]);
|
||||
}
|
||||
}
|
||||
|
||||
gRect.appendChild(animElement);
|
||||
|
||||
// Seek to halfway through animation
|
||||
SMILUtil.getSVGRoot().setCurrentTime(1); // Seek halfway through animation
|
||||
|
||||
// Check CTM against expected value
|
||||
CTMUtil.assertCTMEqual(gRect.getCTM(), aExpectedCTM,
|
||||
CTMUtil.CTM_COMPONENTS_ALL, aErrMsg, false);
|
||||
|
||||
// CLEAN UP
|
||||
SMILUtil.getSVGRoot().setCurrentTime(0);
|
||||
removeElem(animElement);
|
||||
}
|
||||
|
||||
// Main Function
|
||||
function main()
|
||||
{
|
||||
if (!SMILUtil.isSMILEnabled()) {
|
||||
ok(false, "SMIL dosn't seem to be enabled");
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
}
|
||||
|
||||
// Start out with document paused
|
||||
var svg = SMILUtil.getSVGRoot();
|
||||
ok(svg.animationsPaused(), "should be paused by <svg> load handler");
|
||||
is(svg.getCurrentTime(), 0, "should be paused at 0 in <svg> load handler");
|
||||
|
||||
runTest();
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
window.addEventListener("load", main, false);
|
||||
]]>
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,41 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
class="reftest-wait">
|
||||
<script xlink:href="../smil-util.js" type="text/javascript"/>
|
||||
<script type="text/javascript">
|
||||
function doTest() {
|
||||
setTimeAndSnapshot(1, true);
|
||||
}
|
||||
window.addEventListener("MozReftestInvalidate", doTest, false);
|
||||
</script>
|
||||
|
||||
<!-- Big green background to match lime.svg -->
|
||||
<rect width="100%" height="100%" fill="lime"/>
|
||||
<!-- Red "workspace" (should be covered up, if tests pass) -->
|
||||
<rect x="100" y="100" width="100" height="100" fill="red"/>
|
||||
|
||||
<!-- FIRST ROW -->
|
||||
<!-- Check that 'by' works at all -->
|
||||
<rect fill="lime" x="0" y="0" width="50" height="50">
|
||||
<animateMotion by="100, 100" begin="0" dur="1" fill="freeze"/>
|
||||
</rect>
|
||||
|
||||
<!-- Check that 'by' is additive w/ 'by' -->
|
||||
<rect fill="lime" x="50" y="50" width="50" height="50">
|
||||
<animateMotion by="60, 75" begin="0" dur="1" fill="freeze"/>
|
||||
<animateMotion by="40, -25" begin="0" dur="1" fill="freeze"/>
|
||||
</rect>
|
||||
|
||||
<!-- SECOND ROW -->
|
||||
<!-- Check that 'by' is additive w/ 'to' -->
|
||||
<rect fill="lime" width="50" height="50">
|
||||
<animateMotion to="50,100" begin="0" dur="1" fill="freeze"/>
|
||||
<animateMotion by="50, 50" begin="0" dur="1" fill="freeze"/>
|
||||
</rect>
|
||||
|
||||
<!-- Check that 'from-to' replaces 'by' -->
|
||||
<rect fill="lime" width="50" height="50">
|
||||
<animateMotion by="500, 500" begin="0" dur="1" fill="freeze"/>
|
||||
<animateMotion from="300,300" to="150,150" begin="0" dur="1" fill="freeze"/>
|
||||
</rect>
|
||||
</svg>
|
После Ширина: | Высота: | Размер: 1.5 KiB |
|
@ -0,0 +1,44 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
class="reftest-wait">
|
||||
<script xlink:href="../smil-util.js" type="text/javascript"/>
|
||||
<script type="text/javascript">
|
||||
function doTest() {
|
||||
setTimeAndSnapshot(1, true);
|
||||
}
|
||||
window.addEventListener("MozReftestInvalidate", doTest, false);
|
||||
</script>
|
||||
|
||||
<!-- Big green background to match lime.svg -->
|
||||
<rect width="100%" height="100%" fill="lime"/>
|
||||
<!-- Red "workspace" (should be covered up, if tests pass) -->
|
||||
<rect x="100" y="100" width="100" height="100" fill="red"/>
|
||||
|
||||
<!-- FIRST ROW -->
|
||||
<!-- Check that 'from' gets applied at begin time -->
|
||||
<rect fill="lime" x="0" y="0" width="50" height="50">
|
||||
<animateMotion from="100, 100" to="500, 500" begin="1" dur="1"/>
|
||||
</rect>
|
||||
|
||||
<!-- Check that 'to' gets hit at end time -->
|
||||
<rect fill="lime" x="0" y="0" width="50" height="50">
|
||||
<animateMotion from="200,200" to="150,100" begin="0" dur="1" fill="freeze"/>
|
||||
</rect>
|
||||
|
||||
<!-- SECOND ROW -->
|
||||
<!-- Check that animation effects are removed after end time
|
||||
(note that fill="remove" is default; just specifying it for clarity -->
|
||||
<rect fill="lime" x="100" y="150" width="50" height="50">
|
||||
<animateMotion from="500,500" to="600,600" begin="0" dur="1" fill="remove"/>
|
||||
</rect>
|
||||
<rect fill="purple" x="-25" y="-25" width="25" height="25">
|
||||
<!-- With the purple rect's x/y offsets, this animateMotion path moves us
|
||||
around the 2nd row, 1st col -->
|
||||
<animateMotion from="125,175" to="150,175" begin="0" dur="1" fill="remove"/>
|
||||
</rect>
|
||||
|
||||
<!-- Check interpolation halfway through animation -->
|
||||
<rect fill="lime" width="50" height="50">
|
||||
<animateMotion from="200,100" to="100,200" begin="0.5" dur="1"/>
|
||||
</rect>
|
||||
</svg>
|
После Ширина: | Высота: | Размер: 1.7 KiB |
|
@ -0,0 +1,151 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
class="reftest-wait">
|
||||
<style>
|
||||
.background { fill: lime }
|
||||
.workspace { fill: red }
|
||||
.test { fill: lime }
|
||||
</style>
|
||||
<defs>
|
||||
<!-- 'Dummy' path -->
|
||||
<path id="moveFarAway" d="M300,300 h0"/>
|
||||
|
||||
<path id="moveToUpperLeft" d="M100,100 h0"/>
|
||||
|
||||
<path id="pathWhoseDAttrChanges" d="M360,360 h0"/>
|
||||
|
||||
<!-- The first of these two elems w/ same ID should be used. -->
|
||||
<path id="moveToMiddleLeft" d="M100,150 h0"/>
|
||||
<path id="moveToMiddleLeft" d="M350,350 h0"/>
|
||||
|
||||
<!-- The first of these two elems w/ same ID initially wins, but then
|
||||
it gets removed via script. -->
|
||||
<path id="moveToMiddleCenter" d="M340,340 h0"/>
|
||||
<path id="moveToMiddleCenter" d="M150,150 h0"/>
|
||||
|
||||
<!-- This elem doesn't do what its id would suggest, but we'll use JS to
|
||||
add an earlier elem with the same ID that *does* do what it says. -->
|
||||
<path id="moveToMiddleRight" d="M330,330 h0"/>
|
||||
|
||||
<path id="moveToLowerLeft" d="M100,200 h0"/>
|
||||
<path id="moveToLowerCenter" d="M150,200 h0"/>
|
||||
|
||||
</defs>
|
||||
|
||||
<script xlink:href="../smil-util.js" type="text/javascript"/>
|
||||
<script type="text/javascript">
|
||||
const SVGNS = "http://www.w3.org/2000/svg";
|
||||
const XLINKNS = "http://www.w3.org/1999/xlink";
|
||||
|
||||
|
||||
function insertPathElem(aPathId, aPathSpec) {
|
||||
var newPath = document.createElementNS(SVGNS, "path");
|
||||
newPath.setAttribute("id", aPathId);
|
||||
newPath.setAttribute("d", aPathSpec);
|
||||
|
||||
// Insert new path into defs
|
||||
var defsElem = document.getElementsByTagName("defs")[0];
|
||||
defsElem.insertBefore(newPath, defsElem.firstChild);
|
||||
}
|
||||
|
||||
function doTest() {
|
||||
// Seek already, so we'll have sampled the initial 'stale' state
|
||||
document.documentElement.setCurrentTime(1);
|
||||
|
||||
// Make tweaks
|
||||
var mpathToModify = document.getElementById("modifyMyTarget");
|
||||
mpathToModify.setAttributeNS(XLINKNS, "href", "#moveToUpperLeft");
|
||||
|
||||
var mpathWhoseHrefNeedsClearing = document.getElementById("unsetMyTarget");
|
||||
mpathWhoseHrefNeedsClearing.removeAttributeNS(XLINKNS, "href");
|
||||
|
||||
var pathToTweak = document.getElementById("pathWhoseDAttrChanges");
|
||||
pathToTweak.setAttribute("d", "M200 100 h0");
|
||||
|
||||
var mpathToDelete = document.getElementById("removeMe");
|
||||
mpathToDelete.parentNode.removeChild(mpathToDelete);
|
||||
|
||||
var pathToDelete = document.getElementById("moveToMiddleCenter");
|
||||
pathToDelete.parentNode.removeChild(pathToDelete);
|
||||
|
||||
insertPathElem("moveToMiddleRight", "M200,150 h0");
|
||||
insertPathElem("moveToLowerRight", "M200,200 h0");
|
||||
|
||||
setTimeAndSnapshot(1, true);
|
||||
}
|
||||
window.addEventListener("MozReftestInvalidate", doTest, false);
|
||||
</script>
|
||||
|
||||
<!-- Big green background to match lime.svg -->
|
||||
<rect class="background" width="100%" height="100%" />
|
||||
<!-- Red "workspace" (should be covered up, if tests pass) -->
|
||||
<rect class="workspace" x="100" y="100" width="150" height="150"/>
|
||||
|
||||
<!-- FIRST ROW: Test behavior... -->
|
||||
<!-- ...when mpath's 'xlink:href' attr is modified. -->
|
||||
<rect class="test" x="0" y="0" width="50" height="50">
|
||||
<animateMotion begin="1" dur="1" fill="freeze">
|
||||
<mpath id="modifyMyTarget" xlink:href="#moveFarAway"/>
|
||||
</animateMotion>
|
||||
</rect>
|
||||
|
||||
<!-- ...when mpath's 'xlink:href' is unset. -->
|
||||
<rect class="test" x="150" y="100" width="50" height="50">
|
||||
<animateMotion begin="1" dur="1" fill="freeze">
|
||||
<mpath id="unsetMyTarget" xlink:href="#moveFarAway"/>
|
||||
</animateMotion>
|
||||
</rect>
|
||||
|
||||
<!-- ...when the target-path's "d" attr is modified. -->
|
||||
<rect class="test" x="0" y="0" width="50" height="50">
|
||||
<animateMotion begin="1" dur="1" fill="freeze">
|
||||
<mpath xlink:href="#pathWhoseDAttrChanges"/>
|
||||
</animateMotion>
|
||||
</rect>
|
||||
|
||||
<!-- SECOND ROW: Test behavior... -->
|
||||
<!-- ...when there are two paths with same ID (first should win) -->
|
||||
<rect class="test" x="0" y="0" width="50" height="50">
|
||||
<animateMotion begin="1" dur="1" fill="freeze">
|
||||
<mpath xlink:href="#moveToMiddleLeft"/>
|
||||
</animateMotion>
|
||||
</rect>
|
||||
|
||||
<!-- ...when there are two paths with same ID, and the first is removed. -->
|
||||
<rect class="test" x="0" y="0" width="50" height="50">
|
||||
<animateMotion begin="1" dur="1" fill="freeze">
|
||||
<mpath xlink:href="#moveToMiddleCenter"/>
|
||||
</animateMotion>
|
||||
</rect>
|
||||
|
||||
<!-- ...when an earlier path is added with our target ID. -->
|
||||
<rect class="test" x="0" y="0" width="50" height="50">
|
||||
<animateMotion begin="1" dur="1" fill="freeze">
|
||||
<mpath xlink:href="#moveToMiddleRight"/>
|
||||
</animateMotion>
|
||||
</rect>
|
||||
|
||||
<!-- THIRD ROW: Test behavior... -->
|
||||
<!-- ...when there are two mpath children (first should win). -->
|
||||
<rect class="test" x="0" y="0" width="50" height="50">
|
||||
<animateMotion begin="1" dur="1" fill="freeze">
|
||||
<mpath xlink:href="#moveToLowerLeft"/>
|
||||
<mpath xlink:href="#moveFarAway"/>
|
||||
</animateMotion>
|
||||
</rect>
|
||||
|
||||
<!-- ...when there are two mpath children, and the first is removed. -->
|
||||
<rect class="test" x="0" y="0" width="50" height="50">
|
||||
<animateMotion begin="1" dur="1" fill="freeze">
|
||||
<mpath id="removeMe" xlink:href="#moveFarAway"/>
|
||||
<mpath xlink:href="#moveToLowerCenter"/>
|
||||
</animateMotion>
|
||||
</rect>
|
||||
<!-- ...when there's an mpath child that initially matches nothing, until
|
||||
a node with the right ID is inserted into the DOM. -->
|
||||
<rect class="test" x="0" y="0" width="50" height="50">
|
||||
<animateMotion begin="1" dur="1" fill="freeze">
|
||||
<mpath xlink:href="#moveToLowerRight"/>
|
||||
</animateMotion>
|
||||
</rect>
|
||||
</svg>
|
После Ширина: | Высота: | Размер: 5.5 KiB |
|
@ -0,0 +1,63 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
class="reftest-wait">
|
||||
<style>
|
||||
.background { fill: lime }
|
||||
.workspace { fill: red }
|
||||
.test { fill: lime }
|
||||
.filler { fill: lime }
|
||||
</style>
|
||||
|
||||
<script xlink:href="../smil-util.js" type="text/javascript"/>
|
||||
<script type="text/javascript">
|
||||
function doTest() {
|
||||
setTimeAndSnapshot(1, true);
|
||||
}
|
||||
window.addEventListener("MozReftestInvalidate", doTest, false);
|
||||
</script>
|
||||
|
||||
<!-- Big green background to match lime.svg -->
|
||||
<rect class="background" width="100%" height="100%" />
|
||||
<!-- Red "workspace" (should be covered up, if tests pass) -->
|
||||
<rect class="workspace" x="100" y="100" width="100" height="100"/>
|
||||
|
||||
<!-- FIRST ROW -->
|
||||
<!-- Check that 'rotate' gets applied at begin time -->
|
||||
<g>
|
||||
<animateMotion from="150, 100" to="500, 500" rotate="90"
|
||||
begin="1" dur="1"/>
|
||||
<rect class="test" x="0" y="0" width="20" height="50"/>
|
||||
<rect class="test" x="0" y="0" width="50" height="20"/>
|
||||
</g>
|
||||
<rect class="filler" x="100" y="120" width="30" height="30"/>
|
||||
|
||||
<!-- Check that 'rotate' gets applied at end time -->
|
||||
<g>
|
||||
<animateMotion from="600, 700" to="200, 150" rotate="180" begin="0"
|
||||
dur="1" fill="freeze"/>
|
||||
<rect class="test" x="0" y="0" width="20" height="50"/>
|
||||
<rect class="test" x="0" y="0" width="50" height="20"/>
|
||||
</g>
|
||||
<rect class="filler" x="150" y="100" width="30" height="30"/>
|
||||
|
||||
<!-- SECOND ROW -->
|
||||
<!-- Check that rotate combines with existing rotate -->
|
||||
<g transform="rotate(90)">
|
||||
<animateMotion from="150,200" to="600,600" rotate="90"
|
||||
begin="1" dur="1"/>
|
||||
<rect class="test" x="0" y="0" width="20" height="50"/>
|
||||
<rect class="test" x="0" y="0" width="50" height="20"/>
|
||||
</g>
|
||||
<rect class="filler" x="100" y="150" width="30" height="30"/>
|
||||
|
||||
<!-- Check additivity of <animateMotion> "rotate" adds -->
|
||||
<g>
|
||||
<animateMotion from="100,100" to="100,200" rotate="90"
|
||||
begin="0.5" dur="1"/>
|
||||
<animateMotion by="100,-200" rotate="90"
|
||||
begin="0.5" dur="1"/>
|
||||
<rect class="test" x="0" y="0" width="20" height="50"/>
|
||||
<rect class="test" x="0" y="0" width="50" height="20"/>
|
||||
</g>
|
||||
<rect class="filler" x="150" y="150" width="30" height="30"/>
|
||||
</svg>
|
После Ширина: | Высота: | Размер: 2.3 KiB |
|
@ -0,0 +1,50 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
class="reftest-wait">
|
||||
<!-- Tests for rotate="auto" and "auto-reverse" -->
|
||||
<!-- The idea here is to create positioned red "holes" in the lime
|
||||
background, and then hopefully use paused <animateMotion> elements to
|
||||
position other elements exactly on top of the hole. -->
|
||||
<style>
|
||||
.background { fill: lime }
|
||||
.hole { color: red }
|
||||
.testBegin { color: purple }
|
||||
.testEnd { color: orange }
|
||||
.mask { color: lime }
|
||||
</style>
|
||||
<defs>
|
||||
<!-- A 'pin' marker, just offscreen, pointing directly down at 0,0 -->
|
||||
<!-- NOTE: The lime 2px-wide stroke is a hack to get around "seams" in
|
||||
SVG when redrawing the same non-pixel-aligned shape on top of itself
|
||||
in different colors. -->
|
||||
<path id="marker" d="m0,0 l-10,-30 c-5,-20 25,-20 20,0 z"
|
||||
style="fill: currentColor; stroke: lime; stroke-width: 2px"/>
|
||||
</defs>
|
||||
<script xlink:href="../smil-util.js" type="text/javascript"/>
|
||||
<script type="text/javascript">
|
||||
function doTest() {
|
||||
setTimeAndSnapshot(1, true);
|
||||
}
|
||||
window.addEventListener("MozReftestInvalidate", doTest, false);
|
||||
</script>
|
||||
|
||||
<!-- Big green background to match lime.svg -->
|
||||
<rect class="background" width="100%" height="100%" />
|
||||
<g transform="translate(50,50)">
|
||||
<!-- Here's the hole -->
|
||||
<use xlink:href="#marker" class="hole"
|
||||
transform="translate(20,20) rotate(45)"/>
|
||||
|
||||
<!-- And here's a stack of elements animated with 'animateMotion' that
|
||||
should end up there. -->
|
||||
<use xlink:href="#marker" class="testBegin">
|
||||
<animateMotion from="20,20" to="40,40" rotate="auto" begin="1s" dur="1s"/>
|
||||
</use>
|
||||
<use xlink:href="#marker" class="testEnd">
|
||||
<animateMotion by="20,20" rotate="auto" dur="1s" fill="freeze"/>
|
||||
</use>
|
||||
<use xlink:href="#marker" class="mask">
|
||||
<animateMotion by="40,40" rotate="auto" dur="2s"/>
|
||||
</use>
|
||||
</g>
|
||||
</svg>
|
После Ширина: | Высота: | Размер: 2.0 KiB |
|
@ -0,0 +1,38 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg">
|
||||
<!-- First row -->
|
||||
<g transform="translate(20,20)">
|
||||
<g>
|
||||
<rect width="15px" height="15px"/>
|
||||
</g>
|
||||
<g transform="translate(50,0)">
|
||||
<rect x="0" y="10" width="15px" height="15px"/>
|
||||
</g>
|
||||
<g transform="translate(100,0)">
|
||||
<rect x="9" y="10" width="15px" height="15px"/>
|
||||
</g>
|
||||
</g>
|
||||
<!-- Second row -->
|
||||
<g transform="translate(20,70)">
|
||||
<g>
|
||||
<rect x="22.5" y="10" width="15px" height="15px"/>
|
||||
</g>
|
||||
<g transform="translate(50,0)">
|
||||
<rect x="29.7" y="10" width="15px" height="15px"/>
|
||||
</g>
|
||||
<g transform="translate(100,0)">
|
||||
<rect x="45" y="30" width="15px" height="15px"/>
|
||||
</g>
|
||||
</g>
|
||||
<!-- Third row -->
|
||||
<g transform="translate(20,120)">
|
||||
<g>
|
||||
<rect x="48" y="34" width="15px" height="15px"/>
|
||||
</g>
|
||||
<g transform="translate(50,0)">
|
||||
<rect x="60" y="50" width="15px" height="15px"/>
|
||||
</g>
|
||||
<g transform="translate(100,0)">
|
||||
<rect x="60" y="50" width="15px" height="15px"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
После Ширина: | Высота: | Размер: 1.0 KiB |
|
@ -0,0 +1,15 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
class="reftest-wait"
|
||||
onload="go()">
|
||||
<!-- Tests for <animateMotion> with 'values' attribute -->
|
||||
<script xlink:href="../smil-grid.js" type="text/javascript"/>
|
||||
<script xlink:href="../smil-util.js" type="text/javascript"/>
|
||||
<script>
|
||||
function go() {
|
||||
var animAttrHash = { "values" : "0,10; 30,10; 60,50",
|
||||
"calcMode" : "linear" };
|
||||
testAnimatedRectGrid("animateMotion", [animAttrHash]);
|
||||
}
|
||||
</script>
|
||||
</svg>
|
После Ширина: | Высота: | Размер: 556 B |
|
@ -0,0 +1,38 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg">
|
||||
<!-- First row -->
|
||||
<g transform="translate(20,20)">
|
||||
<g>
|
||||
<rect width="15px" height="15px"/>
|
||||
</g>
|
||||
<g transform="translate(50,0)">
|
||||
<rect x="0" y="10" width="15px" height="15px"/>
|
||||
</g>
|
||||
<g transform="translate(100,0)">
|
||||
<rect x="12" y="10" width="15px" height="15px"/>
|
||||
</g>
|
||||
</g>
|
||||
<!-- Second row -->
|
||||
<g transform="translate(20,70)">
|
||||
<g>
|
||||
<rect x="30" y="10" width="15px" height="15px"/>
|
||||
</g>
|
||||
<g transform="translate(50,0)">
|
||||
<rect x="35.76" y="17.68" width="15px" height="15px"/>
|
||||
</g>
|
||||
<g transform="translate(100,0)">
|
||||
<rect x="48" y="34" width="15px" height="15px"/>
|
||||
</g>
|
||||
</g>
|
||||
<!-- Third row -->
|
||||
<g transform="translate(20,120)">
|
||||
<g>
|
||||
<rect x="50.4" y="37.2" width="15px" height="15px"/>
|
||||
</g>
|
||||
<g transform="translate(50,0)">
|
||||
<rect x="60" y="50" width="15px" height="15px"/>
|
||||
</g>
|
||||
<g transform="translate(100,0)">
|
||||
<rect x="60" y="50" width="15px" height="15px"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
После Ширина: | Высота: | Размер: 1.0 KiB |
|
@ -0,0 +1,14 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
class="reftest-wait"
|
||||
onload="go()">
|
||||
<!-- Tests for <animateMotion> with 'values' attribute -->
|
||||
<script xlink:href="../smil-grid.js" type="text/javascript"/>
|
||||
<script xlink:href="../smil-util.js" type="text/javascript"/>
|
||||
<script>
|
||||
function go() {
|
||||
var animAttrHash = { "values" : "0,10; 30,10; 60,50"};
|
||||
testAnimatedRectGrid("animateMotion", [animAttrHash]);
|
||||
}
|
||||
</script>
|
||||
</svg>
|
После Ширина: | Высота: | Размер: 504 B |
|
@ -0,0 +1,15 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
class="reftest-wait"
|
||||
onload="go()">
|
||||
<!-- Tests for <animateMotion> with 'values' attribute -->
|
||||
<script xlink:href="../smil-grid.js" type="text/javascript"/>
|
||||
<script xlink:href="../smil-util.js" type="text/javascript"/>
|
||||
<script>
|
||||
function go() {
|
||||
var animAttrHash = { "values" : "0,10; 30,10; 60,50",
|
||||
"calcMode" : "paced" };
|
||||
testAnimatedRectGrid("animateMotion", [animAttrHash]);
|
||||
}
|
||||
</script>
|
||||
</svg>
|
После Ширина: | Высота: | Размер: 555 B |
|
@ -0,0 +1,8 @@
|
|||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/licenses/publicdomain/
|
||||
-->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
|
||||
<title>Testcase reference file for generic pass condition</title>
|
||||
<rect width="100%" height="100%" fill="lime"/>
|
||||
</svg>
|
После Ширина: | Высота: | Размер: 297 B |
|
@ -0,0 +1,13 @@
|
|||
# Tests related to SVG Animation (using SMIL), focusing on the animateMotion
|
||||
# element.
|
||||
|
||||
== animateMotion-by-1.svg lime.svg
|
||||
== animateMotion-from-to-1.svg lime.svg
|
||||
== animateMotion-rotate-1.svg lime.svg
|
||||
== animateMotion-rotate-2.svg lime.svg
|
||||
== animateMotion-values-linear-1.svg animateMotion-values-linear-1-ref.svg
|
||||
== animateMotion-values-paced-1a.svg animateMotion-values-paced-1-ref.svg
|
||||
== animateMotion-values-paced-1b.svg animateMotion-values-paced-1-ref.svg
|
||||
|
||||
# Tests involving <mpath> sub-element
|
||||
== animateMotion-mpath-targetChange-1.svg lime.svg
|