turtlestitch/stitchcode/morphic.js

309 wiersze
8.2 KiB
JavaScript

/* Morph.fromImageURL = function(url) {
var m = new Morph();
m.texture = url;
m.render = function(context) {
context.fillStyle = 'rgba(0,0,0,0)';
context.fillRect(0, 0, this.width(), this.height());
if (this.texture) {
this.drawTexture(this.texture);
}
}
m.drawCachedTexture = function () {
var context = this.image.getContext('2d');
context.drawImage(
this.cachedTexture,
0,
Math.round((this.height() - this.cachedTexture.height) / 2)
);
this.changed();
};
m.drawNew();
m.setExtent(new Point(m.cachedTexture.width, m.cachedTexture.height));
return m;
}
*/
Morph.fromImageURL = function(url) {
var m = new Morph();
m.texture = url;
m.edge = Morph.prototype.edge;
m.render = function (ctx) {
Morph.prototype.render.call(this, ctx);
if (m.texture) {
m.renderTexture(m.texture, ctx);
}
};
m.fixLayout();
return m;
}
// ColorPaletteMorph ///////////////////////////////////////////////////
// from https://github.com/jguille2
var ColorPaletteMorph;
// ColorPaletteMorph inherits from Morph:
ColorPaletteMorph.prototype = new Morph();
ColorPaletteMorph.prototype.constructor = ColorPaletteMorph;
ColorPaletteMorph.uber = Morph.prototype;
// ColorPaletteMorph instance creation:
function ColorPaletteMorph(target, sizePoint) {
this.init(
target || null,
sizePoint || new Point(80, 50)
);
}
ColorPaletteMorph.prototype.init = function (target, size) {
ColorPaletteMorph.uber.init.call(this);
this.isCachingImage = true;
this.target = target;
this.targetSetter = 'color';
this.setExtent(size);
this.choice = null;
this.rerender();
};
ColorPaletteMorph.prototype.render = function (context) {
var ext, x, y, h, l, colors;
ext = this.extent();
this.choice = new Color();
colors = ['rgb(0, 0,0)', //black
'rgb(128, 128, 128)', //gray
'rgb(192, 192, 192)', //silver
'rgb(255, 255, 255)', //white
'rgb(139, 69, 19)', //saddlebrown
'rgb(128, 0, 0)', //maroon
'rgb(255, 0, 0)', //red
'rgb(255, 192, 203)', //pink
'rgb(255, 165, 0)', //orange
'rgb(210, 105, 30)', //chocolate
'rgb(255, 255, 0)', //yellow
'rgb(128, 128, 0)', //olive
'rgb(0, 255, 0)', //lime
'rgb(0, 128, 0)', //green
'rgb(0, 255, 255)', //aqua
'rgb(0, 128, 128)', //teal
'rgb(0, 0, 255)', //blue
'rgb(0, 0, 128)', //navy
'rgb(128, 0, 128)', //purple
'rgb(255, 0, 255)' //magenta
];
// HSL palette (with saturation = 100%)
for (x = 0; x <= ext.x; x++) {
h = 360 * x / ext.x;
for (y = 0; y <= ext.y - 30; y++) {
l = 100 - (y / (ext.y - 30) * 100);
context.fillStyle = 'hsl(' + h + ',100%,' + l + '%)';
context.fillRect(x, y, 1, 1);
}
}
// Gray scale
for (x = 0; x <= ext.x; x++) {
l = 100 - (x/ ext.x * 100);
context.fillStyle = 'hsl(0, 0%, ' + l + '%)';
context.fillRect(x, ext.y - 30, 1, 10);
}
// 20 colors palette (two rows)
for (x = 0; x < 20; x++) {
context.fillStyle = colors[x];
if (x % 2 == 0) {
context.fillRect((x / 2) * ext.x / 10, ext.y - 20, ext.x / 10, 10);
} else {
context.fillRect((Math.round(x / 2) - 1) * ext.x / 10, ext.y - 10, ext.x / 10, 10);
}
}
};
ColorPaletteMorph.prototype.mouseMove = function (pos) {
this.choice = this.getPixelColor(pos);
this.updateTarget();
};
ColorPaletteMorph.prototype.mouseDownLeft = function (pos) {
this.choice = this.getPixelColor(pos);
this.updateTarget();
};
ColorPaletteMorph.prototype.updateTarget = function () {
if (this.target instanceof Morph && this.choice !== null) {
if (this.target[this.targetSetter] instanceof Function) {
this.target[this.targetSetter](this.choice);
} else {
this.target[this.targetSetter] = this.choice;
this.target.rerender();
this.target.changed();
}
}
};
// ColorPaletteMorph menu:
ColorPaletteMorph.prototype.developersMenu = function () {
var menu = ColorPaletteMorph.uber.developersMenu.call(this);
menu.addLine();
menu.addItem(
'set target',
"setTarget",
'choose another morph\nwhose color property\n will be' +
' controlled by this one'
);
return menu;
};
ColorPaletteMorph.prototype.setTarget = function () {
var choices = this.overlappedMorphs(),
menu = new MenuMorph(this, 'choose target:'),
myself = this;
choices.push(this.world());
choices.forEach(function (each) {
menu.addItem(each.toString().slice(0, 50), function () {
myself.target = each;
myself.setTargetSetter();
});
});
if (choices.length === 1) {
this.target = choices[0];
this.setTargetSetter();
} else if (choices.length > 0) {
menu.popUpAtHand(this.world());
}
};
ColorPaletteMorph.prototype.setTargetSetter = function () {
var choices = this.target.colorSetters(),
menu = new MenuMorph(this, 'choose target property:'),
myself = this;
choices.forEach(function (each) {
menu.addItem(each, function () {
myself.targetSetter = each;
});
});
if (choices.length === 1) {
this.targetSetter = choices[0];
} else if (choices.length > 0) {
menu.popUpAtHand(this.world());
}
};
// Hue Wheel
//
// from Bernat / BeetleBlocks
var HueWheelMorph;
// ColorPaletteMorph inherits from Morph:
HueWheelMorph.prototype = new ColorPaletteMorph();
HueWheelMorph.prototype.constructor = HueWheelMorph;
HueWheelMorph.uber = ColorPaletteMorph.prototype;
// ColorPaletteMorph instance creation:
function HueWheelMorph(target, sizePoint) {
this.init(
target || null,
sizePoint || new Point(80, 50)
);
};
HueWheelMorph.prototype.render = function (context) {
var ext, x, y, radius;
ext = this.extent();
console.log(context, ext);
this.choice = new Color();
x = this.getImage().width / 2 + 2;
y = this.size / 2;
radius = this.image.width / 2 - 22;
context.font = '9px Arial';
context.fillStyle = 'rgb(200,200,200)';
context.fillRect(0, 0, this.getImage().width, this.getImage().height);
context.strokeRect(0, 0, this.getImage().width, this.getImage().height);
context.textAlign = 'center';
context.textBaseline = 'middle';
for (var angle = 360; angle > 0; angle --) {
var startAngle = (angle - 1) * Math.PI/180;
var endAngle = (angle + 1) * Math.PI/180;
context.beginPath();
context.moveTo(x, y);
context.arc(x, y, radius, startAngle, endAngle, false);
context.closePath();
context.fillStyle = 'hsl(' + angle + ', 100%, 50%)';
context.fill();
if (angle % 30 == 0) {
var tx = x + (radius + 12) * Math.cos(radians(angle)),
ty = y + (radius + 12) * Math.sin(radians(angle));
context.fillStyle = 'rgb(10,10,10)';
if (angle % 90 == 0) {
context.fillText(angle % 360 + '°', tx, ty);
} else {
context.beginPath()
context.moveTo(tx, ty);
context.lineTo(tx + 5 * Math.cos(radians(angle)), ty + 5 * Math.sin(radians(angle)));
context.stroke();
}
}
}
};
WorldMorph.prototype.updateBroken = function () {
var ctx = this.worldCanvas.getContext('2d'),
i,ide,stage,bounds;
for (i = 0; i < this.children.length; i += 1) {
if (this.children[i] instanceof IDE_Morph) {
ide = this.children[i];
stage = ide.stage;
bounds = stage.bounds;
}
}
this.condenseDamages();
this.broken.forEach(rect => {
if (rect.extent().gt(ZERO)) {
this.fullDrawOn(ctx, rect);
}
});
if (ide) {
if ( this.broken.some(area => area.intersect(bounds).area() > 0)) {
stage.reRender();
}
}
this.broken = [];
};