Hi,
I have taken the custom-element example and the nyan cat example and managed to add my own image to the pallet and renderer fairly easily.
I can drag and drop my new element ( I am overwriting bpmn:ScriptTask just like the nyan cat example ) and the image displays fine on the canvas in both Firefox and Chrome. However in Safari (Version 12.0.2 (14606.3.4)) the image doesn’t display. The element is there as I can click on it and the options pop up.
I have only changed the CustomPallet and CustomRender files like so
CustomPallet.js
import {
assign
} from 'min-dash';
import Cat from '../cat';
/**
* A palette that allows you to create BPMN _and_ custom elements.
*/
export default function PaletteProvider(palette, create, elementFactory, spaceTool, lassoTool) {
this._create = create;
this._elementFactory = elementFactory;
this._spaceTool = spaceTool;
this._lassoTool = lassoTool;
palette.registerProvider(this);
}
PaletteProvider.$inject = [
'palette',
'create',
'elementFactory',
'spaceTool',
'lassoTool'
];
PaletteProvider.prototype.getPaletteEntries = function(element) {
var actions = {},
create = this._create,
elementFactory = this._elementFactory,
spaceTool = this._spaceTool,
lassoTool = this._lassoTool;
function startCreate(event) {
var ScriptTaskShape = elementFactory.create(
'shape', { type: 'bpmn:ScriptTask' }
);
create.start(event, ScriptTaskShape);
}
function createAction(type, group, className, title, options) {
function createListener(event) {
var shape = elementFactory.createShape(assign({ type: type }, options));
if (options) {
shape.businessObject.di.isExpanded = options.isExpanded;
}
create.start(event, shape);
}
var shortType = type.replace(/^bpmn:/, '');
return {
group: group,
className: className,
title: title || 'Create ' + shortType,
action: {
dragstart: createListener,
click: createListener
}
};
}
function createParticipant(event, collapsed) {
create.start(event, elementFactory.createParticipantShape(collapsed));
}
assign(actions, {
'create-script-task': {
group: 'custom',
title: 'MyCat',
imageUrl: Cat.dataURL,
action: {
dragstart: startCreate,
click: startCreate
}
},
'custom-triangle': createAction(
'custom:triangle', 'custom', 'icon-custom-triangle'
),
'custom-circle': createAction(
'custom:circle', 'custom', 'icon-custom-circle'
),
'custom-separator': {
group: 'custom',
separator: true
},
'lasso-tool': {
group: 'tools',
className: 'bpmn-icon-lasso-tool',
title: 'Activate the lasso tool',
action: {
click: function(event) {
lassoTool.activateSelection(event);
}
}
},
'space-tool': {
group: 'tools',
className: 'bpmn-icon-space-tool',
title: 'Activate the create/remove space tool',
action: {
click: function(event) {
spaceTool.activateSelection(event);
}
}
},
'tool-separator': {
group: 'tools',
separator: true
},
'create.start-event': createAction(
'bpmn:StartEvent', 'event', 'bpmn-icon-start-event-none'
),
'create.intermediate-event': createAction(
'bpmn:IntermediateThrowEvent', 'event', 'bpmn-icon-intermediate-event-none'
),
'create.end-event': createAction(
'bpmn:EndEvent', 'event', 'bpmn-icon-end-event-none'
),
'create.exclusive-gateway': createAction(
'bpmn:ExclusiveGateway', 'gateway', 'bpmn-icon-gateway-xor'
),
'create.task': createAction(
'bpmn:Task', 'activity', 'bpmn-icon-task'
),
'create.subprocess-expanded': createAction(
'bpmn:SubProcess', 'activity', 'bpmn-icon-subprocess-expanded', 'Create expanded SubProcess',
{ isExpanded: true }
),
'create.participant-expanded': {
group: 'collaboration',
className: 'bpmn-icon-participant',
title: 'Create Pool/Participant',
action: {
dragstart: createParticipant,
click: createParticipant
}
}
});
return actions;
};
Custom Renderer
import inherits from 'inherits';
import Cat from '../cat';
import BaseRenderer from 'diagram-js/lib/draw/BaseRenderer';
import {
componentsToPath,
createLine
} from 'diagram-js/lib/util/RenderUtil';
import {
append as svgAppend,
attr as svgAttr,
create as svgCreate
} from 'tiny-svg';
/**
* A renderer that knows how to render custom elements.
*/
export default function CustomRenderer(eventBus, styles) {
BaseRenderer.call(this, eventBus, 2000);
var computeStyle = styles.computeStyle;
this.drawTriangle = function(p, side) {
var halfSide = side / 2,
points,
attrs;
points = [ halfSide, 0, side, side, 0, side ];
attrs = computeStyle(attrs, {
stroke: '#3CAA82',
strokeWidth: 2,
fill: '#3CAA82'
});
var polygon = svgCreate('polygon');
svgAttr(polygon, {
points: points
});
svgAttr(polygon, attrs);
svgAppend(p, polygon);
return polygon;
};
this.getTrianglePath = function(element) {
var x = element.x,
y = element.y,
width = element.width,
height = element.height;
var trianglePath = [
['M', x + width / 2, y],
['l', width / 2, height],
['l', -width, 0 ],
['z']
];
return componentsToPath(trianglePath);
};
this.drawCat = function(parent, shape) {
var url = Cat.dataURL;
var catGfx = svgCreate('image', {
x: 0,
y: 0,
width: shape.width,
height: shape.height,
href: url
});
svgAppend(parent, catGfx);
return catGfx;
};
this.drawCircle = function(p, width, height) {
var cx = width / 2,
cy = height / 2;
var attrs = computeStyle(attrs, {
stroke: '#4488aa',
strokeWidth: 4,
fill: 'white'
});
var circle = svgCreate('circle');
svgAttr(circle, {
cx: cx,
cy: cy,
r: Math.round((width + height) / 4)
});
svgAttr(circle, attrs);
svgAppend(p, circle);
return circle;
};
this.getCirclePath = function(shape) {
var cx = shape.x + shape.width / 2,
cy = shape.y + shape.height / 2,
radius = shape.width / 2;
var circlePath = [
['M', cx, cy],
['m', 0, -radius],
['a', radius, radius, 0, 1, 1, 0, 2 * radius],
['a', radius, radius, 0, 1, 1, 0, -2 * radius],
['z']
];
return componentsToPath(circlePath);
};
this.drawCustomConnection = function(p, element) {
var attrs = computeStyle(attrs, {
stroke: '#ff471a',
strokeWidth: 2
});
return svgAppend(p, createLine(element.waypoints, attrs));
};
this.getCustomConnectionPath = function(connection) {
var waypoints = connection.waypoints.map(function(p) {
return p.original || p;
});
var connectionPath = [
['M', waypoints[0].x, waypoints[0].y]
];
waypoints.forEach(function(waypoint, index) {
if (index !== 0) {
connectionPath.push(['L', waypoint.x, waypoint.y]);
}
});
return componentsToPath(connectionPath);
};
}
inherits(CustomRenderer, BaseRenderer);
CustomRenderer.$inject = [ 'eventBus', 'styles' ];
CustomRenderer.prototype.canRender = function(element) {
//return /^custom:/.test(element.type);
return true;
};
CustomRenderer.prototype.drawShape = function(p, element) {
var type = element.type;
if (type === 'custom:triangle') {
return this.drawTriangle(p, element.width);
}
if (type === 'custom:circle') {
return this.drawCircle(p, element.width, element.height);
}
if (type === 'bpmn:ScriptTask') {
return this.drawCat(p, element);
}
};
CustomRenderer.prototype.getShapePath = function(shape) {
var type = shape.type;
if (type === 'custom:triangle') {
return this.getTrianglePath(shape);
}
if (type === 'custom:circle') {
return this.getCirclePath(shape);
}
};
CustomRenderer.prototype.drawConnection = function(p, element) {
var type = element.type;
if (type === 'custom:connection') {
return this.drawCustomConnection(p, element);
}
};
CustomRenderer.prototype.getConnectionPath = function(connection) {
var type = connection.type;
if (type === 'custom:connection') {
return this.getCustomConnectionPath(connection);
}
};
Many thanks