html5 - color - CreateJS Gradiente radial con matriz
radial gradient() (2)
Estoy convirtiendo una aplicación Flash en HTML5 Canvas. La mayor parte del desarrollo está terminado, pero para manejar los colores hay un código como este en la aplicación flash:
matrix = new Matrix ();
matrix.createGradientBox (600, ColorHeight * 1200, 0, 80, ColorHeight * -600);
Animation_gradient_mc.clear ();
Animation_gradient_mc.beginGradientFill (fillType, colors, alphas, ratios, matrix, spreadMethod, interpolationMethod, focalPointRatio);
La declaración de gradiente radial en CreateJS es la siguiente:
beginRadialGradientFill(colors, ratios, x0, y0, r0, x1, y1, r1 )
¿Alguien sabe un método para aplicar una Matriz a un relleno de degradado?
Cualquier ayuda sería apreciada.
Gracias por adelantado
Editar
Aquí hay algunos ejemplos del gradiente que trato de reproducir:
Como puede ver, comienza como un degradado radial estándar.
Sin embargo, también puede parecer estirado, creo que aquí es donde la matriz ayuda.
Intenté crear el mismo efecto creando un createjs.Graphics.Fill con una matriz pero no parece estar haciendo nada:
var matrix = new VacpMatrix();
matrix.createGradientBox(
600,
discharge_gradient.color_height * 1200,
0,
80,
discharge_gradient.color_height * -600
);
// test_graphics.append(new createjs.Graphics.Fill(''#0000ff'', matrix));
console.log(''matrix'', matrix);
test_graphics.append(new createjs.Graphics.Fill(''#ff0000'', matrix).radialGradient(
discharge_gradient.colors,
discharge_gradient.ratios,
discharge_gradient.x0,
discharge_gradient.y0,
discharge_gradient.r0,
discharge_gradient.x1,
discharge_gradient.y1,
discharge_gradient.r1
));
var discharge_shape = new createjs.Shape(test_graphics);
Extendí la clase Matrix2d para agregar un método createGradientBox usando el código del proyecto openfl:
p.createGradientBox = function (width, height, rotation, tx, ty) {
if (_.isUndefined(rotation) || _.isNull(rotation)) {
rotation = 0;
}
if (_.isUndefined(tx) || _.isNull(tx)) {
tx = 0;
}
if (_.isUndefined(ty) || _.isNull(ty)) {
ty = 0;
}
var a = width / 1638.4,
d = height / 1638.4;
// Rotation is clockwise
if (rotation != 0) {
var cos = math.cos(rotation),
sin = math.sin(rotation);
this.b = sin * d;
this.c = -sin * a;
this.a = a * cos;
this.d = d * cos;
} else {
this.b = 0;
this.c = 0;
}
this.tx = tx + width / 2;
this.ty = ty + height / 2;
}
Espero que la información adicional sea útil.
Una matriz estándar ajustaría las entradas:
Width, angle Horizontal, angle Vertical, Height, pos X, pos Y
en ese orden,
Aquí está usando gradientBox que no es el tipo habitual de matriz AS3. Entrada esperada:
Width, Height, Rotation, pos X, pos Y
No uso createJS, así que voy a adivinar esto (construyes sobre él) ...
Su usual beginRadialGradientFill(colors, ratios, x0, y0, r0, x1, y1, r1 )
se vuelve como a continuación (como si la matriz gradientBox está involucrada):
beginRadialGradientFill(colors, ratios, posX, posY, Rotation, Width, Height, Rotation )
No sé crear lo suficiente, ni el objeto Flash Matrix
, pero para hacer este tipo de ovalGradient con la API Canvas2d nativa, necesitarás transformar la matriz del contexto.
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var horizontalScale = .3;
var verticalScale = 1;
var gradient = ctx.createRadialGradient(100/horizontalScale, 100/verticalScale, 100, 100/horizontalScale,100/verticalScale,0);
gradient.addColorStop(0,"green");
gradient.addColorStop(1,"red");
// shrink the context''s matrix
ctx.scale(horizontalScale, verticalScale)
// draw your gradient
ctx.fillStyle = gradient;
// stretch the rectangle which contains the gradient accordingly
ctx.fillRect(0,0, 200/horizontalScale, 200/verticalScale);
// reset the context''s matrix
ctx.setTransform(1,0,0,1,0,0);
canvas{ background-color: ivory;}
<canvas id="canvas" width="200" height="200"></canvas>
Entonces, si planea escribir algún tipo de función para reproducirla, eche un vistazo a ctx.scale()
, ctx.transform()
y ctx.setTransform()
.
EDITAR
Como habrás notado, esto también reducirá tus formas dibujadas, también, tendrás que calcular cuánto debes "deshacer" las del dibujo, tal como lo hice con fillRect
. (de acuerdo, este fue fácil)
Aquí hay una función que podría ayudarte con formas más complicadas. Realmente no lo probé (solo con el ejemplo dado), por lo que puede fallar de alguna manera, pero también puede darte una idea sobre cómo manejarlo:
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
function shrinkedRadial(ctx, shapeArray, xScale, yScale, gradientOpts) {
// scaling by 0 is like not drawing
if (!xScale || !yScale) return;
var gO = gradientOpts;
// apply our scale on the gradient options we passed
var gradient = ctx.createRadialGradient(gO.x0 / xScale, gO.y0 / yScale, gO.r0, gO.x1 / xScale, gO.y1 / yScale, gO.r1);
gradient.addColorStop(gO.c1_pos, gO.c1_fill);
gradient.addColorStop(gO.c2_pos, gO.c2_fill);
// shrink the context''s matrix
ctx.scale(xScale, yScale);
ctx.fillStyle = gradient;
// execute the drawing operations'' string
shapeArray.forEach(function(str) {
var val = str.split('' '');
var op = shapesRef[val[0]];
if (val[1]) {
var pos = val[1].split('','').map(function(v, i) {
// if even, it should be an y axis, otherwise an x one
return i % 2 ? v / yScale : v / xScale;
});
ctx[op].apply(ctx, pos);
} else {
// no parameters
ctx[op]();
}
});
// apply our gradient
ctx.fill();
// reset the transform matrix
ctx.setTransform(1, 0, 0, 1, 0, 0);
}
// just for shortening our shape drawing operations
// notice how arc operations are omitted, it could be implemented but...
var shapesRef = {
b: ''beginPath'',
fR: ''fillRect'',
m: ''moveTo'',
l: ''lineTo'',
bC: ''bezierCurveTo'',
qC: ''quadraticCurveTo'',
r: ''rect'',
c: ''closePath''
};
var gradientOpts = {
x0: 232,
y0: 55,
r0: 70,
x1: 232,
y1: 55,
r1: 0,
c1_fill: ''red'',
c1_pos: 0,
c2_fill: ''green'',
c2_pos: 1
}
var shapes = [''b'', ''m 228,133'', ''bC 209,121,154,76,183,43'', ''bC 199,28,225,34,233,59'', ''bC 239,34,270,29,280,39'', ''bC 317,76,248,124,230,133'']
// our shape is drawn at 150px from the right so we do move the context accordingly, but you won''t have to.
ctx.translate(-150, 0);
shrinkedRadial(ctx, shapes, .3, 1, gradientOpts);
ctx.font = ''15px sans-serif'';
ctx.fillStyle = ''black'';
ctx.fillText(''shrinked radialGradient'', 3, 20);
// how it looks like without scaling :
ctx.translate(50, 0)
var gO = gradientOpts;
var gradient = ctx.createRadialGradient(gO.x0, gO.y0, gO.r0, gO.x1, gO.y1, gO.r1);
gradient.addColorStop(gO.c1_pos, gO.c1_fill);
gradient.addColorStop(gO.c2_pos, gO.c2_fill);
ctx.fillStyle = gradient;
shapes.forEach(function(str) {
var val = str.split('' '');
var op = shapesRef[val[0]];
if (val[1]) {
var pos = val[1].split('','');
ctx[op].apply(ctx, pos);
} else {
ctx[op]();
}
});
ctx.fill();
ctx.font = ''15px sans-serif'';
ctx.fillStyle = ''black'';
ctx.fillText(''normal radialGradient'', 160, 20);
<canvas id="canvas" width="400" height="150"></canvas>