fabricjs 图像加载-等比缩放图像到画布 这篇文章描述了如何进行图像等比缩放,但是加载的图片形状仅限于矩形或者正方形,如果需要显示其他形状,那就需要另寻他法,
效果
代码实现
// 初始化设置画布大小
var canvas = new fabric.Canvas("canvas", {
width: 800,
height: 600,
});
// 椭圆
fabric.Image.fromURL('../public/img/1.jfif',img => {
img.set({
left: 20,
top: 20,
clipPath: new fabric.Ellipse({
rx: 70,
ry: 50,
originX: 'center',
originY: 'center'
})
})
canvas.add(img)
canvas.renderAll()
})
// 圆形
fabric.Image.fromURL('../public/img/2.jfif',img => {
img.set({
left: 300,
top: 20,
clipPath: new fabric.Circle({
radius: 60,
originX: 'center',
originY: 'center',
})
})
canvas.add(img)
canvas.renderAll()
})
// 圆角矩形
fabric.Image.fromURL('../public/img/3.jfif',img => {
img.set({
left: 550,
top: 20,
clipPath: new fabric.Rect({
width:120,
height:100,
rx:20,
ry:20,
originX: 'center',
originY: 'center',
})
})
canvas.add(img)
canvas.renderAll()
})
// 三角形
fabric.Image.fromURL('../public/img/4.jfif',img => {
img.set({
left: 20,
top: 200,
clipPath: new fabric.Triangle({
width: 100, // 底边宽度
height: 100, // 底边到定点的距离
originX: 'center',
originY: 'center',
})
})
canvas.add(img)
canvas.renderAll()
})
// 适用canvas 的原生能力进行裁剪,4.2.0版本不起作用,2.6.0可以达到效果
fabric.Image.fromURL('../public/img/4.jfif',img => {
img.set({
left: 300,
top: 200,
clipTo: function (ctx) {
ctx.arc(0, 0, 60, 0, Math.PI * 2, true);//裁剪圆形
}
})
canvas.add(img)
canvas.renderAll()
})
// 多边形不起作用
fabric.Image.fromURL('../public/img/4.jfif',img => {
img.set({
left: 300,
top: 200,
clipPath:new fabric.Polygon([
{x: 300, y: 200},
{x: 500, y: 320},
{x: 500, y: 400},
{x: 320, y: 380}
],{
backgroundColor:'#cccccc',
opacity:0.6,
stroke:'#6639a6',
strokeWidth:2,
originX: 'center',
originY: 'center'
})
})
console.log(img)
canvas.add(img)
canvas.renderAll()
})
// 线段不起作用
fabric.Image.fromURL('../public/img/4.jfif',img => {
img.set({
left: 550,
top: 200,
clipPath:new fabric.Polyline([
{x:450,y:450},
{x:530,y:450},
{x:450,y:530},
{x:530,y:530},
],{
stroke:'#6639a6',
strokeWidth:2
})
})
canvas.add(img)
canvas.renderAll()
})
// 设置画布的背景
canvas.setBackgroundColor('pink', canvas.renderAll.bind(canvas))
经过测试,矩形,圆形,椭圆,三角形都可以实现裁剪,但是多边形,折线不可以实现裁剪,不知道是不是没有用对方法,有知道的可以滴一下!!!
遗留问题
上面的图片是直接对原图进行裁剪,原图大小204x204, 我们如果将图片换成大图1080x1080,就会发现裁剪位置居中,只能裁剪中间某一部分,无法实现对原图整体裁剪~~~
fabric.Image.fromURL('../public/img/5.jfif',img => {
img.set({
left: 0,
top: 0
})
canvas.add(img)
canvas.renderAll()
})
fabric.Image.fromURL('../public/img/5.jfif',img => {
img.set({
left: 0,
top: 0,
clipPath: new fabric.Circle({
radius:100,
originX: 'center',
originY: 'center'
})
})
canvas2.add(img)
canvas2.renderAll()
})
解决方案
这个就要用到我们这上篇文章中对图片进行等比缩放加载知识,先将原图缩放到画布上然后裁剪
fabric.Image.fromURL('../public/img/5.jfif',img => {
const imgScale = 200 / img.width
img.set({
left: 0,
top: 0,
scaleX:imgScale,
scaleY:imgScale
})
canvas.add(img)
canvas.centerObject(img)
canvas.renderAll()
})
fabric.Image.fromURL('../public/img/5.jfif',img => {
const imgScale = 200 / img.width
img.set({
left: 0,
top: 0,
scaleX:imgScale,
scaleY:imgScale
})
img.clipPath = new fabric.Circle({
radius: 100,
originX: 'center',
originY: 'center'
})
canvas2.add(img)
canvas2.centerObject(img)
canvas2.renderAll()
})
经过上面的代码,我们似乎实现了大图裁剪,但是仔细观察就会发现有bug,我们需要将原图裁剪到为半径为100的圆,会发现只裁剪了中级一小块,和直接裁剪大图的效果一样 ,经过测试,需要将半径设置为原图宽度一半左右,才会显示原图裁剪效果,突然脑子灵光一闪,如果原图宽度一半左右可以显示全图裁剪效果,那么是不是再多写两行代码就能实现~~~~
fabric.Image.fromURL('../public/img/5.jfif',img => {
const imgScale = 200 / img.width
img.set({
left: 0,
top: 0,
scaleX:imgScale,
scaleY:imgScale
})
// 这里可以拿到img的width属性,而且正好是原图的宽
const circleRadius = img.widht / 2
img.clipPath = new fabric.Circle({
// 半径不用设置为固定值,通过circleRadius 动态设置
radius:circleRadius ,
originX: 'center',
originY: 'center'
})
canvas2.add(img)
canvas2.centerObject(img)
canvas2.renderAll()
})