Skip to content

Commit

Permalink
feat: image 添加 radius 属性
Browse files Browse the repository at this point in the history
  • Loading branch information
zengyue committed Mar 2, 2021
1 parent 268f5b4 commit 31ddbc5
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 52 deletions.
42 changes: 16 additions & 26 deletions src/graphic/engine/shape/image.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { isNil } from '../../../util/common';
import Shape from './shape';
import Rect from './rect';

class ImageShape extends Shape {
class ImageShape extends Rect {
_initProperties() {
super._initProperties();
this._attrs.canFill = false;
Expand All @@ -11,15 +11,6 @@ class ImageShape extends Shape {
this._attrs.type = 'image';
}

getDefaultAttrs() {
return {
x: 0,
y: 0,
width: 0,
height: 0
};
}

createPath(context) {
const attrs = this.get('attrs');
const { src } = attrs;
Expand Down Expand Up @@ -49,26 +40,25 @@ class ImageShape extends Shape {
}

drawImage(context, image) {
const attrs = this.get('attrs');
const { x, y, width, height, sx, sy, swidth, sheight } = attrs;
const { attrs, destroyed } = this._attrs;
if (destroyed) {
return;
}
const { x, y, width, height, sx, sy, swidth, sheight, radius } = attrs;
if (radius) {
context.save();
this.createRadiusPath(context, x, y, width, height, radius);
context.clip();
}
if (!isNil(sx) && !isNil(sy) && !isNil(swidth) && !isNil(sheight)) {
context.drawImage(image, sx, sy, swidth, sheight, x, y, width, height);
} else {
context.drawImage(image, x, y, width, height);
}
}

calculateBox() {
const attrs = this.get('attrs');
const { x, y, width, height } = attrs;
// 和rect一样
return {
minX: x,
minY: y,
maxX: x + width,
maxY: y + height
};

if (radius) {
// 因为 save 和 restore 会一定程度上影响绘图性能,所以只在必要是调用
context.restore();
}
}
}

Expand Down
28 changes: 16 additions & 12 deletions src/graphic/engine/shape/rect.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,26 +36,30 @@ class Rect extends Shape {
};
}

createRadiusPath(context, x, y, width, height, radius) {
radius = parseRadius(radius, width, height);
context.moveTo(x + radius[0], y);
context.lineTo(x + width - radius[1], y);
context.arc(x + width - radius[1], y + radius[1], radius[1], -Math.PI / 2, 0, false);
context.lineTo(x + width, y + height - radius[2]);
context.arc(x + width - radius[2], y + height - radius[2], radius[2], 0, Math.PI / 2, false);
context.lineTo(x + radius[3], y + height);
context.arc(x + radius[3], y + height - radius[3], radius[3], Math.PI / 2, Math.PI, false);
context.lineTo(x, y + radius[0]);
context.arc(x + radius[0], y + radius[0], radius[0], Math.PI, Math.PI * 3 / 2, false);
context.closePath();
}

createPath(context) {
const self = this;
const attrs = self.get('attrs');
let { x, y, width, height, radius } = attrs;
const { x, y, width, height, radius } = attrs;

context.beginPath();
if (!radius || !(width * height)) {
context.rect(x, y, width, height);
} else {
radius = parseRadius(radius, width, height);
context.moveTo(x + radius[0], y);
context.lineTo(x + width - radius[1], y);
context.arc(x + width - radius[1], y + radius[1], radius[1], -Math.PI / 2, 0, false);
context.lineTo(x + width, y + height - radius[2]);
context.arc(x + width - radius[2], y + height - radius[2], radius[2], 0, Math.PI / 2, false);
context.lineTo(x + radius[3], y + height);
context.arc(x + radius[3], y + height - radius[3], radius[3], Math.PI / 2, Math.PI, false);
context.lineTo(x, y + radius[0]);
context.arc(x + radius[0], y + radius[0], radius[0], Math.PI, Math.PI * 3 / 2, false);
context.closePath();
this.createRadiusPath(context, x, y, width, radius);
}
}

Expand Down
73 changes: 59 additions & 14 deletions test/unit/graphic/shape/image-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,16 @@ dom.id = 'canvas';
document.body.appendChild(dom);

describe('imageShape', function() {
const canvas = new Canvas({
el: 'canvas',
width: 300,
height: 300,
pixelRatio: 1
}); // 创建 canvas 实例
it('new imageShape', function() {
const canvas = new Canvas({
el: 'canvas',
width: 200,
height: 100
}); // 创建 canvas 实例

const container = canvas.addGroup({
zIndex: 2
}); // canvas 添加一个 group
const container = canvas.addGroup(); // canvas 添加一个 group

const imageShape = container.addShape('image', {
zIndex: 31,
attrs: {
x: 0,
y: 0,
Expand All @@ -33,15 +30,65 @@ describe('imageShape', function() {
}
});

container.sort();
canvas.sort(); // canvas 容器内的元素排序
expect(imageShape.get('loading')).toBe(false);
canvas.draw(); // 绘制
expect(imageShape.get('loading')).toBe(true);
expect(imageShape.get('image')).toBe(null);

container.remove(true);
});

it('image radius', function(done) {
const container = canvas.addGroup();

const src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyBAMAAADsEZWCAAAAG1BMVEXMzMz////r6+vf39/l5eX4+PjY2Njy8vLS0tJvPPLMAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAQUlEQVQ4jWNgGAWjgP6ASdncAEaiAhaGiACmFhCJLsMaIiDAEQEi0WXYEiMCOCJAJIY9KuYGTC0gknpuHwXDGwAA5fsIZw0iYWYAAAAASUVORK5CYII=';

container.addShape('image', {
attrs: {
x: 0,
y: 0,
src,
width: 50,
height: 50,
radius: [ 20, 10, 20 ]
}
});

container.addShape('image', {
attrs: {
x: 100,
y: 100,
src,
width: 50,
height: 50
}
});

canvas.draw();

// 要异步获取
setTimeout(() => {
const context = dom.getContext('2d');

// 第一个image圆角区域
const imageData1 = context.getImageData(0, 0, 1, 1).data;
// 第二个image圆角区域
const imageData2 = context.getImageData(100, 100, 1, 1).data;
expect(imageData1[0]).toBe(0);
expect(imageData1[1]).toBe(0);
expect(imageData1[2]).toBe(0);
expect(imageData1[3]).toBe(0);

expect(imageData2[0]).not.toBe(0);
expect(imageData2[1]).not.toBe(0);
expect(imageData2[2]).not.toBe(0);
expect(imageData2[3]).not.toBe(0);
done();
}, 100);
});
});

describe('chart image shape', () => {
it('chart add imageShape', function() {

const data = [
Expand Down Expand Up @@ -99,6 +146,4 @@ describe('imageShape', function() {


});


});

0 comments on commit 31ddbc5

Please sign in to comment.