Canvas 创建为圆形的EaselJS图像

Canvas 创建为圆形的EaselJS图像,canvas,html5-canvas,createjs,easeljs,Canvas,Html5 Canvas,Createjs,Easeljs,我正在努力使画架上的图像变成圆形 基本上,我在EaselJS中寻找与CSS3相当的边界半径,但找不到解决方案 最接近这一点的是创建一个圆形,并向其添加一个BitmapFill。。。我看到的问题是位图填充卡在圆形状后面的(0,0)x/y位置,当我将形状移动到图像大小以外的任何位置时,位图不会跟随(或捕捉)形状并随之移动 检查我的 如果将圆x位置更改为50,它看起来很正常。。。但请注意,将圆从(50,50)x/y位置进一步移动,会使位图落后,而不是跟随 有关我的HTML/CSS/Javascrip

我正在努力使画架上的图像变成圆形

基本上,我在EaselJS中寻找与CSS3相当的
边界半径
,但找不到解决方案

最接近这一点的是创建一个圆形,并向其添加一个
BitmapFill
。。。我看到的问题是
位图填充
卡在圆形状后面的
(0,0)
x/y位置,当我将形状移动到图像大小以外的任何位置时,
位图
不会跟随(或捕捉)形状并随之移动


检查我的

如果将圆x位置更改为
50
,它看起来很正常。。。但请注意,将圆从
(50,50)
x/y位置进一步移动,会使
位图
落后,而不是跟随

有关我的HTML/CSS/Javascript在小提琴中的外观,请参见下文:

HTML:

<!-- CreateJS CDN -->
<script src="https://code.createjs.com/createjs-2015.11.26.min.js"></script>
<canvas id="stage-canvas" width="300" height="300">
  This web browser does not support canvas.
</canvas>
canvas {
  background-color: #FFF;
  display: block;
}
// Self running function (once page loads)
(function(){
  // preload image assets first with preloadJS
  // used from example here: http://createjs.com/docs/preloadjs/modules/PreloadJS.html
  var queue = new createjs.LoadQueue();
  queue.on("complete", loaded, this);
  queue.loadManifest([
     {id: "poke", src:"https://upload.wikimedia.org/wikipedia/en/f/f1/Bulbasaur_pokemon_red.png"}
  ]);

  // once images above preloaded, run this function:
  function loaded() {
    // Init Stage
    var stage = new createjs.Stage("stage-canvas")

    // Create Background
    var bg1 = new createjs.Shape()
    bg1.graphics.beginFill("ghostwhite") // first bg is white
    bg1.graphics.drawRect(
      0,                    // x position
      0,                    // y position
      stage.canvas.width,   // width of shape (in px)
      stage.canvas.height   // height of shape (in px)
    )
    // Can only define this after shape is drawn, else no fill applies
    bg1.graphics.ef()    // short for endFill()
    stage.addChild(bg1)  // Add Child to Stage

    // trying to create image to be circlular
    // this will add it as the background-image to a circle
    // but I'm having problems getting it to "snap" to the circle
    // instead of stuck at (0, 0) x/y position behind circle...?
    var circle = new createjs.Shape()
    circle.graphics.beginBitmapFill(
      queue.getResult("poke"), // image to be used as fill
      "no-repeat" // image repeating or not
    )
    circle.graphics.drawCircle(
      150, // x position
      50, // y position
      50 // diameter (in px)
    )
    stage.addChild(circle)

    stage.update()
    }
})()
var circle = new createjs.Shape()
circle.graphics.beginBitmapFill(
  queue.getResult("poke"), // image to be used as fill
  "no-repeat" // image repeating or not
)
circle.graphics.drawCircle(
  150, // x position
  50, // y position
  50 // diameter (in px)
)
stage.addChild(circle)
var circle = new createjs.Shape()
circle.graphics.beginBitmapFill(
  queue.getResult("poke"), // image to be used as fill
  "no-repeat" // image repeating or not
)
circle.graphics.drawCircle(
  50, // x position
  50, // y position
  50 // diameter (in px)
)
// Create a container for the circle
var container = new createjs.Container()
container.x = 150
container.y = 150
container.addChild(circle) // add circle to container
stage.addChild(container) // then add container to stage
Javascript:

<!-- CreateJS CDN -->
<script src="https://code.createjs.com/createjs-2015.11.26.min.js"></script>
<canvas id="stage-canvas" width="300" height="300">
  This web browser does not support canvas.
</canvas>
canvas {
  background-color: #FFF;
  display: block;
}
// Self running function (once page loads)
(function(){
  // preload image assets first with preloadJS
  // used from example here: http://createjs.com/docs/preloadjs/modules/PreloadJS.html
  var queue = new createjs.LoadQueue();
  queue.on("complete", loaded, this);
  queue.loadManifest([
     {id: "poke", src:"https://upload.wikimedia.org/wikipedia/en/f/f1/Bulbasaur_pokemon_red.png"}
  ]);

  // once images above preloaded, run this function:
  function loaded() {
    // Init Stage
    var stage = new createjs.Stage("stage-canvas")

    // Create Background
    var bg1 = new createjs.Shape()
    bg1.graphics.beginFill("ghostwhite") // first bg is white
    bg1.graphics.drawRect(
      0,                    // x position
      0,                    // y position
      stage.canvas.width,   // width of shape (in px)
      stage.canvas.height   // height of shape (in px)
    )
    // Can only define this after shape is drawn, else no fill applies
    bg1.graphics.ef()    // short for endFill()
    stage.addChild(bg1)  // Add Child to Stage

    // trying to create image to be circlular
    // this will add it as the background-image to a circle
    // but I'm having problems getting it to "snap" to the circle
    // instead of stuck at (0, 0) x/y position behind circle...?
    var circle = new createjs.Shape()
    circle.graphics.beginBitmapFill(
      queue.getResult("poke"), // image to be used as fill
      "no-repeat" // image repeating or not
    )
    circle.graphics.drawCircle(
      150, // x position
      50, // y position
      50 // diameter (in px)
    )
    stage.addChild(circle)

    stage.update()
    }
})()
var circle = new createjs.Shape()
circle.graphics.beginBitmapFill(
  queue.getResult("poke"), // image to be used as fill
  "no-repeat" // image repeating or not
)
circle.graphics.drawCircle(
  150, // x position
  50, // y position
  50 // diameter (in px)
)
stage.addChild(circle)
var circle = new createjs.Shape()
circle.graphics.beginBitmapFill(
  queue.getResult("poke"), // image to be used as fill
  "no-repeat" // image repeating or not
)
circle.graphics.drawCircle(
  50, // x position
  50, // y position
  50 // diameter (in px)
)
// Create a container for the circle
var container = new createjs.Container()
container.x = 150
container.y = 150
container.addChild(circle) // add circle to container
stage.addChild(container) // then add container to stage
提前感谢您帮助我找出如何修复代码,或者如果我在这里走错了路



更新:我最初问这个问题是因为做了一个圆形图像,或者是一个圆角图像。我真的只需要圆形图像方法,因为提供的答案仅针对这一点,所以我删除了我的问题,同时要求提供圆角解决方案。

将圆形形状放入容器中,然后将容器移动到需要的位置。这是我目前找到的唯一选项:

更改此选项:

<!-- CreateJS CDN -->
<script src="https://code.createjs.com/createjs-2015.11.26.min.js"></script>
<canvas id="stage-canvas" width="300" height="300">
  This web browser does not support canvas.
</canvas>
canvas {
  background-color: #FFF;
  display: block;
}
// Self running function (once page loads)
(function(){
  // preload image assets first with preloadJS
  // used from example here: http://createjs.com/docs/preloadjs/modules/PreloadJS.html
  var queue = new createjs.LoadQueue();
  queue.on("complete", loaded, this);
  queue.loadManifest([
     {id: "poke", src:"https://upload.wikimedia.org/wikipedia/en/f/f1/Bulbasaur_pokemon_red.png"}
  ]);

  // once images above preloaded, run this function:
  function loaded() {
    // Init Stage
    var stage = new createjs.Stage("stage-canvas")

    // Create Background
    var bg1 = new createjs.Shape()
    bg1.graphics.beginFill("ghostwhite") // first bg is white
    bg1.graphics.drawRect(
      0,                    // x position
      0,                    // y position
      stage.canvas.width,   // width of shape (in px)
      stage.canvas.height   // height of shape (in px)
    )
    // Can only define this after shape is drawn, else no fill applies
    bg1.graphics.ef()    // short for endFill()
    stage.addChild(bg1)  // Add Child to Stage

    // trying to create image to be circlular
    // this will add it as the background-image to a circle
    // but I'm having problems getting it to "snap" to the circle
    // instead of stuck at (0, 0) x/y position behind circle...?
    var circle = new createjs.Shape()
    circle.graphics.beginBitmapFill(
      queue.getResult("poke"), // image to be used as fill
      "no-repeat" // image repeating or not
    )
    circle.graphics.drawCircle(
      150, // x position
      50, // y position
      50 // diameter (in px)
    )
    stage.addChild(circle)

    stage.update()
    }
})()
var circle = new createjs.Shape()
circle.graphics.beginBitmapFill(
  queue.getResult("poke"), // image to be used as fill
  "no-repeat" // image repeating or not
)
circle.graphics.drawCircle(
  150, // x position
  50, // y position
  50 // diameter (in px)
)
stage.addChild(circle)
var circle = new createjs.Shape()
circle.graphics.beginBitmapFill(
  queue.getResult("poke"), // image to be used as fill
  "no-repeat" // image repeating or not
)
circle.graphics.drawCircle(
  50, // x position
  50, // y position
  50 // diameter (in px)
)
// Create a container for the circle
var container = new createjs.Container()
container.x = 150
container.y = 150
container.addChild(circle) // add circle to container
stage.addChild(container) // then add container to stage
对此:

<!-- CreateJS CDN -->
<script src="https://code.createjs.com/createjs-2015.11.26.min.js"></script>
<canvas id="stage-canvas" width="300" height="300">
  This web browser does not support canvas.
</canvas>
canvas {
  background-color: #FFF;
  display: block;
}
// Self running function (once page loads)
(function(){
  // preload image assets first with preloadJS
  // used from example here: http://createjs.com/docs/preloadjs/modules/PreloadJS.html
  var queue = new createjs.LoadQueue();
  queue.on("complete", loaded, this);
  queue.loadManifest([
     {id: "poke", src:"https://upload.wikimedia.org/wikipedia/en/f/f1/Bulbasaur_pokemon_red.png"}
  ]);

  // once images above preloaded, run this function:
  function loaded() {
    // Init Stage
    var stage = new createjs.Stage("stage-canvas")

    // Create Background
    var bg1 = new createjs.Shape()
    bg1.graphics.beginFill("ghostwhite") // first bg is white
    bg1.graphics.drawRect(
      0,                    // x position
      0,                    // y position
      stage.canvas.width,   // width of shape (in px)
      stage.canvas.height   // height of shape (in px)
    )
    // Can only define this after shape is drawn, else no fill applies
    bg1.graphics.ef()    // short for endFill()
    stage.addChild(bg1)  // Add Child to Stage

    // trying to create image to be circlular
    // this will add it as the background-image to a circle
    // but I'm having problems getting it to "snap" to the circle
    // instead of stuck at (0, 0) x/y position behind circle...?
    var circle = new createjs.Shape()
    circle.graphics.beginBitmapFill(
      queue.getResult("poke"), // image to be used as fill
      "no-repeat" // image repeating or not
    )
    circle.graphics.drawCircle(
      150, // x position
      50, // y position
      50 // diameter (in px)
    )
    stage.addChild(circle)

    stage.update()
    }
})()
var circle = new createjs.Shape()
circle.graphics.beginBitmapFill(
  queue.getResult("poke"), // image to be used as fill
  "no-repeat" // image repeating or not
)
circle.graphics.drawCircle(
  150, // x position
  50, // y position
  50 // diameter (in px)
)
stage.addChild(circle)
var circle = new createjs.Shape()
circle.graphics.beginBitmapFill(
  queue.getResult("poke"), // image to be used as fill
  "no-repeat" // image repeating or not
)
circle.graphics.drawCircle(
  50, // x position
  50, // y position
  50 // diameter (in px)
)
// Create a container for the circle
var container = new createjs.Container()
container.x = 150
container.y = 150
container.addChild(circle) // add circle to container
stage.addChild(container) // then add container to stage

将圆形状放入容器中,然后将容器移动到需要的位置。这是我目前找到的唯一选项:

更改此选项:

<!-- CreateJS CDN -->
<script src="https://code.createjs.com/createjs-2015.11.26.min.js"></script>
<canvas id="stage-canvas" width="300" height="300">
  This web browser does not support canvas.
</canvas>
canvas {
  background-color: #FFF;
  display: block;
}
// Self running function (once page loads)
(function(){
  // preload image assets first with preloadJS
  // used from example here: http://createjs.com/docs/preloadjs/modules/PreloadJS.html
  var queue = new createjs.LoadQueue();
  queue.on("complete", loaded, this);
  queue.loadManifest([
     {id: "poke", src:"https://upload.wikimedia.org/wikipedia/en/f/f1/Bulbasaur_pokemon_red.png"}
  ]);

  // once images above preloaded, run this function:
  function loaded() {
    // Init Stage
    var stage = new createjs.Stage("stage-canvas")

    // Create Background
    var bg1 = new createjs.Shape()
    bg1.graphics.beginFill("ghostwhite") // first bg is white
    bg1.graphics.drawRect(
      0,                    // x position
      0,                    // y position
      stage.canvas.width,   // width of shape (in px)
      stage.canvas.height   // height of shape (in px)
    )
    // Can only define this after shape is drawn, else no fill applies
    bg1.graphics.ef()    // short for endFill()
    stage.addChild(bg1)  // Add Child to Stage

    // trying to create image to be circlular
    // this will add it as the background-image to a circle
    // but I'm having problems getting it to "snap" to the circle
    // instead of stuck at (0, 0) x/y position behind circle...?
    var circle = new createjs.Shape()
    circle.graphics.beginBitmapFill(
      queue.getResult("poke"), // image to be used as fill
      "no-repeat" // image repeating or not
    )
    circle.graphics.drawCircle(
      150, // x position
      50, // y position
      50 // diameter (in px)
    )
    stage.addChild(circle)

    stage.update()
    }
})()
var circle = new createjs.Shape()
circle.graphics.beginBitmapFill(
  queue.getResult("poke"), // image to be used as fill
  "no-repeat" // image repeating or not
)
circle.graphics.drawCircle(
  150, // x position
  50, // y position
  50 // diameter (in px)
)
stage.addChild(circle)
var circle = new createjs.Shape()
circle.graphics.beginBitmapFill(
  queue.getResult("poke"), // image to be used as fill
  "no-repeat" // image repeating or not
)
circle.graphics.drawCircle(
  50, // x position
  50, // y position
  50 // diameter (in px)
)
// Create a container for the circle
var container = new createjs.Container()
container.x = 150
container.y = 150
container.addChild(circle) // add circle to container
stage.addChild(container) // then add container to stage
对此:

<!-- CreateJS CDN -->
<script src="https://code.createjs.com/createjs-2015.11.26.min.js"></script>
<canvas id="stage-canvas" width="300" height="300">
  This web browser does not support canvas.
</canvas>
canvas {
  background-color: #FFF;
  display: block;
}
// Self running function (once page loads)
(function(){
  // preload image assets first with preloadJS
  // used from example here: http://createjs.com/docs/preloadjs/modules/PreloadJS.html
  var queue = new createjs.LoadQueue();
  queue.on("complete", loaded, this);
  queue.loadManifest([
     {id: "poke", src:"https://upload.wikimedia.org/wikipedia/en/f/f1/Bulbasaur_pokemon_red.png"}
  ]);

  // once images above preloaded, run this function:
  function loaded() {
    // Init Stage
    var stage = new createjs.Stage("stage-canvas")

    // Create Background
    var bg1 = new createjs.Shape()
    bg1.graphics.beginFill("ghostwhite") // first bg is white
    bg1.graphics.drawRect(
      0,                    // x position
      0,                    // y position
      stage.canvas.width,   // width of shape (in px)
      stage.canvas.height   // height of shape (in px)
    )
    // Can only define this after shape is drawn, else no fill applies
    bg1.graphics.ef()    // short for endFill()
    stage.addChild(bg1)  // Add Child to Stage

    // trying to create image to be circlular
    // this will add it as the background-image to a circle
    // but I'm having problems getting it to "snap" to the circle
    // instead of stuck at (0, 0) x/y position behind circle...?
    var circle = new createjs.Shape()
    circle.graphics.beginBitmapFill(
      queue.getResult("poke"), // image to be used as fill
      "no-repeat" // image repeating or not
    )
    circle.graphics.drawCircle(
      150, // x position
      50, // y position
      50 // diameter (in px)
    )
    stage.addChild(circle)

    stage.update()
    }
})()
var circle = new createjs.Shape()
circle.graphics.beginBitmapFill(
  queue.getResult("poke"), // image to be used as fill
  "no-repeat" // image repeating or not
)
circle.graphics.drawCircle(
  150, // x position
  50, // y position
  50 // diameter (in px)
)
stage.addChild(circle)
var circle = new createjs.Shape()
circle.graphics.beginBitmapFill(
  queue.getResult("poke"), // image to be used as fill
  "no-repeat" // image repeating or not
)
circle.graphics.drawCircle(
  50, // x position
  50, // y position
  50 // diameter (in px)
)
// Create a container for the circle
var container = new createjs.Container()
container.x = 150
container.y = 150
container.addChild(circle) // add circle to container
stage.addChild(container) // then add container to stage

您可以在
位图上使用
掩码
属性()实现圆角

var stage = new createjs.Stage(document.getElementById('canvas'));

var img = new Image();
img.onload = function() {
    var container = new createjs.Container();

    var bitmap = new createjs.Bitmap(img);
    bitmap.regX = bitmap.regY = 150;
    bitmap.y = bitmap.x = 150;

    var maskShape = new createjs.Shape(new createjs.Graphics().f("#000").drawCircle(150,150,150));
    bitmap.mask = maskShape;

    container.addChild(bitmap);

    stage.addChild(container);
    stage.update();

    container.x = container.y = 50;

    stage.update();
};
img.src = '//unsplash.it/300/300';

编辑
正如Lanny所提到的,mask
使用Canvas
clip
方法,因此不会在Chrome中进行抗锯齿(open bug)。如果您需要在Chrome中进行抗锯齿处理,您可以使用compositeOperation来解决问题,请检查更新的JSFIDLE:

您可以使用
位图上的
掩码
属性()来实现圆角

var stage = new createjs.Stage(document.getElementById('canvas'));

var img = new Image();
img.onload = function() {
    var container = new createjs.Container();

    var bitmap = new createjs.Bitmap(img);
    bitmap.regX = bitmap.regY = 150;
    bitmap.y = bitmap.x = 150;

    var maskShape = new createjs.Shape(new createjs.Graphics().f("#000").drawCircle(150,150,150));
    bitmap.mask = maskShape;

    container.addChild(bitmap);

    stage.addChild(container);
    stage.update();

    container.x = container.y = 50;

    stage.update();
};
img.src = '//unsplash.it/300/300';

编辑
正如Lanny所提到的,mask
使用Canvas
clip
方法,因此不会在Chrome中进行抗锯齿(open bug)。如果您需要在Chrome中进行抗锯齿处理,可以使用compositeOperation进行解决,请检查更新的JSFIDLE:

我建议将圆居中,并使用矩阵将位图填充居中

// Create a matrix
var matrix = new createjs.Matrix2D()
    .translate(-160/2, -144/2); // Move to 50% the width and height of the image

circle.graphics.beginBitmapFill(
  queue.getResult("poke"), // image to be used as fill
  "no-repeat",
  matrix // Pass in the matrix
);

// Draw the circle at 0,0
circle.graphics.drawCircle(
  0, // x position
  0, // y position
  50 // diameter (in px)
);

// Move it to wherever you want
circle.x = 100;
circle.y = 100;
这里是一个更新的小提琴:


您还可以缩放矩阵,使图像与圆圈相匹配。

我建议将圆圈居中,并使用矩阵将位图填充居中

// Create a matrix
var matrix = new createjs.Matrix2D()
    .translate(-160/2, -144/2); // Move to 50% the width and height of the image

circle.graphics.beginBitmapFill(
  queue.getResult("poke"), // image to be used as fill
  "no-repeat",
  matrix // Pass in the matrix
);

// Draw the circle at 0,0
circle.graphics.drawCircle(
  0, // x position
  0, // y position
  50 // diameter (in px)
);

// Move it to wherever you want
circle.x = 100;
circle.y = 100;
这里是一个更新的小提琴:


您还可以缩放矩阵,使图像与圆圈相匹配。

遮罩很棒(而且性能最好),但是请注意,它不会在Chrome中进行抗锯齿处理。位图填充方法解决了这个问题。我确实更喜欢这种掩码方法,但这仍然会导致我在尝试移动x/y位置时遇到的相同问题:。你知道如何同时修复@derz吗?同样@derz,你的JSFIDLE需要更新以匹配上面的代码:)(还要添加createjs脚本include以便工作)我已经更新了你的FIDLE(并更正了链接;-))。但是我不确定,为什么遮罩不是相对于位图的-我想应该是这样的@Lanny,我错了吗?还有一个在Chrome中获得抗锯齿功能的更新:但是我也不确定这里,什么更快-使用复合操作解决方案或bitmapFill。也许@Lanny做了一些性能测试?Mask很棒(也是性能最好的),但是请注意,它不会在Chrome中进行抗锯齿处理。位图填充方法解决了这个问题。我确实更喜欢这种掩码方法,但这仍然会导致我在尝试移动x/y位置时遇到的相同问题:。你知道如何同时修复@derz吗?同样@derz,你的JSFIDLE需要更新以匹配上面的代码:)(还要添加createjs脚本include以便工作)我已经更新了你的FIDLE(并更正了链接;-))。但是我不确定,为什么遮罩不是相对于位图的-我想应该是这样的@Lanny,我错了吗?还有一个在Chrome中获得抗锯齿功能的更新:但是我也不确定这里,什么更快-使用复合操作解决方案或bitmapFill。也许@Lanny做了一些性能测试?谢谢@Lanny,我想知道矩阵到底为我们做了什么?你能解释一下吗?(我相当数学赤字:P)我不明白“只是解决了这个问题”是怎么回事?矩阵只是告诉填充按特定量进行变换(缩放、旋转、平移)。因为您只想移动(平移)坐标,所以我使用了
translate
方法,将其移动到图像宽度和高度的一半(-w/2,-h/2)。希望能有帮助。谢谢@Lanny,我正在努力了解矩阵到底为我们做了什么?你能解释一下吗?(我相当数学赤字:P)我不明白“只是解决了这个问题”是怎么回事?矩阵只是告诉填充按特定量进行变换(缩放、旋转、平移)。因为您只想移动(平移)坐标,所以我使用了
translate
方法,将其移动到图像宽度和高度的一半(-w/2,-h/2)。希望有帮助。