html - CreateJS 带矩阵的径向渐变

标签 html flash canvas html5-canvas createjs

我正在将 Flash 应用程序转换为 HTML5 Canvas。大部分开发工作已经完成,但是为了处理颜色,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);

CreateJS 中径向渐变的声明如下:

beginRadialGradientFill(colors, ratios, x0, y0, r0, x1, y1, r1 )

有人知道将矩阵应用于渐变填充的方法吗?

如有任何帮助,我们将不胜感激。

提前致谢

编辑

以下是我尝试重现的渐变的一些示例:

Gradient start

如您所见,它以标准径向渐变开始。

但是,它也可能会显得拉伸(stretch),我认为这是矩阵的帮助所在。

Gradient 2

我试图通过创建一个带有矩阵的 createjs.Graphics.Fill 来创建相同的效果,但它似乎没有做任何事情:

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);

我使用 openfl 项目中的代码扩展了 Matrix2d 类以添加一个 createGradientBox 方法:

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;
}

我希望额外的信息有用。

最佳答案

我对 createJS 和 Flash Matrix 对象的了解不够,但要使用 native Canvas2d API 制作这种椭圆渐变,您需要转换上下文的矩阵。

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>

因此,如果您打算编写某种函数来重现它,请查看 ctx.scale() , ctx.transform()ctx.setTransform() .

编辑

正如您所注意到的,这也会缩小您绘制的形状,而且,您还必须计算在绘图时应该“缩小”多少形状,就像我对 fillRect 所做的那样。 (同意,这个很简单)

这是一个可以帮助您处理更复杂形状的函数。我没有真正测试过它(仅使用给定的示例),所以它可能会以某种方式失败,但它也可以让您了解如何处理它:

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>

关于html - CreateJS 带矩阵的径向渐变,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35542825/

相关文章:

html - 覆盖 Outlook 深色模式按钮背景

html - 当 textsize 很大时,工具提示不显示在 css 中

javascript - 从javascript/jQuery调用Flash AS3函数

flash - ActionScript 3 如何跟踪耗时?

asp.net - 氟TransientAttribute和Linq-to-SQL

javascript - Canvas HTML 中 “Coordinates in pixels” 和 “Coordinates” 之间的区别

javascript - 无法通过 HTML 在屏幕上显示 Canvas

javascript - 没有折叠的相同导航栏

javascript - 带复选框的多选下拉菜单

javascript - HTML5 Canvas — 线条太粗