Skip to content

Instantly share code, notes, and snippets.

@shspage
Created June 5, 2016 06:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shspage/c3df24731bbc4f9dece27fcb5dea2901 to your computer and use it in GitHub Desktop.
Save shspage/c3df24731bbc4f9dece27fcb5dea2901 to your computer and use it in GitHub Desktop.
colorizing script for Illustrator (Commented in Japanese)
#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);
var center = [(rect.left + rect.right) / 2,
(rect.top + rect.bottom) / 2];
// 色作成用function
var getColorByAngle = getColorByAngleFunc(center, stops);
if(!getColorByAngle) return;
// 色を割り当て
for(var i = 1; i < sel.length; i++){
var center = getCenter(sel[i]);
sel[i].fillColor = getColorByAngle(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 getColorByAngleFunc(center, stops){
var getColorByAngle = function(point){
var t = Math.atan2(center[1] - point[1],
center[0] - point[0]); // -PI ~ PI
//var p = (Math.PI + t) * 100 / (Math.PI * 2);
var p = (Math.PI + t) * 50 / Math.PI;
var c = getColorOfGradationAtPercent(stops, p);
return c;
}
return getColorByAngle;
}
main();
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment