add shape and image shape

This commit is contained in:
casperlamboo 2017-11-14 17:42:08 +01:00
parent 09f276e26c
commit 15dcddc3c3
3 changed files with 164 additions and 0 deletions

43
src/d2/ImageShape.js Normal file
View File

@ -0,0 +1,43 @@
import { IMAGE_GUIDE_TRANSPARENCY, DESELECT_TRANSPARENCY } from '../constants/d2Constants.js';
import { Surface } from 'cal';
export default class ImageShape extends Surface {
constructor(shapeData) {
super();
this.depth = -1;
this.UID = shapeData.UID;
this.update(shapeData);
this.setOpaque(true);
}
update(newShapeData) {
let changed;
if (!this._shapeData || this._shapeData.transform !== newShapeData.transform) {
changed = true;
this.copyMatrix(newShapeData.transform);
}
if (!this._shapeData || this._shapeData.imageData !== newShapeData.imageData) {
changed = true;
const newImage = newShapeData.imageData;
const image = this._shapeData ? this._shapeData.imageData : {};
if (newImage.width !== image.width || newImage.height !== image.height) {
this.setSize(newImage.width, newImage.height);
this.centerX = newImage.width / 2;
this.centerY = newImage.height / 2;
}
this.context.drawImage(newImage, 0, 0, newImage.width, newImage.height);
}
this._shapeData = newShapeData;
return changed;
}
setOpaque(opaque) {
this.alpha = opaque ? IMAGE_GUIDE_TRANSPARENCY : DESELECT_TRANSPARENCY;
}
}

119
src/d2/Shape.js Normal file
View File

@ -0,0 +1,119 @@
import { shapeToPoints } from '../shape/shapeToPoints.js';
import { shapeChanged } from '../shape/shapeDataUtils.js';
import { Matrix } from 'cal';
import { LINE_WIDTH } from '../constants/d2Constants.js';
import { hexToStyle } from '../utils/colorUtils.js';
import { DESELECT_TRANSPARENCY, FILL_TRANSPARENCY, LINE_TRANSPARENCY } from '../constants/d2Constants.js';
import { PIXEL_RATIO } from '../constants/general.js';
export default class Shape extends Matrix {
constructor(shapeData) {
super();
this.visible = true;
this.active = false;
this.depth = shapeData.height + shapeData.z;
this.color = '';
this.UID = shapeData.UID;
this.update(shapeData);
this.setOpaque(true);
}
update(shapeData) {
let changed = false;
this.depth = shapeData.height + shapeData.z;
if (!this._shapeData || shapeChanged(shapeData, this._shapeData)) {
this.shapes = shapeToPoints(shapeData);
changed = true;
}
if (!this._shapeData || this._shapeData.transform !== shapeData.transform) {
if (shapeData.transform.matrix.some(value => typeof value !== 'number' || isNaN(value))) {
throw new Error(`Cannot update object ${this.UID}: transform contains invalid values.`);
}
this.copyMatrix(shapeData.transform);
changed = true;
}
if (!this._shapeData || this._shapeData.color !== shapeData.color) {
if (typeof shapeData.color !== 'number' || isNaN(shapeData.color)) {
throw new Error(`Cannot update object ${this.UID}: color is an invalid value.`);
}
this.color = hexToStyle(shapeData.color);
changed = true;
}
this._shapeData = shapeData;
return changed;
}
setOpaque(opaque) {
const selectTransparency = this._shapeData.fill ? FILL_TRANSPARENCY : LINE_TRANSPARENCY;
this.alpha = opaque ? selectTransparency : DESELECT_TRANSPARENCY;
}
draw(context, matrix) {
context.beginPath();
for (let i = 0; i < this.shapes.length; i ++) {
const { points, holes } = this.shapes[i];
for (let j = 0; j < points.length; j ++) {
const point = points[j].applyMatrix(matrix);
if (j === 0) {
context.moveTo(point.x, point.y);
} else {
context.lineTo(point.x, point.y);
}
}
for (let j = 0; j < holes.length; j ++) {
const hole = holes[j];
for (let k = 0; k < hole.length; k ++) {
const point = hole[k].applyMatrix(matrix);
if (k === 0) {
context.moveTo(point.x, point.y);
} else {
context.lineTo(point.x, point.y);
}
}
}
}
context.lineCap = 'round';
context.lineJoin = 'round';
const lineWidth = PIXEL_RATIO * LINE_WIDTH;
context.globalAlpha = this.alpha;
if (this._shapeData.fill) {
context.fillStyle = this.color;
context.fill();
context.strokeStyle = 'black';
context.lineWidth = lineWidth / 2.0;
context.stroke();
} else {
const outerLineWidth = lineWidth * this.parent.sx;
const innerLineWidth = outerLineWidth - lineWidth;
context.strokeStyle = 'black';
context.lineWidth = outerLineWidth;
context.stroke();
if (innerLineWidth > 0) {
context.strokeStyle = this.color;
context.lineWidth = innerLineWidth;
context.stroke();
}
}
}
}

View File

@ -1,6 +1,8 @@
import memoize from 'memoizee';
import { Vector } from '@doodle3d/cal';
import { SHAPE_CACHE_LIMIT } from '../constants/general.js';
import ImageShape from '../d2/ImageShape.js';
import Shape from '../d2/Shape.js';
export function shapeChanged(oldShapeData, newShapeData) {
const pointsChanged = oldShapeData.points !== newShapeData.points;