Announcing the new WebGL Snapshot package for UAR!

Hi @Francesca, the snapshot package works well with three.js, however, I had to call promptImage() from ZapparWebGLSnapshot as opposed to SnapshotManager in order to access the api.

Hi @Francesca thank you for posting this package, I managed to get it working in Unity after a bit of setup, I was also experiencing the black screen on taking the snapshot at first and managed to resolve this by enabling preserveDrawingBuffer as @Deim suggested, my only problem is I find that this really slows down the experience, at least on Android. I did also try to set this up in a coroutine to see if delaying the Snapshot.promptImage() part of the code by a frame or by 0.1 of a second would resolve the black image issue with preserveDrawingBuffer disabled but had no luck. Any suggestions on how this could be resolved in Unity?

I have also found that on iOS the screenshot image gets flipped upside down on the rear camera.

Hi, i faced the same problem too, any updates?

Hi everyone!
How to use WebGL Snapshot in Webpack packet “zappar-react-three-fiber”.
Where to find the description of the ZapparCanvas class to access the Canvas tag?
What about GIF recording?

Anybody was done access to the canvas with Hooks?
import { useThree } from ‘react-three-fiber’
const { gl } = useThree() // WebGL renderer

Hi @d.haiduk1,

Give gl.domElement a shot to get the canvas element. Note you’re gonna need to preserve drawing buffer:
<ZapparCanvas gl={{ preserveDrawingBuffer: true }} >

You could also record some mp4’s using https://www.npmjs.com/package/@zappar/video-recorder :slight_smile:

Hi, @Deim Thanks for the reply. Do you have an example?

Hi @Francesca I got this error when try using snapshot, Can you help me to check it?
image

I got error snapshot is not defined though I already import it on head tag

Here my screen testing
image

Hi,

try replacing the import with
<script src="https://libs.zappar.com/zappar-snapshot/0.0.17/zappar-snapshot.min.js"></script>

I did but still cannot get file import do you know any way or code example?

Hi Admin , I get sappshot from my camera but I got blank image. I use Javascript. I tried to set !!
var gl = canvas.getContext(“webgl”, {preserveDrawingBuffer: true});
but it doesn’t work. How can I fix that? Thanks a lot.
image

I am facing the same issue. even after including cdn link, i get function not defined error.

Hi, may i know how do you integrate this package into Unity?

2 Likes

Ok, lets clear some things up as I finished testing with some bugs that were thrown at me. To do a proper setup using the index.html file:

  1. Add these to your header:

< head>
< meta charset=“utf-8”>
< meta http-equiv=“Content-Type” content=“text/html; charset=utf-8”>
< meta name=“viewport” content=“width=device-width, initial-scale=1.0, user-scalable=no”>
< title> Zappar AR< /title>
< link rel=“shortcut icon” href=“TemplateData/favicon.ico”>
< script type=“text/javascript” src=“https://libs.zappar.com/zappar-cv/0.3.8/zappar-cv.js”>var zappar=ZCV.initialize();< /script>
< script src=“https://libs.zappar.com/zappar-snapshot/0.0.22/zappar-snapshot.min.js”>
< script type=“text/javascript” import ZapparWebGLSnapshot from ‘@zappar/webgl-snapshot’>< /script>

< /head>

I highlighted where to add the snapshot referencing code!

  1. Create a function to call a snapshot; which can be called from a button (from html or Unity: will go into this in next step) and then make sure the code is within script markers:

    < script>
    function takeScreenshot() {

             // Get canvas from dom
             const canvas = document.querySelector('canvas');
             var gl = canvas.getContext('webgl', { preserveDrawingBuffer: true });
    
             // Convert canvas data to url
             const url = canvas.toDataURL('image/jpeg', 0.8);
    
             // Take snapshot
             ZapparWebGLSnapshot({
                 data: url,
                 fileNamePrepend: 'Zappar',
                 shareUrl: 'www.zappar.com',
                 shareTitle: 'Hello World!',
                 shareText: 'Hello World!',
                 onSave: () => {
                     console.log(`Image was saved`)
                 },
                 onShare: () => {
                     console.log('Share button was pressed');
                 },
                 onClose: () => {
                     console.log('Dialog was closed');
                 }
             }, {
                 SAVE: "SAVE",
                 SHARE: "SHARE",
                 NowOpenFilesAppToShare: "Now open files app to share",
                 TapAndHoldToSave: "Tap and hold the image to save to your Photos app",
             });
    
         }
    

    < /script>

  2. If you want to use in Unity, follow these steps:
    a. Create a jslib file to get Unity to work with html and put this file in the Plugins folder inside Unity. It should look something like this; I named it TakeScreenshot.jslib:

mergeInto(LibraryManager.library, {

TakeScreenshot: function()
{
takeScreenshot();
}

});

b. Create a C# file in Unity and name it something like TakeScreenShot.cs, then add this:

public class TakeScreenShot : MonoBehaviour
{
[DllImport("__Internal")]
private static extern void TakeScreenshot();

public void Take () {

  TakeScreenshot();

}

}

c. Create a button in Unity and use UnityEvents for that button to call the Take function of the Screenshot script. If you need instructions of how to use Unity button events to call stuff in scripts, there are plenty of tutorials on Youtube for that.

BUT WAIT!

If you launch on the web browser you will get this error:
image

Uncaught TypeError: Cannot set property ‘0’ of undefined
at new o (zappar-snapshot.min.js:1)
at new o (zappar-snapshot.min.js:1)
at t.default (zappar-snapshot.min.js:1)

This error is because of these lines of the ZapparWebGLSnapshot:

SAVE: “SAVE”,
SHARE: “SHARE”,
NowOpenFilesAppToShare: “Now open files app to share”,
TapAndHoldToSave: “Tap and hold the image to save to your Photos app”,

Remove these and the screenshot feature should work. I checked the docs and it says this is for localization. So for now if you don’t need to change to different wordings or language then ignore. But I will email the Zapworks team about this!

Thanks,
jrDev

1 Like

Hi everyone!

Thank you for bringing this to our attention - we’ve been able to have a look at the issues here and were successfully able to find a solution. The README should now be updated and we will be updating the docs to reflect this change :zap:

You should now be able to use the package something like this:

// Get canvas from dom
const canvas = document.querySelector('canvas');

// Convert canvas data to url

const url = canvas!.toDataURL('image/jpeg', 0.8);

ZapparWebGLSnapshot({
  data: url,
  fileNamePrepend: 'Zappar',
  shareUrl: 'www.zappar.com',
  shareTitle: 'Hello World!',
  shareText: 'Hello World!',
  onSave: () => {
    console.log('Image was saved');
  },
  onShare: () => {
    console.log('Share button was pressed');
  },
  onClose: () => {
    console.log('Dialog was closed');
  },
}, {}, {
  SAVE: 'SAVE',
  SHARE: 'SHARE',
  NowOpenFilesAppToShare: 'Now open files app to share',
  TapAndHoldToSave: 'Tap and hold the image<br/>to save to your Photos app',
});


Have a great day!
Francesca :blush:

1 Like

i follow the step and still get black screenshot

1 Like

You are correct! One thing I forgot to note on the Unity side is that you NEED to have a yield WaitForEndOfFrame in the code! So here is an edit to the TakeScreenShot.cs:

public void TakeScreenShot () {
		
		StartCoroutine(GetScreenshot());
		
	}
	
	IEnumerator GetScreenshot(){

		yield return new WaitForEndOfFrame();
		
		TakeScreenshot();
		
	}

Now, another issue people were having was because the screenshot was being flipped upside down. With help from the Zapworks team we found this fix. Change this code:

const url = canvas.toDataURL('image/jpeg', 0.8);

To this code:

const url = getDataUrl(canvas, 'image/jpeg');

Then add this function:

function getDataUrl(origCanvas, mimeType) {
             
   var canvas = document.createElement('canvas');
   canvas.width = origCanvas.width;
   canvas.height = origCanvas.height;
   var destCtx = canvas.getContext('2d');
   if (!destCtx) {
       console.error("Cannot create context")
       return ""
   }
   destCtx?.drawImage(origCanvas, 0, 0);
   return destCtx.canvas.toDataURL(mimeType);
}

Thanks,
jrDev
1 Like

thanks, now its working

1 Like

When I use this code, I only see the option to Save. I do not see any Share button or feature anywhere in the Snapshot UI. I am setting hideShareButton to false.

What am I missing? I am testing on iOS Safari mobile.

Update: I see the Share button when testing on Android. If the Share button is only available on Android, please update the README for the npm page to clarify that, rather than just stating “Where available”.