200 lines
7.4 KiB
JavaScript
200 lines
7.4 KiB
JavaScript
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
|
/* vim: set ts=2 sw=2 sts=2 et: */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
/* Javascript library for dynamically generating a simple SVG/SMIL reftest
|
|
* with several copies of the same animation, each seeked to a different time.
|
|
*/
|
|
|
|
// Global variables
|
|
const START_TIMES = [ "4.0s", "3.0s", "2.7s",
|
|
"2.25s", "2.01s", "1.5s",
|
|
"1.4s", "1.0s", "0.5s" ];
|
|
|
|
const X_POSNS = [ "20px", "70px", "120px",
|
|
"20px", "70px", "120px",
|
|
"20px", "70px", "120px" ];
|
|
|
|
const Y_POSNS = [ "20px", "20px", "20px",
|
|
"70px", "70px", "70px",
|
|
"120px", "120px", "120px" ];
|
|
|
|
const DURATION = "2s";
|
|
const SNAPSHOT_TIME ="3";
|
|
const SVGNS = "http://www.w3.org/2000/svg";
|
|
|
|
// Convenience wrapper using testAnimatedGrid to make 15pt-by-15pt rects
|
|
function testAnimatedRectGrid(animationTagName, animationAttrHashList) {
|
|
var targetTagName = "rect";
|
|
var targetAttrHash = {"width" : "15px",
|
|
"height" : "15px" };
|
|
testAnimatedGrid(targetTagName, targetAttrHash,
|
|
animationTagName, animationAttrHashList);
|
|
}
|
|
|
|
// Convenience wrapper using testAnimatedGrid to make grid of text
|
|
function testAnimatedTextGrid(animationTagName, animationAttrHashList) {
|
|
var targetTagName = "text";
|
|
var targetAttrHash = { };
|
|
testAnimatedGrid(targetTagName, targetAttrHash,
|
|
animationTagName, animationAttrHashList);
|
|
}
|
|
|
|
// Generates a visual grid of elements of type "targetTagName", with the
|
|
// attribute values given in targetAttrHash. Each generated element has
|
|
// exactly one child -- an animation element of type "animationTagName", with
|
|
// the attribute values given in animationAttrHash.
|
|
function testAnimatedGrid(targetTagName, targetAttrHash,
|
|
animationTagName, animationAttrHashList) {
|
|
// SANITY CHECK
|
|
const numElementsToMake = START_TIMES.length;
|
|
if (X_POSNS.length != numElementsToMake ||
|
|
Y_POSNS.length != numElementsToMake) {
|
|
return;
|
|
}
|
|
|
|
for (var i = 0; i < animationAttrHashList.length; i++) {
|
|
var animationAttrHash = animationAttrHashList[i];
|
|
// Default to fill="freeze" so we can test the final value of the animation
|
|
if (!animationAttrHash["fill"]) {
|
|
animationAttrHash["fill"] = "freeze";
|
|
}
|
|
}
|
|
|
|
// Build the grid!
|
|
var svg = document.documentElement;
|
|
for (var i = 0; i < numElementsToMake; i++) {
|
|
// Build target & animation elements
|
|
var targetElem = buildElement(targetTagName, targetAttrHash);
|
|
for (var j = 0; j < animationAttrHashList.length; j++) {
|
|
var animationAttrHash = animationAttrHashList[j];
|
|
var animElem = buildElement(animationTagName, animationAttrHash);
|
|
|
|
// Customize them using global constant values
|
|
targetElem.setAttribute("x", X_POSNS[i]);
|
|
targetElem.setAttribute("y", Y_POSNS[i]);
|
|
animElem.setAttribute("begin", START_TIMES[i]);
|
|
animElem.setAttribute("dur", DURATION);
|
|
|
|
// Append to target
|
|
targetElem.appendChild(animElem);
|
|
}
|
|
// Insert target into DOM
|
|
svg.appendChild(targetElem);
|
|
}
|
|
|
|
// Take snapshot
|
|
setTimeAndSnapshot(SNAPSHOT_TIME, true);
|
|
}
|
|
|
|
// Generates a visual grid of elements of type |graphicElemTagName|, with the
|
|
// attribute values given in |graphicElemAttrHash|. This is a variation of the
|
|
// above function. We use <defs> to include the reference elements because
|
|
// some animatable properties are only applicable to some specific elements
|
|
// (e.g. feFlood, stop), so then we apply an animation element of type
|
|
// |animationTagName|, with the attribute values given in |animationAttrHash|,
|
|
// to those specific elements. |defTagNameList| is an array of tag names.
|
|
// We will create elements hierarchically according to this array. The first tag
|
|
// in |defTagNameList| is the outer-most one in <defs>, and the last tag is the
|
|
// inner-most one and it is the target to which the animation element will be
|
|
// applied. We visualize the effect of our animation by referencing each
|
|
// animated subtree from some graphical element that we generate. The
|
|
// |graphicElemIdValueProperty| parameter provides the name of the CSS property
|
|
// that we should use to hook up this reference.
|
|
//
|
|
// e.g. if a caller passes a defTagNameList of [ "linearGradient", "stop" ],
|
|
// this function will generate the following subtree:
|
|
// <defs>
|
|
// <linearGradient id="elem0">
|
|
// <stop>
|
|
// <animate ..../>
|
|
// </stop>
|
|
// </linearGradient>
|
|
// <linearGradient id="elem1">
|
|
// <stop>
|
|
// <animate ..../>
|
|
// </stop>
|
|
// </linearGradient>
|
|
//
|
|
// <!--- more similar linearGradients here, up to START_TIMES.length -->
|
|
// </defs>
|
|
function testAnimatedGridWithDefs(graphicElemTagName,
|
|
graphicElemAttrHash,
|
|
graphicElemIdValuedProperty,
|
|
defTagNameList,
|
|
animationTagName,
|
|
animationAttrHashList) {
|
|
// SANITY CHECK
|
|
const numElementsToMake = START_TIMES.length;
|
|
if (X_POSNS.length != numElementsToMake ||
|
|
Y_POSNS.length != numElementsToMake) {
|
|
return;
|
|
}
|
|
|
|
if (defTagNameList.length == 0) {
|
|
return;
|
|
}
|
|
|
|
for (var i = 0; i < animationAttrHashList.length; i++) {
|
|
var animationAttrHash = animationAttrHashList[i];
|
|
// Default to fill="freeze" so we can test the final value of the animation
|
|
if (!animationAttrHash["fill"]) {
|
|
animationAttrHash["fill"] = "freeze";
|
|
}
|
|
}
|
|
|
|
var svg = document.documentElement;
|
|
|
|
// Build defs element.
|
|
var defs = buildElement('defs');
|
|
for (var i = 0; i < numElementsToMake; i++) {
|
|
// This will track the innermost element in our subtree:
|
|
var innerElement = defs;
|
|
|
|
for (var defIdx = 0; defIdx < defTagNameList.length; ++defIdx) {
|
|
// Set an ID on the first level of nesting (on child of defs):
|
|
var attrs = defIdx == 0 ? { "id": "elem" + i } : {};
|
|
|
|
var newElem = buildElement(defTagNameList[defIdx], attrs);
|
|
innerElement.appendChild(newElem);
|
|
innerElement = newElem;
|
|
}
|
|
|
|
for (var j = 0; j < animationAttrHashList.length; ++j) {
|
|
var animationAttrHash = animationAttrHashList[j];
|
|
var animElem = buildElement(animationTagName, animationAttrHash);
|
|
animElem.setAttribute("begin", START_TIMES[i]);
|
|
animElem.setAttribute("dur", DURATION);
|
|
innerElement.appendChild(animElem);
|
|
}
|
|
}
|
|
svg.appendChild(defs);
|
|
|
|
// Build the grid!
|
|
for (var i = 0; i < numElementsToMake; ++i) {
|
|
var graphicElem = buildElement(graphicElemTagName, graphicElemAttrHash);
|
|
graphicElem.setAttribute("x", X_POSNS[i]);
|
|
graphicElem.setAttribute("y", Y_POSNS[i]);
|
|
graphicElem.setAttribute("style", graphicElemIdValuedProperty +
|
|
":url(#elem" + i + ")");
|
|
svg.appendChild(graphicElem);
|
|
}
|
|
|
|
// Take snapshot
|
|
setTimeAndSnapshot(SNAPSHOT_TIME, true);
|
|
}
|
|
|
|
function buildElement(tagName, attrHash) {
|
|
var elem = document.createElementNS(SVGNS, tagName);
|
|
for (var attrName in attrHash) {
|
|
var attrValue = attrHash[attrName];
|
|
elem.setAttribute(attrName, attrValue);
|
|
}
|
|
// If we're creating a text node, populate it with some text.
|
|
if (tagName == "text") {
|
|
elem.appendChild(document.createTextNode("abc"));
|
|
}
|
|
return elem;
|
|
}
|