JointJS: Bootstrap Icon

by Roman Bruckner

HTML

<html>

  <head>
    <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/jointjs/3.6.3/joint.css" />
  </head>

  <body>
    <!-- content -->
    <div id="paper"></div>

    <!-- dependencies -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.4.0/backbone.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jointjs/3.7.5/joint.js"></script>

  </body>

</html>

JavaScript

const { dia, util, shapes: defaultShapes } = joint;

const shapes = {
  ...defaultShapes}

const graph = new dia.Graph({}, {
  cellNamespace: shapes
});

const paper = new dia.Paper({
  el: document.getElementById('paper'),
  width: 800,
  height: 900,
  model: graph,
  cellViewNamespace: shapes,
  gridSize: 10,
  async: true,
  sorting: dia.Paper.sorting.APPROX,
  defaultLink: () => new shapes.standard.Link()
});

const SHAPE_HEIGHT = 30;
const SHAPE_WIDTH = 30;

const clipArtShapes = () => {
	const svgFile = [
		'<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-webcam" viewBox="0 0 16 16">' +
			'<path d="M0 6a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v3a2 2 0 0 1-2 2H9.269c.144.162.33.324.531.475a7 7 0 0 0 .907.57l.014.006.003.002A.5.5 0 0 1 10.5 13h-5a.5.5 0 0 1-.224-.947l.003-.002.014-.007a5 5 0 0 0 .268-.148 7 7 0 0 0 .639-.421c.2-.15.387-.313.531-.475H2a2 2 0 0 1-2-2zm2-1a1 1 0 0 0-1 1v3a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V6a1 1 0 0 0-1-1z"/>' +
			'<path d="M8 6.5a1 1 0 1 0 0 2 1 1 0 0 0 0-2m-2 1a2 2 0 1 1 4 0 2 2 0 0 1-4 0m7 0a.5.5 0 1 1-1 0 .5.5 0 0 1 1 0"/>' +
			'</svg>',
	].join('');

	var webcam = getShape('webcam', svgFile);

	return [webcam];
};

function getShape(type, svgFile) {
	var shape = new shapes.devs.Model({
		type: type,
		markup: '<g class="rotatable"><g class="scalable"><image class="body"/></g></g>',
		size: {
			width: SHAPE_HEIGHT,
			height: SHAPE_WIDTH,
		},
		attrs: {
			'.body': {
				width: 1024,
				height: 768,
				'xlink:href':
					'data:image/svg+xml;utf8,' + encodeURIComponent(svgFile),
				preserveAspectRatio: 'none',
			},
		},
	});
	return shape;
}

graph.addCells(...clipArtShapes());