import { Component, Properties } from '@hatiolab/things-scene' import ControlBase, { DIRECTION, INOUT, NODE, PIPELINE } from './base/control-base' const NATURE = { mutable: false, resizable: true, rotatable: false, properties: [ { type: 'select', name: 'messageType', label: 'message-type', property: { options: [ { display: '', value: '' }, { display: 'invalid', value: 'invalid' }, { display: 'guaranteed', value: 'guaranteed' }, { display: 'dead-letter', value: 'dead-letter' } ] } } ], help: '/eipatterns/messaging-channel/messaging-channel' } export default class MessagingChannel extends ControlBase { private imageElement?: HTMLImageElement static get nature() { return NATURE } get nodes(): NODE[] { return [ { name: 'In', description: 'Message inlet', inout: INOUT.IN, type: PIPELINE.MESSAGE, direction: DIRECTION.WEST, multiplicity: 1 }, { name: 'Out', description: 'Message outlet', inout: INOUT.OUT, type: PIPELINE.MESSAGE, direction: DIRECTION.EAST } ] } render(ctx: CanvasRenderingContext2D) { const { left, top, width, height } = this.bounds const rx = Math.abs(height / 12) const ry = Math.abs(height / 8) const startAngle = (Math.PI * 3) / 2 const endAngle = Math.PI / 2 const sy = (height * 3) / 8 const cy = height / 2 const ey = (height * 5) / 8 const isize = (height * 3) / 8 ctx.translate(left, top) ctx.beginPath() ctx.ellipse(width - rx, cy, rx, ry, 0, startAngle, startAngle - Math.PI * 2, true) ctx.lineTo(rx, sy) ctx.ellipse(rx, cy, rx, ry, 0, startAngle, endAngle, true) ctx.lineTo(width - rx, ey) this.drawFill(ctx) this.drawStroke(ctx) ctx.beginPath() const image = this.getImageElement() if (image) { this.drawImage(ctx, image, width / 2 - isize / 2, height - isize, isize, isize) } ctx.translate(-left, -top) } onchange(after: Properties, before: Properties) { if ('messageType' in after || 'strokeStyle' in after) { delete this.imageElement } } getImageElement(): HTMLImageElement | undefined { if (!this.imageElement) { const { messageType, strokeStyle } = this.state if (!messageType) { return } const src = IMAGES[messageType] if (!src) { return } this.imageElement = new Image() this.imageElement.src = 'data:image/svg+xml;charset=UTF-8;base64,' + btoa(src.replace(/{{strokeColor}}/g, strokeStyle)) } return this.imageElement } } Component.register('messaging-channel', MessagingChannel) const IMAGES = { 'dead-letter': ` `, invalid: ` `, guaranteed: ` ` }