Align picture from the top

Hello,

If I have a node with height X and a picture with height x+50. I want to show the picture from top of the node until X and the rest of the picture is cropped.

The picture is inside a Panel (auto).

Code :

g(go.Panel, “Auto”,
{
isClipping: true,
width: shapeWidth || 110,
height: shapeHeight || 90
},
g(go.Shape, ‘RoundedRectangle’,
{
spot1: go.Spot.TopLeft,
spot2: go.Spot.BottomRight
}),
g(go.Picture,
{
maxSize: new go.Size(shapeWidth || 104, NaN),
imageStretch: go.GraphObject.Uniform,
cursor: diagramMode.isPreview ? ‘pointer’ : ‘’,
click: (e, obj) => {
if (diagramMode.isPreview) {
if (obj.part.data.showMockup) {
$window.open(obj.part.data.fullSizeMockUrl, “_blank”, “width=800, height=600”)
}
}
}
},
new go.Binding(‘source’, ‘mockupUrl’)
),
new go.Binding(‘visible’, ‘showMockup’)
),

How can I do that?

Thanks!

OK, here’s both the original template, slightly updated, and a completely different way to try clipping.

    myDiagram.nodeTemplate =
      $(go.Node, "Auto",
        $(go.Shape,  // this is the normal border in an Auto Panel
          { portId: "" },  // links connect with edge of shape, not with rectangular Node
          { fill: null, stroke: "cyan", strokeWidth: 4 },
          { geometryString: "F1 M30 0 L60 60 0 60z" },  // default to a triangle
          new go.Binding("geometryString", "geo")),
        $(go.Panel, "Auto",
          { isClipping: true },  // cause the Shape's geometry to clip other element(s)
          { width: 100, height: 100 },  // bigger than the actual image, to demo stretch
          $(go.Shape,
            { geometryString: "F1 M30 0 L60 60 0 60z" },  // default to a triangle
            new go.Binding("geometryString", "geo")),
          $(go.Picture,
            {
              stretch: go.GraphObject.Fill,  // stretch picture to fill whole area of shape
              imageStretch: go.GraphObject.UniformToFill  // but don't distort the image within the picture
              // alas there is no imageAlign property to control where the image is drawn within the picture
            },
            new go.Binding("source", "src"))
        )
      );

    myDiagram.nodeTemplateMap.add("Position",
      $(go.Node, "Position",
        {
          isClipping: true,
          selectionObjectName: "BORDER"
        },  // cause the main Shape's geometry to clip other element(s)
        $(go.Shape,  // this is the border
          {
            name: "BORDER",
            portId: "",  // links connect with edge of shape, not with rectangular Node
            fill: null,
            stroke: "cyan",
            strokeWidth: 4,
            geometry: go.Geometry.parse("F1 M27.5 0 L55 55 0 55z")  // default to a triangle
          },
          new go.Binding("geometry", "geo", go.Geometry.parse)),
        $(go.Shape,
          {
            isPanelMain: true,  // this is the clipping shape
            position: new go.Point(2, 2),  // because border's strokeWidth: 4
            geometry: go.Geometry.parse("F1 M27.5 0 L55 55 0 55z")  // default to a triangle
          },
          new go.Binding("geometry", "geo", go.Geometry.parse)),
        $(go.Picture,
          {
            position: new go.Point(2, 2),  // because border's strokeWidth: 4
            width: 60,  // but leave desiredSize.height at the default value of NaN
            imageStretch: go.GraphObject.UniformToFill
            // alas there is no imageAlign property to control where the image is drawn within the picture
          },
          new go.Binding("source", "src"))
      ));

    myDiagram.model = new go.GraphLinksModel([
      { key: "Alpha", src: "http://gojs.net/latest/samples/images/storage%20array.jpg" },
      {
        key: "Beta", src: "http://gojs.net/latest/samples/images/storage%20array.jpg",
        geo: "F1 M20 0 L60 0 60 40 40 60 0 60 0 20z"
      },
      {
        key: "Gamma", src: "http://gojs.net/latest/samples/images/storage%20array.jpg",
        category: "Position"
      },
      {
        key: "Delta", src: "http://gojs.net/latest/samples/images/storage%20array.jpg",
        geo: "F1 M20 0 L55 0 55 40 40 55 0 55 0 20z",
        category: "Position"
      }
    ],[
      { from: "Alpha", to: "Beta" },
      { from: "Gamma", to: "Delta" }
    ]);

The Panel.isClipping feature is still experimental. Do you think we should have the clipping Shape also draw its stroke? What about its fill?

Hi,

I used the first option but still I see the middle of the picture in the node if its height is more than the node height. I want the picture to strat from the top and clip at the bottom:

This is the original image :

This the modified code:

`			return g(go.Node, "Auto",
				{
					width: shapeWidth,
					height: shapeHeight
				},
				g(go.Shape, 'RoundedRectangle',  // this is the normal border in an Auto Panel
					{ portId: "" },  // links connect with edge of shape, not with rectangular Node
					{
						fill: null,
						stroke: "cyan",
						strokeWidth: 4,
					}
				),
				g(go.Panel, "Auto",
					{
						width: shapeWidth,
						height: shapeHeight,
						isClipping: true
					},  // bigger than the actual image, to demo stretch
					g(go.Shape, 'RoundedRectangle',
						{
							maxSize: new go.Size(shapeWidth, NaN)
						}
					),
					g(go.Picture,
						{
							stretch: go.GraphObject.Default,  // stretch picture to fill whole area of shape
							imageStretch: go.GraphObject.Uniform,  // but don't distort the image within the picture
							maxSize: new go.Size(shapeWidth, NaN)
							// alas there is no imageAlign property to control where the image is drawn within the picture
						},
						new go.Binding("source", "mockupUrl")
					)
				)`

Any suggestions?

I do.

Its very useful.

Doesn’t the second option do what you want? I was demonstrating first the basic technique for using isClipping and then second how to align the image the way you wanted.

No it did not, can you help me with the current code I have (the code I attached in the previous reply)?

So you did not try the “Position” template?

I did try.

It didnt work.

Here’s what I get with the “Position” template:

Where the source image is: http://gojs.net/latest/samples/images/storage%20array.jpg. You can see that the bottom of the image has been clipped.

I remember what the problem I had with it, I had some picture with width larger then the node width. The width was clipped and not resized to the node width.

Can you try your code with wide and long image -> the width is resized to the node width and the height is clipped at the bottom?

Thanks!

Maybe do something like:

      $(go.Node, "Position",
        {
          isClipping: true,
          selectionObjectName: "BORDER"
        },  // cause the main Shape's geometry to clip other element(s)
        $(go.Shape,  // this is the border
          {
            name: "BORDER",
            portId: "",  // links connect with edge of shape, not with rectangular Node
            fill: null,
            stroke: "cyan",
            strokeWidth: 0,
            geometry: go.Geometry.parse("F1 M27.5 0 L55 55 0 55z")  // default to a triangle
          },
          new go.Binding("geometry", "geo", go.Geometry.parse)),
        $(go.Shape,
          {
            isPanelMain: true,  // this is the clipping shape
            position: new go.Point(2, 2),  // because border's strokeWidth: 4
            geometry: go.Geometry.parse("F1 M27.5 0 L55 55 0 55z")  // default to a triangle
          },
          new go.Binding("geometry", "geo", go.Geometry.parse)),
        $(go.Panel, "Viewbox",
          {
            width: 55, height: NaN,
            position: new go.Point(2, 2),  // because border's strokeWidth: 4
          },
          $(go.Picture,
            new go.Binding("source", "src"))
        )
      )

Hi Watler,

I insert your code, but cant see any picture :(

Using the right bindings?

new go.Binding(“source”, “http://gojs.net/latest/samples/images/storage%20array.jpg”)

The second argument to the Binding constructor should be the name of the property on the binding source object, not some particular property value.

Ohhhh silly me :) Thanks!

It is almost there :) Another problem, what happen if the height and the width of the picture is smaller then the node. I want the picture to be aligned in the center (horizontally and vertically) with its original dimensions.

I tried with maxSize, align and all sort of combination but didn’t succeed.

Thanks!

If you want completely different rules when the image’s natural size is smaller than the Picture, I would guess that that cannot be expressed with a single set of properties. I suppose bindings with conversion functions could help. If that isn’t sufficient, you’ll need to use JavaScript code to compute and set the properties whenever the image changes.

Sorry, but I don’t have time now to figure this out for you.

There was one bug related to Picture alignment when imageStretch is set to UniformToFill. That has been fixed and will be out in the next release.

1.6.12 has been released, which fixed a bug with image alignment when imageStretch was UniformToFill.

Thanks. I have the latest version now.

What I dont understand is why when doing ‘UniformToFill’ I get picture starting from the middle and not from the top. Cant use node.spot only node.auto. I explained this issue at the top regarding the butterfly picture.

That is why I am still stuck.