Last active
July 29, 2016 00:50
-
-
Save shspage/1fb61ff3c6b5466451d371e6666ccc0b to your computer and use it in GitHub Desktop.
colorizing script for Illustrator (Commented in Japanese)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#target "illustrator" | |
// 選択パスのうち最前面のもののfillColor(CMYKグラデーション)をソースとして、 | |
// その他の選択パスのfillColorを、選択パス(最前面を除く)を囲む | |
// 矩形範囲の対角線(左上→右下)を基準にした位置にあたるソース上の色の云々 | |
// TODO: midPoint, opacity を考慮する | |
(function(){ | |
function main(){ | |
// selectionは全てpathItemとする | |
var sel = app.activeDocument.selection; | |
if(sel.length < 2) return; | |
// 最前面のパスのfillColor(CMYKグラデーション)をソースにする | |
var grad = sel[0].fillColor; | |
if(isGradInvalid(grad)) return; | |
var stops = grad.gradient.gradientStops; | |
// 選択範囲全体の矩形範囲(最前面を除く)を取得 | |
var rect = getSelBounds(sel); | |
// 色作成用function | |
var getColorOnDiagonal = getColorOnDiagonalFunc(rect, stops); | |
if(!getColorOnDiagonal) return; | |
// 色を割り当て | |
for(var i = 1; i < sel.length; i++){ | |
var center = getCenter(sel[i]); | |
sel[i].fillColor = getColorOnDiagonal(center); | |
} | |
} | |
// --------------------------------------------------------------- | |
// グラデーションが不適切な場合に true を返す。 | |
// grad = GradientColor ? | |
function isGradInvalid(grad){ | |
if(!grad || grad.typename != "GradientColor"){ | |
alert("最前面パスの色がグラデーションではありません"); | |
return true; | |
} | |
var stops = grad.gradient.gradientStops; | |
for(var i = 0; i < stops.length; i++){ | |
if(stops[i].color.typename != "CMYKColor" | |
&& stops[i].color.typename != "GrayColor"){ | |
alert("グラデーションにCMYK, グレースケール以外の色が含まれています"); | |
return true; | |
} | |
} | |
return false; | |
} | |
// --------------------------------------------------------------- | |
function getSelBounds(sel){ | |
var rect = { left:0, top:0, right:0, bottom:0, width:0, height:0 }; | |
// 最前面は除く | |
var idx = 1; | |
var gb = sel[idx].geometricBounds; | |
rect.left = gb[0]; | |
rect.top = gb[1]; | |
rect.right = gb[2]; | |
rect.bottom = gb[3]; | |
for(var i = idx, iEnd = sel.length; i < iEnd; i++){ | |
gb = sel[i].geometricBounds; | |
if(gb[0] < rect.left) rect.left = gb[0]; | |
if(gb[1] > rect.top) rect.top = gb[1]; | |
if(gb[2] > rect.right) rect.right = gb[2]; | |
if(gb[3] < rect.bottom) rect.bottom = gb[3]; | |
} | |
rect.width = rect.right - rect.left; | |
rect.height = rect.top - rect.bottom; | |
return rect; | |
} | |
// --------------------------------------------------------------- | |
var getCenter = function(p){ | |
var gb = p.geometricBounds; // left, top, right, bottom | |
return [(gb[0] + gb[2]) / 2, (gb[1] + gb[3]) / 2]; | |
} | |
// --------------------------------------------------------------- | |
function mix(c1, c2, p1, p2){ | |
return Math.min(100, c1 * p1 + c2 * p2); | |
} | |
// --------------------------------------------------------------- | |
function getColorOfGradationAtPercent(stops, p){ | |
// stops = grad.gradient.gradientStops | |
// p = 対角線左上=0, 右下=100 とした対角線上の位置 | |
// TODO: midPoint, opacity | |
// midPoint, opacity は考慮されていません | |
if(p <= stops[0].rampPoint) return stops[0].color; | |
if(p >= stops[stops.length - 1].rampPoint) return stops[stops.length - 1].color; | |
var idx = 0; | |
for(var i = 1; i < stops.length; i++){ | |
if(p < stops[i].rampPoint){ | |
idx = i; | |
break; | |
} | |
} | |
var loc = p - stops[idx - 1].rampPoint; | |
var range = stops[idx].rampPoint - stops[idx - 1].rampPoint; | |
if(range == 0) return stops[idx].color; | |
var p1 = loc / range; | |
var p2 = 1 - p1; | |
var c1 = fixColor(stops[idx - 1].color); | |
var c2 = fixColor(stops[idx].color); | |
var c = new CMYKColor(); | |
c.cyan = mix(c1.cyan, c2.cyan, p2, p1); | |
c.magenta = mix(c1.magenta, c2.magenta, p2, p1); | |
c.yellow = mix(c1.yellow, c2.yellow, p2, p1); | |
c.black = mix(c1.black, c2.black, p2, p1); | |
return c; | |
} | |
// --------------------------------------------------------------- | |
function fixColor(c){ | |
if(c.typename == "CMYKColor") return c; | |
if(c.typename == "GrayColor"){ | |
var c1 = new CMYKColor(); | |
c1.cyan = 0; | |
c1.magenta = 0; | |
c1.yellow = 0; | |
c1.black = c.gray; | |
return c1; | |
} | |
} | |
// --------------------------------------------------------------- | |
function getColorOnDiagonalFunc(rect, stops){ | |
var wh = rect.width * rect.height; | |
if(wh == 0) return; | |
var wh2 = 2 * wh; | |
var getColorOnDiagonal = function(point){ | |
var x = point[0] - rect.left; | |
var y = point[1] - rect.bottom; | |
var p = 100 * (wh + rect.height * x - rect.width * y) / wh2; // wh2 != 0 | |
var c = getColorOfGradationAtPercent(stops, p); | |
return c; | |
} | |
return getColorOnDiagonal; | |
} | |
main(); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment