source: other-projects/nz-flag-design/trunk/design-2d/Original editor.method.ac/method-draw/lib/jgraduate/jquery.jgraduate.js@ 29468

Last change on this file since 29468 was 29468, checked in by sjs49, 9 years ago

Initial commit for editor.method.ac for flag design

  • Property svn:executable set to *
File size: 36.4 KB
Line 
1/*
2 * jGraduate 0.4
3 *
4 * jQuery Plugin for a gradient picker
5 *
6 * Copyright (c) 2010 Jeff Schiller
7 * http://blog.codedread.com/
8 * Copyright (c) 2010 Alexis Deveria
9 * http://a.deveria.com/
10 *
11 * Apache 2 License
12
13jGraduate( options, okCallback, cancelCallback )
14
15where options is an object literal:
16 {
17 window: { title: "Pick the start color and opacity for the gradient" },
18 images: { clientPath: "images/" },
19 paint: a Paint object,
20 newstop: String of value "same", "inverse", "black" or "white"
21 OR object with one or both values {color: #Hex color, opac: number 0-1}
22 }
23
24- the Paint object is:
25 Paint {
26 type: String, // one of "none", "solidColor", "linearGradient", "radialGradient"
27 alpha: Number representing opacity (0-100),
28 solidColor: String representing #RRGGBB hex of color,
29 linearGradient: object of interface SVGLinearGradientElement,
30 radialGradient: object of interface SVGRadialGradientElement,
31 }
32
33$.jGraduate.Paint() -> constructs a 'none' color
34$.jGraduate.Paint({copy: o}) -> creates a copy of the paint o
35$.jGraduate.Paint({hex: "#rrggbb"}) -> creates a solid color paint with hex = "#rrggbb"
36$.jGraduate.Paint({linearGradient: o, a: 50}) -> creates a linear gradient paint with opacity=0.5
37$.jGraduate.Paint({radialGradient: o, a: 7}) -> creates a radial gradient paint with opacity=0.07
38$.jGraduate.Paint({hex: "#rrggbb", linearGradient: o}) -> throws an exception?
39
40- picker accepts the following object as input:
41 {
42 okCallback: function to call when Ok is pressed
43 cancelCallback: function to call when Cancel is pressed
44 paint: object describing the paint to display initially, if not set, then default to opaque white
45 }
46
47- okCallback receives a Paint object
48
49 *
50 */
51
52(function() {
53
54var ns = { svg: 'http://www.w3.org/2000/svg', xlink: 'http://www.w3.org/1999/xlink' };
55if(!window.console) {
56 window.console = new function() {
57 this.log = function(str) {};
58 this.dir = function(str) {};
59 };
60}
61
62$.jGraduate = {
63 Paint:
64 function(opt) {
65 var options = opt || {};
66 this.alpha = isNaN(options.alpha) ? 100 : options.alpha;
67 // copy paint object
68 if (options.copy) {
69 this.type = options.copy.type;
70 this.alpha = options.copy.alpha;
71 this.solidColor = null;
72 this.linearGradient = null;
73 this.radialGradient = null;
74
75 switch(this.type) {
76 case "none":
77 break;
78 case "solidColor":
79 this.solidColor = options.copy.solidColor;
80 break;
81 case "linearGradient":
82 this.linearGradient = options.copy.linearGradient.cloneNode(true);
83 break;
84 case "radialGradient":
85 this.radialGradient = options.copy.radialGradient.cloneNode(true);
86 break;
87 }
88 }
89 // create linear gradient paint
90 else if (options.linearGradient) {
91 this.type = "linearGradient";
92 this.solidColor = null;
93 this.radialGradient = null;
94 this.linearGradient = options.linearGradient.cloneNode(true);
95 }
96 // create linear gradient paint
97 else if (options.radialGradient) {
98 this.type = "radialGradient";
99 this.solidColor = null;
100 this.linearGradient = null;
101 this.radialGradient = options.radialGradient.cloneNode(true);
102 }
103 // create solid color paint
104 else if (options.solidColor) {
105 this.type = "solidColor";
106 this.solidColor = options.solidColor;
107 }
108 // create empty paint
109 else {
110 this.type = "none";
111 this.solidColor = null;
112 this.linearGradient = null;
113 this.radialGradient = null;
114 }
115 }
116};
117
118jQuery.fn.jGraduateDefaults = {
119 paint: new $.jGraduate.Paint(),
120 window: {
121 pickerTitle: "Drag markers to pick a paint"
122 },
123 images: {
124 clientPath: "images/"
125 },
126 newstop: 'inverse' // same, inverse, black, white
127};
128
129var isGecko = navigator.userAgent.indexOf('Gecko/') >= 0;
130
131function setAttrs(elem, attrs) {
132 if(isGecko) {
133 for (var aname in attrs) elem.setAttribute(aname, attrs[aname]);
134 } else {
135 for (var aname in attrs) {
136 var val = attrs[aname], prop = elem[aname];
137 if(prop && prop.constructor === 'SVGLength') {
138 prop.baseVal.value = val;
139 } else {
140 elem.setAttribute(aname, val);
141 }
142 }
143 }
144}
145
146function mkElem(name, attrs, newparent) {
147 var elem = document.createElementNS(ns.svg, name);
148 setAttrs(elem, attrs);
149 if(newparent) newparent.appendChild(elem);
150 return elem;
151}
152
153jQuery.fn.jGraduate =
154 function(options) {
155 var $arguments = arguments;
156 return this.each( function() {
157 var $this = $(this), $settings = $.extend(true, {}, jQuery.fn.jGraduateDefaults, options),
158 id = $this.attr('id'),
159 idref = '#'+$this.attr('id')+' ';
160
161 if (!idref)
162 {
163 alert('Container element must have an id attribute to maintain unique id strings for sub-elements.');
164 return;
165 }
166
167 var okClicked = function() {
168 switch ( $this.paint.type ) {
169 case "radialGradient":
170 $this.paint.linearGradient = null;
171 break;
172 case "linearGradient":
173 $this.paint.radialGradient = null;
174 break;
175 case "solidColor":
176 $this.paint.radialGradient = $this.paint.linearGradient = null;
177 break;
178 }
179 $.isFunction($this.okCallback) && $this.okCallback($this.paint);
180 $this.hide();
181 },
182 cancelClicked = function() {
183 $.isFunction($this.cancelCallback) && $this.cancelCallback();
184 $this.hide();
185 };
186
187 $.extend(true, $this, // public properties, methods, and callbacks
188 {
189 // make a copy of the incoming paint
190 paint: new $.jGraduate.Paint({copy: $settings.paint}),
191 okCallback: $.isFunction($arguments[1]) && $arguments[1] || null,
192 cancelCallback: $.isFunction($arguments[2]) && $arguments[2] || null
193 });
194
195 var pos = $this.position(),
196 color = null;
197 var $win = $(window);
198
199 if ($this.paint.type == "none") {
200 $this.paint = $.jGraduate.Paint({solidColor: 'ffffff'});
201 }
202
203 $this.addClass('jGraduate_Picker');
204 $this.html('<ul class="jGraduate_tabs">' +
205 '<li class="jGraduate_tab_color jGraduate_tab_current" data-type="col">Solid Color</li>' +
206 '<li class="jGraduate_tab_lingrad" data-type="lg">Linear Gradient</li>' +
207 '<li class="jGraduate_tab_radgrad" data-type="rg">Radial Gradient</li>' +
208 '</ul>' +
209 '<div class="jGraduate_colPick"></div>' +
210 '<div class="jGraduate_gradPick"></div>' +
211 '<div class="jGraduate_LightBox"></div>' +
212 '<div id="' + id + '_jGraduate_stopPicker" class="jGraduate_stopPicker"></div>'
213
214
215 );
216 var colPicker = $(idref + '> .jGraduate_colPick');
217 var gradPicker = $(idref + '> .jGraduate_gradPick');
218
219 gradPicker.html(
220 '<div id="' + id + '_jGraduate_Swatch" class="jGraduate_Swatch">' +
221 '<h2 class="jGraduate_Title">' + $settings.window.pickerTitle + '</h2>' +
222 '<div id="' + id + '_jGraduate_GradContainer" class="jGraduate_GradContainer"></div>' +
223 '<div id="' + id + '_jGraduate_StopSlider" class="jGraduate_StopSlider"></div>' +
224 '</div>' +
225 '<div class="jGraduate_Form jGraduate_Points jGraduate_lg_field">' +
226 '<div class="jGraduate_StopSection">' +
227 '<label class="jGraduate_Form_Heading">Begin Point</label>' +
228 '<div class="jGraduate_Form_Section">' +
229 '<label>x:</label>' +
230 '<input type="text" id="' + id + '_jGraduate_x1" size="3" title="Enter starting x value between 0.0 and 1.0"/>' +
231 '<label> y:</label>' +
232 '<input type="text" id="' + id + '_jGraduate_y1" size="3" title="Enter starting y value between 0.0 and 1.0"/>' +
233 '</div>' +
234 '</div>' +
235 '<div class="jGraduate_StopSection">' +
236 '<label class="jGraduate_Form_Heading">End Point</label>' +
237 '<div class="jGraduate_Form_Section">' +
238 '<label>x:</label>' +
239 '<input type="text" id="' + id + '_jGraduate_x2" size="3" title="Enter ending x value between 0.0 and 1.0"/>' +
240 '<label> y:</label>' +
241 '<input type="text" id="' + id + '_jGraduate_y2" size="3" title="Enter ending y value between 0.0 and 1.0"/>' +
242 '</div>' +
243 '</div>' +
244 '</div>' +
245 '<div class="jGraduate_Form jGraduate_Points jGraduate_rg_field">' +
246 '<div class="jGraduate_StopSection">' +
247 '<label class="jGraduate_Form_Heading">Center Point</label>' +
248 '<div class="jGraduate_Form_Section">' +
249 '<label>x:</label>' +
250 '<input type="text" id="' + id + '_jGraduate_cx" size="3" title="Enter x value between 0.0 and 1.0"/>' +
251 '<label> y:</label>' +
252 '<input type="text" id="' + id + '_jGraduate_cy" size="3" title="Enter y value between 0.0 and 1.0"/>' +
253 '</div>' +
254 '</div>' +
255 '<div class="jGraduate_StopSection">' +
256 '<label class="jGraduate_Form_Heading">Focal Point</label>' +
257 '<div class="jGraduate_Form_Section">' +
258 '<label>Match center: <input type="checkbox" checked="checked" id="' + id + '_jGraduate_match_ctr"/></label><br/>' +
259 '<label>x:</label>' +
260 '<input type="text" id="' + id + '_jGraduate_fx" size="3" title="Enter x value between 0.0 and 1.0"/>' +
261 '<label> y:</label>' +
262 '<input type="text" id="' + id + '_jGraduate_fy" size="3" title="Enter y value between 0.0 and 1.0"/>' +
263 '</div>' +
264 '</div>' +
265 '</div>' +
266 '<div class="jGraduate_StopSection jGraduate_SpreadMethod">' +
267 '<label class="jGraduate_Form_Heading">Spread method</label>' +
268 '<div class="jGraduate_Form_Section">' +
269 '<select class="jGraduate_spreadMethod">' +
270 '<option value=pad selected>Pad</option>' +
271 '<option value=reflect>Reflect</option>' +
272 '<option value=repeat>Repeat</option>' +
273 '</select>' +
274 '</div>' +
275 '</div>' +
276 '<div class="jGraduate_Form">' +
277 '<div class="jGraduate_Slider jGraduate_RadiusField jGraduate_rg_field">' +
278 '<label class="prelabel">Radius:</label>' +
279 '<div id="' + id + '_jGraduate_Radius" class="jGraduate_SliderBar jGraduate_Radius" title="Click to set radius">' +
280 '<img id="' + id + '_jGraduate_RadiusArrows" class="jGraduate_RadiusArrows" src="' + $settings.images.clientPath + 'rangearrows2.gif">' +
281 '</div>' +
282 '<label><input type="text" id="' + id + '_jGraduate_RadiusInput" size="3" value="100"/>%</label>' +
283 '</div>' +
284 '<div class="jGraduate_Slider jGraduate_EllipField jGraduate_rg_field">' +
285 '<label class="prelabel">Ellip:</label>' +
286 '<div id="' + id + '_jGraduate_Ellip" class="jGraduate_SliderBar jGraduate_Ellip" title="Click to set Ellip">' +
287 '<img id="' + id + '_jGraduate_EllipArrows" class="jGraduate_EllipArrows" src="' + $settings.images.clientPath + 'rangearrows2.gif">' +
288 '</div>' +
289 '<label><input type="text" id="' + id + '_jGraduate_EllipInput" size="3" value="0"/>%</label>' +
290 '</div>' +
291 '<div class="jGraduate_Slider jGraduate_AngleField jGraduate_rg_field">' +
292 '<label class="prelabel">Angle:</label>' +
293 '<div id="' + id + '_jGraduate_Angle" class="jGraduate_SliderBar jGraduate_Angle" title="Click to set Angle">' +
294 '<img id="' + id + '_jGraduate_AngleArrows" class="jGraduate_AngleArrows" src="' + $settings.images.clientPath + 'rangearrows2.gif">' +
295 '</div>' +
296 '<label><input type="text" id="' + id + '_jGraduate_AngleInput" size="3" value="0"/>º&nbsp;</label>' +
297 '</div>' +
298 '<div class="jGraduate_Slider jGraduate_OpacField">' +
299 '<label class="prelabel">Opac:</label>' +
300 '<div id="' + id + '_jGraduate_Opac" class="jGraduate_SliderBar jGraduate_Opac" title="Click to set Opac">' +
301 '<img id="' + id + '_jGraduate_OpacArrows" class="jGraduate_OpacArrows" src="' + $settings.images.clientPath + 'rangearrows2.gif">' +
302 '</div>' +
303 '<label><input type="text" id="' + id + '_jGraduate_OpacInput" size="3" value="100"/>%</label>' +
304 '</div>' +
305 '</div>' +
306 '<div class="jGraduate_OkCancel">' +
307 '<input type="button" id="' + id + '_jGraduate_Ok" class="jGraduate_Ok" value="OK"/>' +
308 '<input type="button" id="' + id + '_jGraduate_Cancel" class="jGraduate_Cancel" value="Cancel"/>' +
309 '</div>');
310
311 // --------------
312 // Set up all the SVG elements (the gradient, stops and rectangle)
313 var MAX = 256, MARGINX = 0, MARGINY = 0, STOP_RADIUS = 15/2,
314 SIZEX = MAX - 2*MARGINX, SIZEY = MAX - 2*MARGINY;
315
316 var curType, curGradient, previewRect;
317
318 var attr_input = {};
319
320 var SLIDERW = 145;
321 $('.jGraduate_SliderBar').width(SLIDERW);
322
323 var container = $('#' + id+'_jGraduate_GradContainer')[0];
324
325 var svg = mkElem('svg', {
326 id: id + '_jgraduate_svg',
327 width: MAX,
328 height: MAX,
329 xmlns: ns.svg
330 }, container);
331
332 // if we are sent a gradient, import it
333
334 curType = curType || $this.paint.type;
335
336 var grad = curGradient = $this.paint[curType];
337
338 var gradalpha = $this.paint.alpha;
339
340 var isSolid = curType === 'solidColor';
341
342 // Make any missing gradients
343 switch ( curType ) {
344 case "solidColor":
345 // fall through
346 case "linearGradient":
347 if(!isSolid) {
348 curGradient.id = id+'_lg_jgraduate_grad';
349 grad = curGradient = svg.appendChild(curGradient);//.cloneNode(true));
350 }
351 mkElem('radialGradient', {
352 id: id + '_rg_jgraduate_grad'
353 }, svg);
354 if(curType === "linearGradient") break;
355 case "radialGradient":
356 if(!isSolid) {
357 curGradient.id = id+'_rg_jgraduate_grad';
358 grad = curGradient = svg.appendChild(curGradient);//.cloneNode(true));
359 }
360 mkElem('linearGradient', {
361 id: id + '_lg_jgraduate_grad'
362 }, svg);
363 }
364
365 if(isSolid) {
366 grad = curGradient = $('#' + id + '_lg_jgraduate_grad')[0];
367 var color = $this.paint[curType];
368 mkStop(0, '#' + color, 1);
369
370 var type = typeof $settings.newstop;
371
372 if(type === 'string') {
373 switch ( $settings.newstop ) {
374 case 'same':
375 mkStop(1, '#' + color, 1);
376 break;
377
378 case 'inverse':
379 // Invert current color for second stop
380 var inverted = '';
381
382 for(var i = 0; i < 6; i += 2) {
383 var ch = color.substr(i, 2);
384 var inv = (255 - parseInt(color.substr(i, 2), 16)).toString(16);
385 if(inv.length < 2) inv = 0 + inv;
386 inverted += inv;
387 }
388 mkStop(1, '#' + inverted, 1);
389 break;
390
391 case 'white':
392 mkStop(1, '#ffffff', 1);
393 break;
394
395 case 'black':
396 mkStop(1, '#000000', 1);
397 break;
398 }
399 } else if(type === 'object'){
400 var opac = ('opac' in $settings.newstop) ? $settings.newstop.opac : 1;
401 mkStop(1, ($settings.newstop.color || '#' + color), opac);
402 }
403 }
404
405
406 var x1 = parseFloat(grad.getAttribute('x1')||0.0),
407 y1 = parseFloat(grad.getAttribute('y1')||0.0),
408 x2 = parseFloat(grad.getAttribute('x2')||1.0),
409 y2 = parseFloat(grad.getAttribute('y2')||0.0);
410
411 var cx = parseFloat(grad.getAttribute('cx')||0.5),
412 cy = parseFloat(grad.getAttribute('cy')||0.5),
413 fx = parseFloat(grad.getAttribute('fx')|| cx),
414 fy = parseFloat(grad.getAttribute('fy')|| cy);
415
416
417 var previewRect = mkElem('rect', {
418 id: id + '_jgraduate_rect',
419 x: MARGINX,
420 y: MARGINY,
421 width: SIZEX,
422 height: SIZEY,
423 fill: 'url(#'+id+'_jgraduate_grad)',
424 'fill-opacity': gradalpha/100
425 }, svg);
426
427 // stop visuals created here
428 var beginCoord = $('<div/>').attr({
429 'class': 'grad_coord jGraduate_lg_field',
430 title: 'Begin Stop'
431 }).text(1).css({
432 top: y1 * MAX,
433 left: x1 * MAX
434 }).data('coord', 'start').appendTo(container);
435
436 var endCoord = beginCoord.clone().text(2).css({
437 top: y2 * MAX,
438 left: x2 * MAX
439 }).attr('title', 'End stop').data('coord', 'end').appendTo(container);
440
441 var centerCoord = $('<div/>').attr({
442 'class': 'grad_coord jGraduate_rg_field',
443 title: 'Center stop'
444 }).text('C').css({
445 top: cy * MAX,
446 left: cx * MAX
447 }).data('coord', 'center').appendTo(container);
448
449 var focusCoord = centerCoord.clone().text('F').css({
450 top: fy * MAX,
451 left: fx * MAX,
452 display: 'none'
453 }).attr('title', 'Focus point').data('coord', 'focus').appendTo(container);
454
455 focusCoord[0].id = id + '_jGraduate_focusCoord';
456
457 var coords = $(idref + ' .grad_coord');
458
459// $(container).hover(function() {
460// coords.animate({
461// opacity: 1
462// }, 500);
463// }, function() {
464// coords.animate({
465// opacity: .2
466// }, 500);
467// });
468
469 $.each(['x1', 'y1', 'x2', 'y2', 'cx', 'cy', 'fx', 'fy'], function(i, attr) {
470 var attrval = curGradient.getAttribute(attr);
471
472 var isRadial = isNaN(attr[1]);
473
474 if(!attrval) {
475 // Set defaults
476 if(isRadial) {
477 // For radial points
478 attrval = "0.5";
479 } else {
480 // Only x2 is 1
481 attrval = attr === 'x2' ? "1.0" : "0.0";
482 }
483 }
484
485 attr_input[attr] = $('#'+id+'_jGraduate_' + attr)
486 .val(attrval)
487 .change(function() {
488 // TODO: Support values < 0 and > 1 (zoomable preview?)
489 if (isNaN(parseFloat(this.value)) || this.value < 0) {
490 this.value = 0.0;
491 } else if(this.value > 1) {
492 this.value = 1.0;
493 }
494
495 if(!(attr[0] === 'f' && !showFocus)) {
496 if(isRadial && curType === 'radialGradient' || !isRadial && curType === 'linearGradient') {
497 curGradient.setAttribute(attr, this.value);
498 }
499 }
500
501 if(isRadial) {
502 var $elem = attr[0] === "c" ? centerCoord : focusCoord;
503 } else {
504 var $elem = attr[1] === "1" ? beginCoord : endCoord;
505 }
506
507 var cssName = attr.indexOf('x') >= 0 ? 'left' : 'top';
508
509 $elem.css(cssName, this.value * MAX);
510 }).change();
511 });
512
513
514
515 function mkStop(n, color, opac, sel, stop_elem) {
516 var stop = stop_elem || mkElem('stop',{'stop-color':color,'stop-opacity':opac,offset:n}, curGradient);
517 if(stop_elem) {
518 color = stop_elem.getAttribute('stop-color');
519 opac = stop_elem.getAttribute('stop-opacity');
520 n = stop_elem.getAttribute('offset');
521 } else {
522 curGradient.appendChild(stop);
523 }
524 if(opac === null) opac = 1;
525
526 var picker_d = 'M-6.2,0.9c3.6-4,6.7-4.3,6.7-12.4c-0.2,7.9,3.1,8.8,6.5,12.4c3.5,3.8,2.9,9.6,0,12.3c-3.1,2.8-10.4,2.7-13.2,0C-9.6,9.9-9.4,4.4-6.2,0.9z';
527
528 var pathbg = mkElem('path',{
529 d: picker_d,
530 fill: 'url(#jGraduate_trans)',
531 transform: 'translate(' + (10 + n * MAX) + ', 26)'
532 }, stopGroup);
533
534 var path = mkElem('path',{
535 d: picker_d,
536 fill: color,
537 'fill-opacity': opac,
538 transform: 'translate(' + (10 + n * MAX) + ', 26)',
539 stroke: '#000',
540 'stroke-width': 1.5
541 }, stopGroup);
542
543 $(path).mousedown(function(e) {
544 selectStop(this);
545 drag = cur_stop;
546 $win.mousemove(dragColor).mouseup(remDrags);
547 stop_offset = stopMakerDiv.offset();
548 e.preventDefault();
549 return false;
550 }).data('stop', stop).data('bg', pathbg).dblclick(function() {
551 $('div.jGraduate_LightBox').show();
552 var colorhandle = this;
553 var stopOpacity = +stop.getAttribute('stop-opacity') || 1;
554 var stopColor = stop.getAttribute('stop-color') || 1;
555 var thisAlpha = (parseFloat(stopOpacity)*255).toString(16);
556 while (thisAlpha.length < 2) { thisAlpha = "0" + thisAlpha; }
557 color = stopColor.substr(1) + thisAlpha;
558 $('#'+id+'_jGraduate_stopPicker').css({'left': 100, 'bottom': 15}).jPicker({
559 window: { title: "Pick the start color and opacity for the gradient" },
560 images: { clientPath: $settings.images.clientPath },
561 color: { active: color, alphaSupport: true }
562 }, function(color, arg2){
563 stopColor = color.val('hex') ? ('#'+color.val('hex')) : "none";
564 stopOpacity = color.val('a') !== null ? color.val('a')/256 : 1;
565 colorhandle.setAttribute('fill', stopColor);
566 colorhandle.setAttribute('fill-opacity', stopOpacity);
567 stop.setAttribute('stop-color', stopColor);
568 stop.setAttribute('stop-opacity', stopOpacity);
569 $('div.jGraduate_LightBox').hide();
570 $('#'+id+'_jGraduate_stopPicker').hide();
571 }, null, function() {
572 $('div.jGraduate_LightBox').hide();
573 $('#'+id+'_jGraduate_stopPicker').hide();
574 });
575 });
576
577 $(curGradient).find('stop').each(function() {
578 var cur_s = $(this);
579 if(+this.getAttribute('offset') > n) {
580 if(!color) {
581 var newcolor = this.getAttribute('stop-color');
582 var newopac = this.getAttribute('stop-opacity');
583 stop.setAttribute('stop-color', newcolor);
584 path.setAttribute('fill', newcolor);
585 stop.setAttribute('stop-opacity', newopac === null ? 1 : newopac);
586 path.setAttribute('fill-opacity', newopac === null ? 1 : newopac);
587 }
588 cur_s.before(stop);
589 return false;
590 }
591 });
592 if(sel) selectStop(path);
593 return stop;
594 }
595
596 function remStop() {
597 delStop.setAttribute('display', 'none');
598 var path = $(cur_stop);
599 var stop = path.data('stop');
600 var bg = path.data('bg');
601 $([cur_stop, stop, bg]).remove();
602 }
603
604
605 var stops, stopGroup;
606
607 var stopMakerDiv = $('#' + id + '_jGraduate_StopSlider');
608
609 var cur_stop, stopGroup, stopMakerSVG, drag;
610
611 var delStop = mkElem('path',{
612 d:'m9.75,-6l-19.5,19.5m0,-19.5l19.5,19.5',
613 fill:'none',
614 stroke:'#D00',
615 'stroke-width':5,
616 display:'none'
617 }, stopMakerSVG);
618
619
620 function selectStop(item) {
621 if(cur_stop) cur_stop.setAttribute('stroke', '#000');
622 item.setAttribute('stroke', 'blue');
623 cur_stop = item;
624 cur_stop.parentNode.appendChild(cur_stop);
625 // stops = $('stop');
626 // opac_select.val(cur_stop.attr('fill-opacity') || 1);
627 // root.append(delStop);
628 }
629
630 var stop_offset;
631
632 function remDrags() {
633 $win.unbind('mousemove', dragColor);
634 if(delStop.getAttribute('display') !== 'none') {
635 remStop();
636 }
637 drag = null;
638 }
639
640 var scale_x = 1, scale_y = 1, angle = 0;
641 var c_x = cx;
642 var c_y = cy;
643
644 function xform() {
645 var rot = angle?'rotate(' + angle + ',' + c_x + ',' + c_y + ') ':'';
646 if(scale_x === 1 && scale_y === 1) {
647 curGradient.removeAttribute('gradientTransform');
648// $('#ang').addClass('dis');
649 } else {
650 var x = -c_x * (scale_x-1);
651 var y = -c_y * (scale_y-1);
652 curGradient.setAttribute('gradientTransform', rot + 'translate(' + x + ',' + y + ') scale(' + scale_x + ',' + scale_y + ')');
653// $('#ang').removeClass('dis');
654 }
655 }
656
657 function dragColor(evt) {
658
659 var x = evt.pageX - stop_offset.left;
660 var y = evt.pageY - stop_offset.top;
661 x = x < 10 ? 10 : x > MAX + 10 ? MAX + 10: x;
662
663 var xf_str = 'translate(' + x + ', 26)';
664 if(y < -60 || y > 130) {
665 delStop.setAttribute('display', 'block');
666 delStop.setAttribute('transform', xf_str);
667 } else {
668 delStop.setAttribute('display', 'none');
669 }
670
671 drag.setAttribute('transform', xf_str);
672 $.data(drag, 'bg').setAttribute('transform', xf_str);
673 var stop = $.data(drag, 'stop');
674 var s_x = (x - 10) / MAX;
675
676 stop.setAttribute('offset', s_x);
677 var last = 0;
678
679 $(curGradient).find('stop').each(function(i) {
680 var cur = this.getAttribute('offset');
681 var t = $(this);
682 if(cur < last) {
683 t.prev().before(t);
684 stops = $(curGradient).find('stop');
685 }
686 last = cur;
687 });
688
689 }
690
691 stopMakerSVG = mkElem('svg', {
692 width: '100%',
693 height: 45
694 }, stopMakerDiv[0]);
695
696 var trans_pattern = mkElem('pattern', {
697 width: 16,
698 height: 16,
699 patternUnits: 'userSpaceOnUse',
700 id: 'jGraduate_trans'
701 }, stopMakerSVG);
702
703 var trans_img = mkElem('image', {
704 width: 16,
705 height: 16
706 }, trans_pattern);
707
708 var bg_image = $settings.images.clientPath + 'map-opacity.png';
709
710 trans_img.setAttributeNS(ns.xlink, 'xlink:href', bg_image);
711
712 $(stopMakerSVG).on("click touchstart", function(evt) {
713 stop_offset = stopMakerDiv.offset();
714 var target = evt.target;
715 if(target.tagName === 'path') return;
716 var x = evt.pageX - stop_offset.left - 8;
717 x = x < 10 ? 10 : x > MAX + 10 ? MAX + 10: x;
718 mkStop(x / MAX, 0, 0, true);
719 evt.stopPropagation();
720 });
721
722 $(stopMakerSVG).mouseover(function() {
723 stopMakerSVG.appendChild(delStop);
724 });
725
726 stopGroup = mkElem('g', {}, stopMakerSVG);
727
728 mkElem('line', {
729 x1: 10,
730 y1: 15,
731 x2: MAX + 10,
732 y2: 15,
733 'stroke-width': 2,
734 stroke: '#000'
735 }, stopMakerSVG);
736
737
738 var spreadMethodOpt = gradPicker.find('.jGraduate_spreadMethod').change(function() {
739 curGradient.setAttribute('spreadMethod', $(this).val());
740 });
741
742
743 // handle dragging the stop around the swatch
744 var draggingCoord = null;
745
746 var onCoordDrag = function(evt) {
747 var x = evt.pageX - offset.left;
748 var y = evt.pageY - offset.top;
749
750 // clamp stop to the swatch
751 x = x < 0 ? 0 : x > MAX ? MAX : x;
752 y = y < 0 ? 0 : y > MAX ? MAX : y;
753
754 draggingCoord.css('left', x).css('top', y);
755
756 // calculate stop offset
757 var fracx = x / SIZEX;
758 var fracy = y / SIZEY;
759
760 var type = draggingCoord.data('coord');
761 var grad = curGradient;
762
763 switch ( type ) {
764 case 'start':
765 attr_input.x1.val(fracx);
766 attr_input.y1.val(fracy);
767 grad.setAttribute('x1', fracx);
768 grad.setAttribute('y1', fracy);
769 break;
770 case 'end':
771 attr_input.x2.val(fracx);
772 attr_input.y2.val(fracy);
773 grad.setAttribute('x2', fracx);
774 grad.setAttribute('y2', fracy);
775 break;
776 case 'center':
777 attr_input.cx.val(fracx);
778 attr_input.cy.val(fracy);
779 grad.setAttribute('cx', fracx);
780 grad.setAttribute('cy', fracy);
781 c_x = fracx;
782 c_y = fracy;
783 xform();
784 break;
785 case 'focus':
786 attr_input.fx.val(fracx);
787 attr_input.fy.val(fracy);
788 grad.setAttribute('fx', fracx);
789 grad.setAttribute('fy', fracy);
790 xform();
791 }
792
793 evt.preventDefault();
794 }
795
796 var onCoordUp = function() {
797 draggingCoord = null;
798 $win.unbind('mousemove', onCoordDrag).unbind('mouseup', onCoordUp);
799 }
800
801 // Linear gradient
802// (function() {
803
804
805 stops = curGradient.getElementsByTagNameNS(ns.svg, 'stop');
806
807 // if there are not at least two stops, then
808 if (numstops < 2) {
809 while (numstops < 2) {
810 curGradient.appendChild( document.createElementNS(ns.svg, 'stop') );
811 ++numstops;
812 }
813 stops = curGradient.getElementsByTagNameNS(ns.svg, 'stop');
814 }
815
816 var numstops = stops.length;
817 for(var i = 0; i < numstops; i++) {
818 mkStop(0, 0, 0, 0, stops[i]);
819 }
820
821 spreadMethodOpt.val(curGradient.getAttribute('spreadMethod') || 'pad');
822
823 var offset;
824
825 // No match, so show focus point
826 var showFocus = false;
827
828 previewRect.setAttribute('fill-opacity', gradalpha/100);
829
830
831 $('#' + id + ' div.grad_coord').mousedown(function(evt) {
832 evt.preventDefault();
833 draggingCoord = $(this);
834 var s_pos = draggingCoord.offset();
835 offset = draggingCoord.parent().offset();
836 $win.mousemove(onCoordDrag).mouseup(onCoordUp);
837 });
838
839 // bind GUI elements
840 $('#'+id+'_jGraduate_Ok').bind('click touchstart', function() {
841 $this.paint.type = curType;
842 $this.paint[curType] = curGradient.cloneNode(true);;
843 $this.paint.solidColor = null;
844 okClicked();
845 });
846 $('#'+id+'_jGraduate_Cancel').bind('click touchstart', function(paint) {
847 cancelClicked();
848 });
849
850 if(curType === 'radialGradient') {
851 if(showFocus) {
852 focusCoord.show();
853 } else {
854 focusCoord.hide();
855 attr_input.fx.val("");
856 attr_input.fy.val("");
857 }
858 }
859
860 $("#" + id + "_jGraduate_match_ctr")[0].checked = !showFocus;
861
862 var lastfx, lastfy;
863
864 $("#" + id + "_jGraduate_match_ctr").change(function() {
865 showFocus = !this.checked;
866 focusCoord.toggle(showFocus);
867 attr_input.fx.val('');
868 attr_input.fy.val('');
869 var grad = curGradient;
870 if(!showFocus) {
871 lastfx = grad.getAttribute('fx');
872 lastfy = grad.getAttribute('fy');
873 grad.removeAttribute('fx');
874 grad.removeAttribute('fy');
875 } else {
876 var fx = lastfx || .5;
877 var fy = lastfy || .5;
878 grad.setAttribute('fx', fx);
879 grad.setAttribute('fy', fy);
880 attr_input.fx.val(fx);
881 attr_input.fy.val(fy);
882 }
883 });
884
885 var stops = curGradient.getElementsByTagNameNS(ns.svg, 'stop');
886 var numstops = stops.length;
887 // if there are not at least two stops, then
888 if (numstops < 2) {
889 while (numstops < 2) {
890 curGradient.appendChild( document.createElementNS(ns.svg, 'stop') );
891 ++numstops;
892 }
893 stops = curGradient.getElementsByTagNameNS(ns.svg, 'stop');
894 }
895
896 var slider;
897
898 var setSlider = function(e) {
899 var offset = slider.offset;
900 var div = slider.parent;
901 var x = (e.pageX - offset.left - parseInt(div.css('border-left-width')));
902 if (x > SLIDERW) x = SLIDERW;
903 if (x <= 0) x = 0;
904 var posx = x - 5;
905 x /= SLIDERW;
906
907 switch ( slider.type ) {
908 case 'radius':
909 x = Math.pow(x * 2, 2.5);
910 if(x > .98 && x < 1.02) x = 1;
911 if (x <= .01) x = .01;
912 curGradient.setAttribute('r', x);
913 break;
914 case 'opacity':
915 $this.paint.alpha = parseInt(x*100);
916 previewRect.setAttribute('fill-opacity', x);
917 break;
918 case 'ellip':
919 scale_x = 1, scale_y = 1;
920 if(x < .5) {
921 x /= .5; // 0.001
922 scale_x = x <= 0 ? .01 : x;
923 } else if(x > .5) {
924 x /= .5; // 2
925 x = 2 - x;
926 scale_y = x <= 0 ? .01 : x;
927 }
928 xform();
929 x -= 1;
930 if(scale_y === x + 1) {
931 x = Math.abs(x);
932 }
933 break;
934 case 'angle':
935 x = x - .5;
936 angle = x *= 180;
937 xform();
938 x /= 100;
939 break;
940 }
941 slider.elem.css({'margin-left':posx});
942 x = Math.round(x*100);
943 slider.input.val(x);
944 };
945
946 var ellip_val = 0, angle_val = 0;
947
948 if(curType === 'radialGradient') {
949 var tlist = curGradient.gradientTransform.baseVal;
950 if(tlist.numberOfItems === 2) {
951 var t = tlist.getItem(0);
952 var s = tlist.getItem(1);
953 if(t.type === 2 && s.type === 3) {
954 var m = s.matrix;
955 if(m.a !== 1) {
956 ellip_val = Math.round(-(1 - m.a) * 100);
957 } else if(m.d !== 1) {
958 ellip_val = Math.round((1 - m.d) * 100);
959 }
960 }
961 } else if(tlist.numberOfItems === 3) {
962 // Assume [R][T][S]
963 var r = tlist.getItem(0);
964 var t = tlist.getItem(1);
965 var s = tlist.getItem(2);
966
967 if(r.type === 4
968 && t.type === 2
969 && s.type === 3) {
970
971 angle_val = Math.round(r.angle);
972 var m = s.matrix;
973 if(m.a !== 1) {
974 ellip_val = Math.round(-(1 - m.a) * 100);
975 } else if(m.d !== 1) {
976 ellip_val = Math.round((1 - m.d) * 100);
977 }
978
979 }
980 }
981 }
982
983 var sliders = {
984 radius: {
985 handle: '#' + id + '_jGraduate_RadiusArrows',
986 input: '#' + id + '_jGraduate_RadiusInput',
987 val: (curGradient.getAttribute('r') || .5) * 100
988 },
989 opacity: {
990 handle: '#' + id + '_jGraduate_OpacArrows',
991 input: '#' + id + '_jGraduate_OpacInput',
992 val: $this.paint.alpha || 100
993 },
994 ellip: {
995 handle: '#' + id + '_jGraduate_EllipArrows',
996 input: '#' + id + '_jGraduate_EllipInput',
997 val: ellip_val
998 },
999 angle: {
1000 handle: '#' + id + '_jGraduate_AngleArrows',
1001 input: '#' + id + '_jGraduate_AngleInput',
1002 val: angle_val
1003 }
1004 }
1005
1006 $.each(sliders, function(type, data) {
1007 var handle = $(data.handle);
1008 handle.mousedown(function(evt) {
1009 var parent = handle.parent();
1010 slider = {
1011 type: type,
1012 elem: handle,
1013 input: $(data.input),
1014 parent: parent,
1015 offset: parent.offset()
1016 };
1017 $win.mousemove(dragSlider).mouseup(stopSlider);
1018 evt.preventDefault();
1019 });
1020
1021 $(data.input).val(data.val).change(function() {
1022 var val = +this.value;
1023 var xpos = 0;
1024 var isRad = curType === 'radialGradient';
1025 switch ( type ) {
1026 case 'radius':
1027 if(isRad) curGradient.setAttribute('r', val / 100);
1028 xpos = (Math.pow(val / 100, 1 / 2.5) / 2) * SLIDERW;
1029 break;
1030
1031 case 'opacity':
1032 $this.paint.alpha = val;
1033 previewRect.setAttribute('fill-opacity', val / 100);
1034 xpos = val * (SLIDERW / 100);
1035 break;
1036
1037 case 'ellip':
1038 scale_x = scale_y = 1;
1039 if(val === 0) {
1040 xpos = SLIDERW * .5;
1041 break;
1042 }
1043 if(val > 99.5) val = 99.5;
1044 if(val > 0) {
1045 scale_y = 1 - (val / 100);
1046 } else {
1047 scale_x = - (val / 100) - 1;
1048 }
1049
1050 xpos = SLIDERW * ((val + 100) / 2) / 100;
1051 if(isRad) xform();
1052 break;
1053
1054 case 'angle':
1055 angle = val;
1056 xpos = angle / 180;
1057 xpos += .5;
1058 xpos *= SLIDERW;
1059 if(isRad) xform();
1060 }
1061 if(xpos > SLIDERW) {
1062 xpos = SLIDERW;
1063 } else if(xpos < 0) {
1064 xpos = 0;
1065 }
1066 handle.css({'margin-left': xpos - 5});
1067 }).change();
1068 });
1069
1070 var dragSlider = function(evt) {
1071 setSlider(evt);
1072 evt.preventDefault();
1073 };
1074
1075 var stopSlider = function(evt) {
1076 $win.unbind('mousemove', dragSlider).unbind('mouseup', stopSlider);
1077 slider = null;
1078 };
1079
1080
1081 // --------------
1082 var thisAlpha = ($this.paint.alpha*255/100).toString(16);
1083 while (thisAlpha.length < 2) { thisAlpha = "0" + thisAlpha; }
1084 thisAlpha = thisAlpha.split(".")[0];
1085 color = $this.paint.solidColor == "none" ? "" : $this.paint.solidColor + thisAlpha;
1086
1087 if(!isSolid) {
1088 color = stops[0].getAttribute('stop-color');
1089 }
1090
1091 // This should be done somewhere else, probably
1092 $.extend($.fn.jPicker.defaults.window, {
1093 alphaSupport: true, effects: {type: 'show',speed: 0}
1094 });
1095
1096 colPicker.jPicker(
1097 {
1098 window: { title: $settings.window.pickerTitle },
1099 images: { clientPath: $settings.images.clientPath },
1100 color: { active: color, alphaSupport: true }
1101 },
1102 function(color) {
1103 $this.paint.type = "solidColor";
1104 $this.paint.alpha = color.val('ahex') ? Math.round((color.val('a') / 255) * 100) : 100;
1105 $this.paint.solidColor = color.val('hex') ? color.val('hex') : "none";
1106 $this.paint.radialGradient = null;
1107 okClicked();
1108 },
1109 null,
1110 function(){ cancelClicked(); }
1111 );
1112
1113
1114 var tabs = $(idref + ' .jGraduate_tabs li');
1115 tabs.on("click touchstart", function() {
1116 tabs.removeClass('jGraduate_tab_current');
1117 $(this).addClass('jGraduate_tab_current');
1118 $(idref + " > div").hide();
1119 var type = $(this).attr('data-type');
1120 var container = $(idref + ' .jGraduate_gradPick').show();
1121 if(type === 'rg' || type === 'lg') {
1122 // Show/hide appropriate fields
1123 $('.jGraduate_' + type + '_field').show();
1124 $('.jGraduate_' + (type === 'lg' ? 'rg' : 'lg') + '_field').hide();
1125
1126 $('#' + id + '_jgraduate_rect')[0].setAttribute('fill', 'url(#' + id + '_' + type + '_jgraduate_grad)');
1127
1128 // Copy stops
1129
1130 curType = type === 'lg' ? 'linearGradient' : 'radialGradient';
1131
1132 $('#' + id + '_jGraduate_OpacInput').val($this.paint.alpha).change();
1133
1134 var newGrad = $('#' + id + '_' + type + '_jgraduate_grad')[0];
1135
1136 if(curGradient !== newGrad) {
1137 var cur_stops = $(curGradient).find('stop');
1138 $(newGrad).empty().append(cur_stops);
1139 curGradient = newGrad;
1140 var sm = spreadMethodOpt.val();
1141 curGradient.setAttribute('spreadMethod', sm);
1142 }
1143 showFocus = type === 'rg' && curGradient.getAttribute('fx') != null && !(cx == fx && cy == fy);
1144 $('#' + id + '_jGraduate_focusCoord').toggle(showFocus);
1145 if(showFocus) {
1146 $('#' + id + '_jGraduate_match_ctr')[0].checked = false;
1147 }
1148 } else {
1149 $(idref + ' .jGraduate_gradPick').hide();
1150 $(idref + ' .jGraduate_colPick').show();
1151 }
1152 });
1153 $(idref + " > div").hide();
1154 tabs.removeClass('jGraduate_tab_current');
1155 var tab;
1156 switch ( $this.paint.type ) {
1157 case 'linearGradient':
1158 tab = $(idref + ' .jGraduate_tab_lingrad');
1159 break;
1160 case 'radialGradient':
1161 tab = $(idref + ' .jGraduate_tab_radgrad');
1162 break;
1163 default:
1164 tab = $(idref + ' .jGraduate_tab_color');
1165 break;
1166 }
1167 $this.show();
1168
1169 // jPicker will try to show after a 0ms timeout, so need to fire this after that
1170 setTimeout(function() {
1171 tab.addClass('jGraduate_tab_current').click();
1172 }, 10);
1173 });
1174 };
1175})();
Note: See TracBrowser for help on using the repository browser.