Resizing canvas causes problems with player.snapshotAsync

Im implementing a threekit integration for a Sales Force Reference Architecture integration.
OOTB, threekit styles the threekit canvas element with a height of 150px and width of 100% the parent element.

For the designs Im working with, I need the threekit canvas element to be square. I can accomplish this quite easily with CSS alone, and alternately with Javascript by manually adding the ‘width’, ‘height’, and ‘style.width’ and ‘style.height’ attributes of the canvas element.

However, the is a side effect of both of these approaches:
Once the user add the product to cart, a snapshot is taken of the threekit product model.
For some reason, after adjusting the threekit canvas with either of the methods mentioned above causes the snapshot that is returned from ‘window.threekit.player.snapshotAsync’ is a transparent image.

Is there a method I need to fire to properly adjust the with and height of the threekit rendering canvas with out affecting the image that is returned from ‘window.threekit.player.snapshotAsync’?

Hi Charles, welcome to the forum and thanks for posting.

The snapshotAsync function should return whatever is in the viewport of the player. When you are firing the function, is the item visible in your player? For example, on a quick test I have this item in our player:

Using snapshotAsync I get an image just as it is shown in the player:

The background is transparent, I do not believe it takes background styles into account when creating a snapshot.

Will-
When you say ‘visible in your player’ do you mean visible to the eye?
The player is visible to the eye though it is removed from the dom shortly after the add to cart method fires.
Is there a way to test in code if it is visible when the snapshot happens?

Also, I noticed in your example that you have a tall rectangle as your player. How did (or would) you go about specifying the width and height?

Thanks for the quick response.

Yes, I believe it is dependent on what is visible to the eye or browser. Per our snapshot docs:
The snapshot api will capture the image from current player canvas so you may want to switch to a specific or frame the camera before you take the snapshot

You can do a quick test if you have a player on your site using this code in the console:

let image = new Image();
let imgSrc = await player.snapshotAsync();
image.src = imgSrc;
// Either append the image or save it somehow
document.body.appendChild(image)

It will just append the snapshot to your page so you can get a quick look. The screenshot I sent is actually a square player with a rectangle asset, you can see the icons that are the edge of the player:

.

You can make the player any size you’d like in HTML or CSS or JS.

I would recommend looking at the docs I linked and perhaps investigate the asset-jobs API technique and see if it better suits your needs.

With this approach you can create a render of the item using the asset-jobs API and from there you can retrieve the thumbnail from our files API.

It does add some API calls to the browser but you do not need the player at all.

Will-
Would you mind taking a look at the url Im testing on?
I have a threekit product page setup here:
https://zzkw-005.sandbox.us01.dx.commercecloud.salesforce.com/s/bellacor/100861.html

I have added the following SCSS/CSS to style the player to be a square:
.threekit-player {
.threekit {
[class^=player__] {
height: 0;
padding-bottom: 100%;

        [class^=canvas__] {
            height: 100%;
            width: 100%;
            position: absolute;
            top: 0;
            left: 0;
        }
    }
}

}

When clicking add to cart, the async snapshot method is called.
For some reason, when the above styles are applied to the threekit element, the returned image is a transparent image.
You can see because the mini cart opens with a blank image.
Further testing in the network tab shows the same problem.

Will-
While trying to debug, I noticed the following error:
THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget

Could this be relative to my issue?

Hey Charles, when I punch in the snapshot script into the console on that page, the image seems to be rendering just fine, and when I take your threekitThumbnailUrl that is logged to the console and paste it into this Base64 → Image converter (be sure to copy the entire string, Chrome cuts off the entirety of the text) it also converts.

This makes me think it could be how the base64 string is converted into an image in the cart and not an issue with the Snapshot API. I refreshed and did another test and see some thumbnails in the cart, let me know if this helped or not!