-
Notifications
You must be signed in to change notification settings - Fork 1
/
gradient-toy.jsx
428 lines (403 loc) · 13 KB
/
gradient-toy.jsx
1
#target Photoshop/* Photoshop Javascripting Gradient Toy Copyright (c) 2011, SjG <[email protected]> All Rights Reserved*/ #include "./optsys.jsx";#include "./gradientsys.jsx";#include "./utilities.jsx";var optconf = { 'fields':{ 'pattern':{ 'input':'radio', 'label':'Gradient Pattern', 'default':'circles', 'options':{ 'circles':{'label':'Circles','tag':'gradientopts','state':'circles'}, 'radial':{'label':'Radial','tag':'gradientopts','state':'radial'}, 'linear':{'label':'Linear','tag':'gradientopts','state':'linear'} }, }, 'type':{ 'input':'radio', 'label':'Gradient Type', 'default':'sine', 'options':{'step':'Stepped','triangle':'Triangle Wave','sine':'Sine Wave'}, }, 'cycles': { 'input':'slider', 'label':'Number of Cycles', 'default':10, 'min':1, 'max':500, 'numbertype':'int' }, 'helptext': { 'input':'static', 'label':'Note', 'value':'One cycle is from foreground to background color', }, 'stroke_width':{ 'label':'Stroke Width', 'default':3, 'input':'slider', 'min':1, 'max':100, 'numbertype':'int' }, 'stroke_growth':{ 'label':'Stroke Width Change %', 'default':0, 'input':'slider', 'min':-25, 'max':25, 'numbertype':'float' }, 'radial_width':{ 'label':'Stroke Width', 'default':3, 'input':'slider', 'min':1, 'max':100, 'numbertype':'int' }, 'radial_growth':{ 'label':'Stroke Width Change %', 'default':0, 'input':'slider', 'min':-25, 'max':25, 'numbertype':'float' }, 'angle':{ 'label':'Angle', 'default':0, 'input':'slider', 'min':0, 'max':90 }, 'steps':{ 'label':'Steps/Cycle', 'default':36, 'input':'slider', 'min':1, 'max':360, 'numbertype':'int' }, 'edges':{ 'input':'radio', 'label':'Anti-Alias mode', 'default':'soft', 'options':{'none':'None','soft':'Soft','sharper':'Sharper'}, }, 'applyto':{ 'input':'radio', 'label':'Calculate using', 'default':'doc', 'options':{ 'doc':{'label':'Full Document','tag':'fof','state':'doc'}, 'sel':{'label':'Selected Region','tag':'fof','state':'sel'} }, }, 'fitorfill':{ 'input':'radio', 'label':'Fill Type', 'default':'fit', 'options':{'fit':'Fit to Selection','fill':'Fill Selected Region'}, }, 'helptext2': { 'input':'static', 'label':'Calculations', 'value':'(Used to determine centers and cycle endpoints)', }, 'fitorfillhelp':{ 'input':'static', 'label':'Note:', 'value':'Calc. using "Full Document" forces a "Fill" of selection.', }, }, 'ui':{ 'title':'Options', 'width':700, 'fieldsets':[ { 'title':'Gradient', 'columns':[ ['pattern','type','cycles','helptext'] ] }, { 'title':'Options', 'tag':'gradientopts', 'state':'circles', 'columns':[ ['radial_width'], ['radial_growth'] ] }, { 'title':'Options', 'tag':'gradientopts', 'state':'linear', 'columns':[ ['stroke_width', 'angle'], ['stroke_growth'] ] }, { 'title':'Options', 'tag':'gradientopts', 'state':'radial', 'columns':[ ['steps','edges'] ] }, { 'title':'Calculations', 'columns':[ ['applyto','helptext2'] ] }, { 'title':'Fit or Fill', 'tag':'fof', 'state':'sel', 'columns':[ ['fitorfill'] ] }, { 'title':'Fit or Fill', 'tag':'fof', 'state':'doc', 'columns':[ ['fitorfillhelp'] ] } ] }}; var opts = new OptObject(optconf);var d=new Date();var namestr = 'Gradient Toy run '+d.toString();var defaultRulerUnits = preferences.rulerUnits;preferences.rulerUnits = Units.PIXELS;var originalLayer = activeDocument.activeLayer;var maskLayer = activeDocument.channels.add();try { var SB = activeDocument.selection.bounds; }catch (e){ app.activeDocument.selection.selectAll();}var originalSelect = activeDocument.selection;var originalBounds = originalSelect.bounds;originalSelect.store(maskLayer);var doc_width = parseInt(app.activeDocument.width); var doc_height = parseInt(app.activeDocument.height);var sel_width = parseInt(originalBounds[2]) - parseInt(originalBounds[0]);var sel_height = parseInt(originalBounds[3]) - parseInt(originalBounds[1]);$.writeln('doc_width,doc_height: '+doc_width+','+doc_height+', sel_width,sel_height: '+sel_width+','+sel_height);if (opts.doDialog(optconf)) { opts.writeToMetadata('Metadata '+namestr); var strokeColor = app.foregroundColor; try { var nextLayer = app.activeDocument.artLayers.add(); nextLayer.name = namestr; app.activeDocument.activeLayer = nextLayer; var dim; var max; var centerx, centery; if (opts.applyto == 'doc') { if (opts.fitorfill == 'fit') { dim = Math.min(doc_width,doc_height); max = Math.floor(dim/2); } else { dim = Math.max(doc_width,doc_height); max = Math.sqrt(doc_width * doc_width + doc_height * doc_height); } centerx = doc_width/2; centery = doc_height/2; } else { if (opts.fitorfill == 'fit') { dim = Math.min(sel_width,sel_height); max = Math.floor(dim/2); } else { dim = Math.max(sel_width,sel_height); app.activeDocument.selection.load(maskLayer, SelectionType.REPLACE); var res = min_max_radius_of_selection(false); max = res[1]; } centerx = parseInt(originalBounds[0]) + sel_width/2; centery = parseInt(originalBounds[1]) + sel_height/2; } var i=1; var stroke = opts.stroke_width; var ucount = 0; if (opts.pattern == 'circles') { while (i < max) { strokeColor = new RGBColor(); var r = gradient(i, 0, max, opts.cycles, opts.gtype); strokeColor.red = r['red']; strokeColor.green = r['green']; strokeColor.blue = r['blue']; app.foregroundColor.rgb = strokeColor; app.activeDocument.selection.load(maskLayer); if ((parseInt(originalBounds[0]) < centerx+max-i && parseInt(originalBounds[1]) < centery + max - i) || (parseInt(originalBounds[2]) > centerx-max+i && parseInt(originalBounds[3]) > centery - max + i)) { drawCircle( centerx - max + i, centery - max + i, centerx + max - i, centery + max - i, true); } ucount++; i += stroke; if (ucount % 50 == 0) { WaitForRedraw(); } if (opts.stroke_growth != 0) { stroke = stroke * (1 + (opts.stroke_growth / 100)); } } } else if (opts.pattern == 'radial') { var sweep= opts.steps * opts.cycles; var angle = 2 * Math.PI / sweep; while (i <= sweep) { strokeColor = new RGBColor(); var r = gradient(i, 0, sweep, opts.cycles, opts.gtype); strokeColor.red = r['red']; strokeColor.green = r['green']; strokeColor.blue = r['blue']; app.foregroundColor.rgb = strokeColor; app.activeDocument.selection.select( [ [centerx,centery], [centerx + max * Math.cos((i-1) * angle),centery + max * Math.sin((i-1) * angle)], [centerx + max * Math.cos(i * angle ),centery + max * Math.sin(i * angle )] ], SelectionType.REPLACE, 0, opts.edges != 'none' ); app.activeDocument.selection.load(maskLayer, SelectionType.INTERSECT); try { var q= app.activeDocument.selection.bounds; app.activeDocument.selection.fill(strokeColor,ColorBlendMode.NORMAL); app.activeDocument.selection.load(maskLayer, SelectionType.REPLACE); if (i < sweep && opts.edges =='sharper') { strokeLine(centerx,centery,centerx + max * Math.cos(i * angle ),centery + max * Math.sin(i * angle ),1); strokeLine(centerx,centery,centerx + max * Math.cos((i-1) * angle ),centery + max * Math.sin((i-1) * angle ),1); } } catch (e2) {}; i++; if (i % 50 == 0) { WaitForRedraw(); } } } else if (opts.pattern == 'linear') { app.activeDocument.selection.load(maskLayer, SelectionType.REPLACE); var bbox = app.activeDocument.selection.bounds; app.activeDocument.selection.deselect(); var xmin = parseInt(bbox[0]); var xmax = parseInt(bbox[2]); var ymin = parseInt(bbox[1]); var ymax = parseInt(bbox[3]); var lcos = Math.cos(opts.angle * Math.PI / 180); var lsin = Math.sin(opts.angle * Math.PI / 180); var bboxwidth = xmax - xmin; var bboxheight = ymax - ymin; if (opts.angle > 45) { var lmax = bboxheight / lsin; var incr = stroke * lsin; var offset = lmax * lcos; var range = bboxwidth + offset; for (var i = 0; i<= range; i+=incr) { strokeColor = new RGBColor(); var r = gradient(i, 0, range, opts.cycles, opts.gtype); strokeColor.red = r['red']; strokeColor.green = r['green']; strokeColor.blue = r['blue']; app.foregroundColor.rgb = strokeColor; strokeLine(xmin+i, ymin, xmin + i - lmax * lcos, ymax, stroke*1.1); if (opts.stroke_growth != 0) { stroke = stroke * (1 + (opts.stroke_growth / 100)); incr = stroke * lsin; } } } else { var lmax = bboxwidth / lcos; var incr = stroke * lcos; var offset = lmax * lsin; var range = bboxheight + offset; for (var i = 0; i<= range; i+=incr) { strokeColor = new RGBColor(); var r = gradient(i, 0, range, opts.cycles, opts.gtype); strokeColor.red = r['red']; strokeColor.green = r['green']; strokeColor.blue = r['blue']; app.foregroundColor.rgb = strokeColor; strokeLine(xmax, ymax - i, xmin, ymax - i + lmax * lsin, stroke*1.1); if (opts.stroke_growth != 0) { stroke = stroke * (1 + (opts.stroke_growth / 100)); incr = stroke * lcos; } } } app.activeDocument.selection.load(maskLayer, SelectionType.REPLACE); app.activeDocument.selection.invert(); app.activeDocument.selection.clear(); app.activeDocument.selection.invert(); } } catch (exception) { alert(exception); } }preferences.rulerUnits = defaultRulerUnits;resetDocumentColors();maskLayer.remove();alert('Gradient Toy run completed.');