You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
330 lines
13 KiB
330 lines
13 KiB
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<title>GoJS Pictures -- Northwoods Software</title>
|
|
<!-- Copyright 1998-2019 by Northwoods Software Corporation. -->
|
|
<script src="../release/go.js"></script>
|
|
<script src="goIntro.js"></script>
|
|
</head>
|
|
<body onload="goIntro()">
|
|
<div id="container" class="container-fluid">
|
|
<div id="content">
|
|
|
|
<h1>Pictures</h1>
|
|
<p>
|
|
Use the <a>Picture</a> class to display images.
|
|
The most common usage is to set the <a>Picture.source</a> property with a URL string,
|
|
along with the <a>GraphObject.desiredSize</a> or the <a>GraphObject.width</a> and <a>GraphObject.height</a>.
|
|
</p>
|
|
<p>
|
|
If the URL is just a simple constant string, you can pass the string directly as an argument to <a>GraphObject,make</a>,
|
|
rather than assign the "source:" property. Both techniques have the same effect.
|
|
</p>
|
|
<p>
|
|
In these simplistic demonstrations, the code programmatically creates a Part and adds it to the Diagram.
|
|
Once you learn about models and data binding you will generally not create parts (nodes or links) programmatically.
|
|
</p>
|
|
<pre class="lang-js" id="source">
|
|
diagram.add(
|
|
$(go.Part,
|
|
$(go.Picture, "images/100x65.png")
|
|
));
|
|
</pre>
|
|
<script>goCode("source", 600, 160)</script>
|
|
<p>
|
|
However for more sophisticated control you can set the <a>Picture.element</a>
|
|
to an <b>HTMLImageElement</b> or an <b>HTMLCanvasElement</b>.
|
|
</p>
|
|
|
|
<h2 id="Sizing">Sizing</h2>
|
|
<p>
|
|
If you do not set the <a>GraphObject.desiredSize</a> of a <a>Picture</a>, it will get the picture's natural size.
|
|
But when you set the desiredSize to be something different than the natural size, the picture may be stretched or compressed to fit.
|
|
</p>
|
|
<p>
|
|
The following pictures all show a picture of kittens that is 100x65 pixels.
|
|
</p>
|
|
<ul>
|
|
<li>The first picture shows the image at its natural size.</li>
|
|
<li>The second picture also shows the image at its natural size, but has its desiredSize set explicitly.</li>
|
|
<li>The third picture increases the size of the Picture, causing the image to be expanded evenly.</li>
|
|
<li>The fourth picture squeezes the 100x65 image into a 50x32.5 space -- half size.
|
|
This also maintains the original aspect ratio of the image.</li>
|
|
<li>The last picture sets the picture size to be 50x70, which changes the aspect ratio to be taller and thinner than the original.</li>
|
|
</ul>
|
|
<pre class="lang-js" id="sizedPictures">
|
|
diagram.add(
|
|
$(go.Part, "Table",
|
|
$(go.Picture, { source: "images/100x65.png", column: 0,
|
|
margin: 2 }),
|
|
$(go.TextBlock, "natural", { row: 1, column: 0 }),
|
|
$(go.Picture, { source: "images/100x65.png", column: 1,
|
|
width: 100, height: 65, margin: 2 }),
|
|
$(go.TextBlock, "same size", { row: 1, column: 1 }),
|
|
$(go.Picture, { source: "images/100x65.png", column: 2,
|
|
width: 200, height: 130, margin: 2 }),
|
|
$(go.TextBlock, "bigger", { row: 1, column: 2 }),
|
|
$(go.Picture, { source: "images/100x65.png", column: 3,
|
|
width: 50, height: 32.5, margin: 2 }),
|
|
$(go.TextBlock, "smaller", { row: 1, column: 3 }),
|
|
$(go.Picture, { source: "images/100x65.png", column: 4,
|
|
width: 50, height: 70, margin: 2 }),
|
|
$(go.TextBlock, "stretched", { row: 1, column: 4 })
|
|
));
|
|
</pre>
|
|
<script>goCode("sizedPictures", 600, 160)</script>
|
|
<p>
|
|
Note that it may take a while for the media to load.
|
|
Until the time that the media has loaded sufficiently to know its natural size, the Picture may have the wrong size, such as 0x0.
|
|
We recommend that you specify the desiredSize (or width and height) so that
|
|
the Panel(s) holding the Picture will not have to rearrange themselves once the media has loaded.
|
|
</p>
|
|
<p>
|
|
However for the times when you cannot know the natural size ahead of time, there are alternative ways of stretching images to fit in a given space.
|
|
</p>
|
|
|
|
<h2 id="ImageStretch">Image Stretch</h2>
|
|
<p>
|
|
Instead of always stretching or compressing to fill the desiredSize,
|
|
you can set the <a>Picture.imageStretch</a> property to control the size and aspect ratio of the drawn image.
|
|
</p>
|
|
<p>
|
|
The following pictures demonstrate the four possible values for Picture.imageStretch.
|
|
All four Pictures here have the size 60x80 and show the same 100x65 PNG file.
|
|
The Pictures also have a light green background, to show the space available that may be left unused, but is still part of the Picture's bounds.
|
|
</p>
|
|
<ul>
|
|
<li>The first picture demonstrates the default behavior, to stretch in both directions.
|
|
Note how the image is distorted to be narrower than it should be.
|
|
However, all of the image is shown.
|
|
Because the image fills the whole area and the image is not translucent, the background color does not show anywhere.
|
|
</li>
|
|
<li>You can see in the second picture, using an imageStretch of <a>GraphObject,None</a>,
|
|
how it only shows a fraction of the whole kitten image.
|
|
Because the desiredSize is smaller than the natural size of the image,
|
|
parts of the image are clipped.
|
|
</li>
|
|
<li>The third picture shows how a <a>GraphObject,Uniform</a> imageStretch will make sure that all of the image is shown,
|
|
at the expense of reducing the scale and leaving some empty space at the sides or at the top and bottom.
|
|
In this case, because the natural image aspect ratio is wider than the available 60x80 aspect ratio,
|
|
the empty space will be at the top and bottom.
|
|
</li>
|
|
<li>The fourth picture shows how a <a>GraphObject,UniformToFill</a> imageStretch will ensure that the whole area is occupied
|
|
with image, but that not all of the image is shown, since some may be clipped at the sides or at the top and bottom.
|
|
Such images normally have a larger scale than when using Uniform imageStretch.
|
|
In this case what must be clipped is at the sides of the image.
|
|
</li>
|
|
<li>Finally there is a separate Part containing the original image, sized naturally, for comparison.</li>
|
|
</ul>
|
|
<pre class="lang-js" id="stretchedPictures">
|
|
diagram.add(
|
|
$(go.Part, "Table",
|
|
$(go.Picture, "images/100x65.png",
|
|
{ column: 0, width: 60, height: 80, margin: 2, background: "chartreuse",
|
|
imageStretch: go.GraphObject.Fill }),
|
|
$(go.TextBlock, "Fill", { row: 1, column: 0 }),
|
|
$(go.Picture, "images/100x65.png",
|
|
{ column: 1, width: 60, height: 80, margin: 2, background: "chartreuse",
|
|
imageStretch: go.GraphObject.None }),
|
|
$(go.TextBlock, "None", { row: 1, column: 1 }),
|
|
$(go.Picture, "images/100x65.png",
|
|
{ column: 2, width: 60, height: 80, margin: 2, background: "chartreuse",
|
|
imageStretch: go.GraphObject.Uniform }),
|
|
$(go.TextBlock, "Uniform", { row: 1, column: 2 }),
|
|
$(go.Picture, "images/100x65.png",
|
|
{ column: 3, width: 60, height: 80, margin: 2, background: "chartreuse",
|
|
imageStretch: go.GraphObject.UniformToFill }),
|
|
$(go.TextBlock, "UniformToFill", { row: 1, column: 3 })
|
|
));
|
|
|
|
// The original image sized naturally, for comparison
|
|
diagram.add(
|
|
$(go.Part, "Vertical",
|
|
$(go.Picture, "images/100x65.png"),
|
|
$(go.TextBlock, "Original image,\nsized naturally")
|
|
));
|
|
</pre>
|
|
<script>goCode("stretchedPictures", 600, 120)</script>
|
|
<p>
|
|
When images are clipped you can control what part of the image is drawn by using the <a>Picture.imageAlignment</a> property.
|
|
</p>
|
|
|
|
<h2 id="Clipping">Clipping</h2>
|
|
|
|
<p>
|
|
If you have a Picture that must be clipped to a geometry, such as to produce a circular image, there are two options.
|
|
The first is to use a "frame" geometry to hide part of the image.
|
|
Typically this frame is the same color as the Diagram background or the background of the Node.
|
|
This method does not change the area of the Picture, does not allow for true transparency, and clicking anywhere in the bounds will always pick the picture.
|
|
</p>
|
|
<p>
|
|
A second method uses <a>Panel.isClipping</a>.
|
|
This property on a "Spot" Panel allows the filled area of the main Shape to serve as a clipping region instead of a drawn shape.
|
|
This method does not change the area of the Picture, but does allow for transparency
|
|
It affects object picking so that only the resultant drawn area is pickable; areas of the image that are not drawn cannot be "hit".
|
|
</p>
|
|
<p>
|
|
Examples of both follow:
|
|
</p>
|
|
<pre class="lang-js" id="clipPictures">
|
|
|
|
diagram.layout = $(go.GridLayout);
|
|
|
|
// Using a black "frame" geometry to hide part of the image.
|
|
// Typically this frame is the same color as the Diagram background or the background of the Node.
|
|
diagram.add(
|
|
$(go.Part, "Spot",
|
|
{ scale: 2 },
|
|
$(go.Picture, "../samples/images/55x55.png",
|
|
{
|
|
name: 'Picture',
|
|
desiredSize: new go.Size(55, 55),
|
|
background: 'red'
|
|
}
|
|
),
|
|
$(go.Shape,
|
|
{
|
|
strokeWidth: 0,
|
|
stroke: null,
|
|
geometryString: "f M0 0 L100 0 L100 100 L0 100 z M5,50a45,45 0 1,0 90,0a45,45 0 1,0 -90,0 z",
|
|
width: 56,
|
|
height: 56,
|
|
fill: 'black'
|
|
})
|
|
)
|
|
);
|
|
|
|
// Using Panel.isClipping
|
|
diagram.add(
|
|
$(go.Part, "Spot",
|
|
{ isClipping: true, scale: 2 },
|
|
$(go.Shape, "Circle", { width: 55, strokeWidth: 0 } ),
|
|
$(go.Picture, "../samples/images/55x55.png",
|
|
{ width: 55, height: 55 }
|
|
)
|
|
)
|
|
);
|
|
|
|
// Using Panel.isClipping and also having a surrounding panel
|
|
diagram.add(
|
|
$(go.Part, "Spot",
|
|
{ scale: 2 },
|
|
$(go.Shape, "Circle", { width: 65, strokeWidth: 0, fill: 'red' } ),
|
|
$(go.Panel, "Spot",
|
|
{ isClipping: true },
|
|
$(go.Shape, "Circle", { width: 55, strokeWidth: 0 } ),
|
|
$(go.Picture, "../samples/images/55x55.png",
|
|
{ width: 55, height: 55 }
|
|
)
|
|
)
|
|
)
|
|
);
|
|
</pre>
|
|
<script>goCode("clipPictures", 500, 200)</script>
|
|
|
|
|
|
<h2 id="Flipping">Flipping</h2>
|
|
|
|
<p>
|
|
You can flip image sources horizontally and vertically with the <a>Picture.flip</a> property:
|
|
</p>
|
|
|
|
<pre class="lang-js" id="flipPictures">
|
|
diagram.add(
|
|
$(go.Part, "Table",
|
|
$(go.Picture, { source: "images/100x65.png", column: 0, margin: 2,
|
|
flip: go.GraphObject.None
|
|
}),
|
|
$(go.TextBlock, "None (default)", { row: 1, column: 0 }),
|
|
$(go.Picture, { source: "images/100x65.png", column: 1, margin: 2,
|
|
flip: go.GraphObject.FlipHorizontal
|
|
}),
|
|
$(go.TextBlock, "FlipHorizontal", { row: 1, column: 1 }),
|
|
$(go.Picture, { source: "images/100x65.png", column: 2, margin: 2,
|
|
flip: go.GraphObject.FlipVertical
|
|
}),
|
|
$(go.TextBlock, "FlipVertical", { row: 1, column: 2 }),
|
|
$(go.Picture, { source: "images/100x65.png", column: 3, margin: 2,
|
|
flip: go.GraphObject.FlipBoth
|
|
}),
|
|
$(go.TextBlock, "FlipBoth", { row: 1, column: 3 })
|
|
));
|
|
</pre>
|
|
<script>goCode("flipPictures", 600, 160)</script>
|
|
|
|
<h2 id="CrossOriginPictures">Cross Origin Pictures</h2>
|
|
|
|
<p>
|
|
Since Pictures are backed by HTMLImageElements, they must abide by the same Cross-origin (CORS) rules that apply to Images.
|
|
If you are using images that apply to CORS rules, you may need to set the <a>Picture.sourceCrossOrigin</a> property to a function that returns an appropriate value.
|
|
If <code>sourceCrossOrigin</code> is supplied, the value returned by the function is used as the value of any constructed <code>image.crossOrigin</code>.
|
|
Example:
|
|
</p>
|
|
<pre class="lang-js">
|
|
$(go.Picture,
|
|
{ width: 64, height: 64 },
|
|
{ sourceCrossOrigin: function(pict) { return "use-credentials"; } },
|
|
new go.Binding("source", "path"))
|
|
</pre>
|
|
<p>
|
|
Common values to return are "use-credentials" and "anonymous", but other situations may call for other values or conditional values.
|
|
We suggest researching <a href="https://enable-cors.org/">cross-origin resource sharing</a> to determine what is right for your situation.
|
|
</p>
|
|
<p>
|
|
If you are using <a>Diagram.makeImage</a>, <a>Diagram.makeImageData</a>, or <a>Diagram.makeSvg</a>,
|
|
and you are seeing blank or missing images, CORS-related problems are the first thing to investigate.
|
|
</p>
|
|
<h2 id="UsingSVGAsPictureSource">Using SVG as a Picture source</h2>
|
|
|
|
<p>
|
|
Almost all browsers accept SVG files as a Picture source, but in many browsers you <strong>must</strong>:
|
|
</p>
|
|
<ul>
|
|
<li>Assign width and height attributes to the SVG element. These values should be integers. (necessary for Firefox)</li>
|
|
<li>Assign the Picture element a desired size, which <strong>must</strong> be the same as its width and height attributes (necessary for Internet Explorer).</li>
|
|
</ul>
|
|
<p>
|
|
This first SVG element has a width and height specified in its SVG element, and also has its desired size set. It should display in most browsers:
|
|
</p>
|
|
|
|
<pre class="lang-html">
|
|
<svg xmlns="http://www.w3.org/2000/svg"
|
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
width="580" height="580">
|
|
...
|
|
</pre>
|
|
|
|
<pre class="lang-js" id="svg1">
|
|
diagram.add(
|
|
$(go.Part,
|
|
$(go.Picture, { desiredSize: new go.Size(580, 580), source: "images/tiger.svg" })
|
|
));
|
|
diagram.scale = 0.5;
|
|
</pre>
|
|
<script>goCode("svg1", 300, 300)</script>
|
|
|
|
<p style="color: red;"><strong>
|
|
This SVG element does not specify width and height attributes in its SVG element, and as a result some browsers may not render it:
|
|
</strong></p>
|
|
|
|
<pre class="lang-html">
|
|
<svg xmlns="http://www.w3.org/2000/svg"
|
|
xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
...
|
|
</pre>
|
|
<pre class="lang-js" id="svg2">
|
|
diagram.add(
|
|
$(go.Part,
|
|
$(go.Picture, { source: "images/tiger-noWidthHeightSpecified.svg" })
|
|
));
|
|
diagram.scale = 0.5;
|
|
</pre>
|
|
<script>goCode("svg2", 300, 300)</script>
|
|
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html>
|