/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Here are a few parameters that you can change to modify the behavior of the patterm // Feel free to modify the values, don't change the variable names modelParameters = { // scaling of the input pattern patternScale : 1, // Spacing between patterns in pixels. // For example,1 creates 1 pixel gap between patterns spacing : 0, // use a value between -10 to 20. The default is 0. // Variation of color of the pattern. // For example, value of 0.2 means that each of the red, green, and blue color components // will be multiplied by a DIFFERENT random value from interval 0.8 and 1.2. // Set to 0 if you do not want to modify the pattern color. colorRandomness : 0.05, // use a value between 0 and 1. The default is 0.05. // Variation of pattern brightness. // For example, value of 0.6 means that each of the red, green, and blue color components // will be multiplied by THE SAME random value from interval 0.4 and 1.6. // Set to 0 if you do not want to modify the pattern brightness. brightnessRandomness : 0.1, // use a value between 0 and 1. The default is 0.1. } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // You can modify the code below but keep in mind that as with any scripting // you can break things. Keep a backup copy. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Get pattern and its size var pattern = RenderAPI.getParameter(kpsPattern) var patternSize = pattern.getParameter(kpsSize) var patternSizeForDialog = Math.max (patternSize.x, patternSize.y) // For the script to work with a menu with preview, you need to define a run method with the following three parameters: // 1. api - render api to be used. Do not use RenderAPI directly, since preview uses a different renderer // 2. parameter - contains model parameters. Do not refer directly to modelParameters inside the run method or methods called from it. // 3. scale - preview can be scaled up or down depending on the size of the input pattern. Accomodate scale inside the run method. function run (api, parameters, scale) { // get the size of the output area var outputSize = api.getParameter(kpsSize) // get the location of the top left corner of the bounding rectangle around the selected area var outputOrigin = api.getParameter(kpsOrigin) var patternSize = pattern.getParameter(kpsSize) patternSize *= parameters.patternScale // to finetune the progress bar, specify how many pixels are covered by patterns - the bigger the spacing the lower the value, for example api.setParameter(kpsPixelCoverage, 0.5 * (patternSize.x * patternSize.y) / ((patternSize.x + parameters.spacing) * (patternSize.y + parameters.spacing ) ) ) // possibly add spacing if (patternSize.x + parameters.spacing >= Math.min (5, patternSize.x) ) patternSize.x += parameters.spacing else patternSize.x = Math.min (5, patternSize.x) if (patternSize.y + parameters.spacing >= Math.min (5, patternSize.y)) patternSize.y += parameters.spacing else patternSize.y = Math.min (5, patternSize.y) // scale up if the patternsize is 1 to avoid long loop if (patternSize.x == 1 && patternSize.y == 1) { if (scale == 1) scale = 20 } patternSize *= scale; var sizeStep = (patternSize.x + patternSize.y) / 2 // negative origin may happen for preview of very small documents if (outputOrigin.x < 0) outputOrigin.x = 0 if (outputOrigin.y < 0) outputOrigin.y = 0 // don't use % since sizeStep may not be integer var xRel = outputOrigin.x - Math.floor (outputOrigin.x / sizeStep) * sizeStep var yRel = outputOrigin.y - Math.floor (outputOrigin.y / sizeStep) * sizeStep api.translateRel ( -xRel, -yRel) var row = Math.floor( outputOrigin.y / sizeStep ) var column = Math.floor( outputOrigin.x / sizeStep ) var mult = ((row*0 + column) % 2) == 0 ? 1 : -1; api.translate(-(column%2)* (patternSize.y - patternSize.x)/2, 0) var margin_y = Math.max(patternSize.x+patternSize.y, -parameters.spacing) for (var y = -patternSize.y/2; y < outputSize.y + margin_y; row++) { api.pushMatrix() // shift each second row api.translate(-mult*(row%2)* (patternSize.y - patternSize.x)/2 - 2*sizeStep, y) var col = column var margin_x = Math.max(4*sizeStep, -parameters.spacing) for (var x = 0; x < outputSize.x + margin_x; x+= rotatedSizeX, col++) { // Set the seed based on the current row and column - this assures that the color will be modified // in the same way for the pattern in the neighboring selected area var seed = (row * 214013+ col * 2531011) %0x7fffffff // var rc = parameters.colorRandomness // color randomness var br = 1 - parameters.brightnessRandomness + Engine.rand(seed) * parameters.brightnessRandomness*2 // brightness api.Color (kFillColor, br *(1 - rc + Engine.rand()*rc*2), br*(1 - rc + Engine.rand()*rc*2), br*(1 - rc + Engine.rand()*rc*2)) var angle = 90 * (col + row + Math.floor(Engine.rand()*2)*2) var side = (angle / 90) % 2 rotatedSizeX = (1-side) * patternSize.x + side * patternSize.y // Use this computation if angle is not a multiple of 90 //var sinA = Math.abs(Math.sin(angle / 180 * 3.141529) ) //var cosA = Math.abs(Math.cos(angle / 180 * 3.141529) ) //var rotatedSizeX = patternSize.x * cosA + patternSize.y * sinA //var rotatedSizeY = patternSize.x * sinA + patternSize.y * cosA api.translate(rotatedSizeX/2, 0) // the pattern is centered api.pushMatrix() api.scale (scale, scale) api.rotate(angle) api.scale(parameters.patternScale) pattern.render(api) api.popMatrix() api.translate(rotatedSizeX/2, 0) } y+=sizeStep api.popMatrix() } } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Menu start // If you want to create a menu in which you change some of the script parameters, include the following code: // For shipped scripts we can include localized strings, prefixed with $$$/ - call method localize(string) on the prefixed string // For your own strings, you can query app.locale and select several language versions (for example, your native language and english). Try alert ("Language is: " + app.locale) var decoMenu = { // an object that defines the menu menuTitle : localize("$$$/DecoScripts/CrossWeave/CrossWeave=Cross Weave"), menuBackground : [0.93, 0.93, 0.93, 1], previewBackground : [1, 1, 1, 1], panels : [ { panelName : "", leftColumnWidth : 180, unitsWidth : 65, panelMenu : [ { itemName : localize("$$$/DecoScripts/PatternScale=Pattern Scale:") , itemUnit : "", itemType : 'slider', itemValue : modelParameters.patternScale, itemMin : 0.10, itemMax : 1.25, itemStep : 0.01, varName : 'patternScale' }, { itemName : localize("$$$/DecoScripts/CrossWeave/Spacing=Spacing:"), itemUnit : localize("$$$/DecoScripts/Units/pixels=pixels"), itemType : 'slider', itemValue : modelParameters.spacing, itemMin : -patternSizeForDialog+1, itemMax : Math.max(100, 3 * patternSizeForDialog), itemStep : 1, varName : 'spacing' }, { itemName : localize("$$$/DecoScripts/ColorRandomness=Color randomness:"), itemUnit : "", itemType : 'slider', itemValue : modelParameters.colorRandomness, itemMin : 0, itemMax : 1, itemStep : 0.01, varName : 'colorRandomness' }, { itemName : localize("$$$/DecoScripts/BrightnessRandomness=Brightness randomness:"), itemUnit : "", itemType : 'slider', itemValue : modelParameters.brightnessRandomness, itemMin : 0, itemMax : 1, itemStep : 0.01, varName : 'brightnessRandomness' } ] } ] // end of panels }; // end of menu // If livePreview is set to 1, the preview image is updated live. Note that due to limitations of scripted menus the update is slow and the flickering may be disturbing. livePreview = 0 // recommended value is 0 // Call Photoshop Script that creates the menu Engine.evalFile ("_Deco Menu.jsx") // Menu finished ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// if (typeof skipRun == 'undefined' || !skipRun) // run unles we exited the preview window without pressing a button run(RenderAPI, modelParameters, 1)