Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / third_party / WebKit / LayoutTests / svg / carto.net / resources / slider.js
blobce3d83f0dbd0d210d976064f0041e55222ee1be0
1 /*
2 Scripts to create interactive sliders in SVG using ECMA script
3 Copyright (C) <2006> <Andreas Neumann>
4 Version 1.0, 2006-08-04
5 neumann@karto.baug.ethz.ch
6 http://www.carto.net/
7 http://www.carto.net/neumann/
9 Credits:
10 * Kevin Lindsey for ideas how to implement such a slider
12 ----
14 Documentation: http://www.carto.net/papers/svg/gui/slider/
16 ----
18 current version: 1.0.
20 version history:
21 0.99 (not documented, somewhere around 2001)
23 1.0 (2006-08-04)
24 changed constructor parameters (added id, parentNode), removed parameter sliderGroupId, added documentation, added method .moveTo()
26 -------
28 This ECMA script library is free software; you can redistribute it and/or
29 modify it under the terms of the GNU Lesser General Public
30 License as published by the Free Software Foundation; either
31 version 2.1 of the License, or (at your option) any later version.
33 This library is distributed in the hope that it will be useful,
34 but WITHOUT ANY WARRANTY; without even the implied warranty of
35 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
36 Lesser General Public License for more details.
38 You should have received a copy of the GNU Lesser General Public
39 License along with this library (lesser_gpl.txt); if not, write to the Free Software
40 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
42 ----
44 original document site: http://www.carto.net/papers/svg/gui/slider/
45 Please contact the author in case you want to use code or ideas commercially.
46 If you use this code, please include this copyright header, the included full
47 LGPL 2.1 text and read the terms provided in the LGPL 2.1 license
48 (http://www.gnu.org/copyleft/lesser.txt)
50 -------------------------------
52 Please report bugs and send improvements to neumann@karto.baug.ethz.ch
53 If you use this control, please link to the original (http://www.carto.net/papers/svg/gui/slider/)
54 somewhere in the source-code-comment or the "about" of your project and give credits, thanks!
58 //slider properties
59 function slider(id,parentNode,x1,y1,value1,x2,y2,value2,startVal,sliderStyles,invisSliderWidth,sliderSymb,functionToCall,mouseMoveBool) {
60 var nrArguments = 14;
61 var createSlider= true;
62 if (arguments.length == nrArguments) {
63 this.id = id; //an internal id, this id is not used in the SVG Dom tree
64 this.parentNode = parentNode; //the parentNode, string or nodeReference
65 this.x1 = x1; //the start point x of the slider
66 this.y1 = y1; //the start point y of the slider
67 this.value1 = value1; //the value at the start point, min slider value
68 this.x2 = x2; //the end point x of the slider
69 this.y2 = y2; //the end point y of the slider
70 this.value2 = value2; //the value at the end point, max slider value
71 this.startVal = startVal; //the initial value of the slider
72 this.value = startVal; //the current value of the slider
73 this.sliderStyles = sliderStyles; //the color of the slider line
74 this.invisSliderWidth = invisSliderWidth; //the width of invisible part of the slider
75 this.sliderSymb = sliderSymb; //the id for the movable symbol to be placed on the slider line
76 this.functionToCall = functionToCall; //the callback function
77 this.mouseMoveBool = mouseMoveBool; //boolean value to indicate if the slider gives immediate feedback or not
78 this.length = toPolarDist((this.x2 - this.x1),(this.y2 - this.y1));
79 this.direction = toPolarDir((this.x2 - this.x1),(this.y2 - this.y1));
80 this.invisSliderLine = null;
81 this.slideStatus = 0;
83 else {
84 createSlider = false;
85 alert("Error in slider ("+id+") constructor: wrong nr of arguments! You have to pass over "+nrArguments+" parameters.");
87 if (createSlider) {
88 this.createSlider();
90 else {
91 alert("Could not create slider with id '"+id+"' due to errors in the constructor parameters");
95 //create slider
96 slider.prototype.createSlider = function() {
97 var result = this.testParent();
98 if (result) {
99 this.invisSliderLine = document.createElementNS(svgNS,"line");
100 this.invisSliderLine.setAttributeNS(null,"x1",this.x1);
101 this.invisSliderLine.setAttributeNS(null,"y1",this.y1);
102 this.invisSliderLine.setAttributeNS(null,"x2",this.x2);
103 this.invisSliderLine.setAttributeNS(null,"y2",this.y2);
104 this.invisSliderLine.setAttributeNS(null,"stroke","black");
105 this.invisSliderLine.setAttributeNS(null,"stroke-width",this.invisSliderWidth);
106 //note that due to bugs in Opera9 and Firefox I can't use pointer-events here
107 this.invisSliderLine.setAttributeNS(null,"stroke-opacity","0");
108 this.invisSliderLine.setAttributeNS(null,"fill-opacity","0");
109 this.invisSliderLine.setAttributeNS(null,"stroke-linecap","square");
110 this.invisSliderLine.addEventListener("mousedown",this,false);
111 this.parentGroup.appendChild(this.invisSliderLine);
112 this.visSliderLine = document.createElementNS(svgNS,"line");
113 this.visSliderLine.setAttributeNS(null,"x1",this.x1);
114 this.visSliderLine.setAttributeNS(null,"y1",this.y1);
115 this.visSliderLine.setAttributeNS(null,"x2",this.x2);
116 this.visSliderLine.setAttributeNS(null,"y2",this.y2);
117 for (var attrib in this.sliderStyles) {
118 this.visSliderLine.setAttributeNS(null,attrib,this.sliderStyles[attrib]);
120 this.visSliderLine.setAttributeNS(null,"pointer-events","none");
121 this.parentGroup.appendChild(this.visSliderLine);
122 this.sliderSymbol = document.createElementNS(svgNS,"use");
123 this.sliderSymbol.setAttributeNS(xlinkNS,"xlink:href","#"+this.sliderSymb);
124 var myStartDistance = this.length - ((this.value2 - this.startVal) / (this.value2 - this.value1)) * this.length;
125 var myPosX = this.x1 + toRectX(this.direction,myStartDistance);
126 var myPosY = this.y1 + toRectY(this.direction,myStartDistance);
127 var myTransformString = "translate("+myPosX+","+myPosY+") rotate(" + Math.round(this.direction / Math.PI * 180) + ")";
128 this.sliderSymbol.setAttributeNS(null,"transform",myTransformString);
129 this.sliderSymbol.setAttributeNS(null,"pointer-events","none");
130 this.parentGroup.appendChild(this.sliderSymbol);
132 else {
133 alert("could not create or reference 'parentNode' of slider with id '"+this.id+"'");
137 //test if parent group exists
138 slider.prototype.testParent = function() {
139 //test if of type object
140 var nodeValid = false;
141 if (typeof(this.parentNode) == "object") {
142 if (this.parentNode.nodeName == "svg" || this.parentNode.nodeName == "g" || this.parentNode.nodeName == "svg:svg" || this.parentNode.nodeName == "svg:g") {
143 this.parentGroup = this.parentNode;
144 nodeValid = true;
147 else if (typeof(this.parentNode) == "string") {
148 //first test if button group exists
149 if (!document.getElementById(this.parentNode)) {
150 this.parentGroup = document.createElementNS(svgNS,"g");
151 this.parentGroup.setAttributeNS(null,"id",this.parentNode);
152 document.documentElement.appendChild(this.parentGroup);
153 nodeValid = true;
155 else {
156 this.parentGroup = document.getElementById(this.parentNode);
157 nodeValid = true;
160 return nodeValid;
163 //remove all slider elements
164 slider.prototype.removeSlider = function() {
165 this.parentGroup.removeChild(this.sliderSymbol);
166 this.parentGroup.removeChild(this.visSliderLine);
167 this.parentGroup.removeChild(this.invisSliderLine);
170 //handle events
171 slider.prototype.handleEvent = function(evt) {
172 this.drag(evt);
175 //drag slider
176 slider.prototype.drag = function(evt) {
177 if (evt.type == "mousedown" || (evt.type == "mousemove" && this.slideStatus == 1)) {
178 //get coordinate in slider coordinate system
179 var coordPoint = myMapApp.calcCoord(evt,this.invisSliderLine);
180 //draw normal line for first vertex
181 var ax = this.x2 - this.x1;
182 var ay = this.y2 - this.y1;
183 //normal vector 1
184 var px1 = parseFloat(this.x1) + ay * -1;
185 var py1 = parseFloat(this.y1) + ax;
186 //normal vector 2
187 var px2 = parseFloat(this.x2) + ay * -1;
188 var py2 = parseFloat(this.y2) + ax;
190 if (leftOfTest(coordPoint.x,coordPoint.y,this.x1,this.y1,px1,py1) == 0 && leftOfTest(coordPoint.x,coordPoint.y,this.x2,this.y2,px2,py2) == 1) {
191 if (evt.type == "mousedown" && (evt.detail == 1 || evt.detail == 0)) {
192 this.slideStatus = 1;
193 document.documentElement.addEventListener("mousemove",this,false);
194 document.documentElement.addEventListener("mouseup",this,false);
196 myNewPos = intersect2lines(this.x1,this.y1,this.x2,this.y2,coordPoint.x,coordPoint.y,coordPoint.x + ay * -1,coordPoint.y + ax);
197 var myPercentage = toPolarDist(myNewPos['x'] - this.x1,myNewPos['y'] - this.y1) / this.length;
198 this.value = this.value1 + myPercentage * (this.value2 - this.value1);
200 else {
201 var myNewPos = new Array();
202 if (leftOfTest(coordPoint.x,coordPoint.y,this.x1,this.y1,px1,py1) == 0 && leftOfTest(coordPoint.x,coordPoint.y,this.x2,this.y2,px2,py2) == 0) {
203 //more than max
204 this.value = this.value2;
205 myNewPos['x'] = this.x2;
206 myNewPos['y'] = this.y2;
208 if (leftOfTest(coordPoint.x,coordPoint.y,this.x1,this.y1,px1,py1) == 1 && leftOfTest(coordPoint.x,coordPoint.y,this.x2,this.y2,px2,py2) == 1) {
209 //less than min
210 this.value = this.value1;
211 myNewPos['x'] = this.x1;
212 myNewPos['y'] = this.y1;
215 var myTransformString = "translate("+myNewPos['x']+","+myNewPos['y']+") rotate(" + Math.round(this.direction / Math.PI * 180) + ")";
216 this.sliderSymbol.setAttributeNS(null,"transform",myTransformString);
217 this.fireFunction();
219 if (evt.type == "mouseup" && (evt.detail == 1 || evt.detail == 0)) {
220 if (this.slideStatus == 1) {
221 this.slideStatus = 2;
222 document.documentElement.removeEventListener("mousemove",this,false);
223 document.documentElement.removeEventListener("mouseup",this,false);
224 this.fireFunction();
226 this.slideStatus = 0;
230 //this code is executed, after the slider is released
231 //you can use switch/if to detect which slider was used (use this.id) for that
232 slider.prototype.fireFunction = function() {
233 if (this.slideStatus == 1 && this.mouseMoveBool == true) {
234 if (typeof(this.functionToCall) == "function") {
235 this.functionToCall("change",this.id,this.value);
237 if (typeof(this.functionToCall) == "object") {
238 this.functionToCall.getSliderVal("change",this.id,this.value);
240 if (typeof(this.functionToCall) == undefined) {
241 return;
244 if (this.slideStatus == 2) {
245 if (typeof(this.functionToCall) == "function") {
246 this.functionToCall("release",this.id,this.value);
248 if (typeof(this.functionToCall) == "object") {
249 this.functionToCall.getSliderVal("release",this.id,this.value);
251 if (typeof(this.functionToCall) == undefined) {
252 return;
257 slider.prototype.getValue = function() {
258 return this.value;
261 //this is to set the value from other scripts
262 slider.prototype.setValue = function(value,fireFunction) {
263 this.value = value;
264 var myPercAlLine = (this.value - this.value1) / (this.value2 - this.value1);
265 var myPosX = this.x1 + toRectX(this.direction,this.length * myPercAlLine);
266 var myPosY = this.y1 + toRectY(this.direction,this.length * myPercAlLine);
267 var myTransformString = "translate("+myPosX+","+myPosY+") rotate(" + Math.round(this.direction / Math.PI * 180) + ")";
268 this.sliderSymbol.setAttributeNS(null,"transform",myTransformString);
269 if (fireFunction) {
270 //temporary set slideStatus
271 this.slideStatus = 2;
272 this.fireFunction();
273 this.slideStatus = 0;
277 slider.prototype.moveTo = function(x1,y1,x2,y2) {
278 this.x1 = x1;
279 this.y1 = y1;
280 this.x2 = x2;
281 this.y2 = y2;
282 this.invisSliderLine.setAttributeNS(null,"x1",this.x1);
283 this.invisSliderLine.setAttributeNS(null,"y1",this.y1);
284 this.invisSliderLine.setAttributeNS(null,"x2",this.x2);
285 this.invisSliderLine.setAttributeNS(null,"y2",this.y2);
286 this.visSliderLine.setAttributeNS(null,"x1",this.x1);
287 this.visSliderLine.setAttributeNS(null,"y1",this.y1);
288 this.visSliderLine.setAttributeNS(null,"x2",this.x2);
289 this.visSliderLine.setAttributeNS(null,"y2",this.y2);
290 //reset direction and length of the slider
291 this.length = toPolarDist((this.x2 - this.x1),(this.y2 - this.y1));
292 this.direction = toPolarDir((this.x2 - this.x1),(this.y2 - this.y1));
293 //reset the value to correctly reposition element
294 this.setValue(this.getValue(),false);