You cant activate the context menu on mobile, like it is on your PC. And i think Safari dont even has a context menu for canvas in general. But you can simply use "toDataURL", you said its throwing an error, i dont know exactly what youre using. But i know this implementation of it, without needing a server etc. I provided you a codepen for it (Stackoverflow snippets deactivated iframe-downloads). Just open the context menu of the canvas and it will download without you needing to anything, also works on mobile (press it for longer). Just a custom context menu, you can find tons of articles in the internet.
https://codepen.io/raqhael/pen/RwRGmQx (I use a function from somewhere else in there, all credit to the function goes to owencm)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>URL Demo</title>
<style>
body {
margin: 0;
padding: 0;
overflow: hidden;
background-color: #f0f0f0;
}
#buttons {
position: absolute;
top: 5px;
left: 10px;
display:none;
}
#buttons > input {
padding: 10px;
display: block;
margin-top: 5px;
}
</style>
</head>
<body>
<div id="container"></div>
<div id="buttons">
<button id="save">
Save as image
</button>
</div>
<canvas id="cv"></canvas>
<script>
let can = document.getElementById("cv");
let ctx = can.getContext("2d");
var width = window.innerWidth;
var height = window.innerHeight;
ctx.beginPath();
ctx.rect(20, 20, 150, 100);
ctx.fillStyle = "red";
ctx.fill();
ctx.beginPath();
ctx.rect(40, 40, 150, 100);
ctx.fillStyle = "blue";
ctx.fill();
// function from https://stackoverflow.com/a/15832662/512042
function downloadURI(uri, name) {
var link = document.createElement('a');
link.download = name;
link.href = uri;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
delete link;
}
can.oncontextmenu = () => {
var dataURL = can.toDataURL();
downloadURI(dataURL, 'canvas.png');
};
</script>
</body>
</html>