Примерно так...
<!DOCTYPE html>
<html>
<head>
<style>
canvas {
background: black;
}
form {
display: grid;
grid-template-columns: 1fr 2fr;
margin: 1em;
align-self: flex-start;
align-items: center;
grid-gap: .5em;
}
form label {
display: contents;
}
body {
display: flex;
flex-flow: wrap;
}
</style>
</head>
<body>
<canvas id="canvas" width="500" height="500"></canvas>
<form>
<label>
angle
<input type="range" id="angle" value="0" min="-180" max="180" step="any">
</label>
<label>
cropX
<input type="number" id="cropX" value="850" step="1">
</label>
<label>
cropY
<input type="number" id="cropY" value="600" step="1">
</label>
<label>
cropWidth
<input type="number" id="cropWidth" value="300" step="1">
</label>
<label>
cropHeight
<input type="number" id="cropHeight" value="300" step="1">
</label>
<label>
scale
<input type="range" id="scale" value="1" min="0.1" max="5" step="any">
</label>
</form>
<script>
var ctx = document.getElementById("canvas").getContext("2d");
var image = new Image();
image.src = "https://placeimg.com/2000/1500/any";
image.onload = applyInputs;
document.addEventListener("input", applyInputs);
function applyInputs() {
crop(ctx, image, $.reduce((m, { id, value }) => Object.assign(m, { [id]: value }), {}));
}
var $ = "cropX cropY cropWidth cropHeight scale angle"
.split(/\s+/)
.map(id => document.getElementById(id));
function crop(ctx, image, { cropX, cropY, cropWidth, cropHeight, scale, angle }) {
ctx.save();
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
ctx.translate(.5 * ctx.canvas.width, .5 * ctx.canvas.height);
ctx.rotate(angle * Math.PI / 180);
ctx.save();
ctx.globalAlpha = 0.125;
ctx.scale(scale, scale);
ctx.translate(-.5 * cropWidth - cropX, -.5 * cropHeight - cropY);
ctx.drawImage(image, 0, 0, image.width, image.height, 0, 0, image.width, image.height);
ctx.restore();
ctx.save();
ctx.scale(scale, scale);
ctx.translate(-.5 * cropWidth - cropX, -.5 * cropHeight - cropY);
ctx.drawImage(image, cropX, cropY, cropWidth, cropHeight, cropX, cropY, cropWidth, cropHeight);
ctx.restore();
ctx.restore();
}
</script>
</body>
</html>
В общем главная тут функция crop (строки 77-97), остальное чтобы показать, как оно действует
Если это действует так как нужно, то достаточно сохранить { cropX, cropY, cropWidth, cropHeight, scale, angle }, чтобы потом заново восстановить картинку.