InPlace Crop : Final Stage
A good enough scenario with how the in place crop will function
by adil_invideo
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/5.3.3/pixi.min.js"></script>
<canvas id="my-canvas"></canvas>
<div class="crop-control hide" id="crop-control">
<div>
<label for="resize-crop">Resize Crop window</label>
<input type="range" id="resize-crop" min=-200 max=200 value=0 steps=1 />
</div>
<div>
<label for="move-sprite">TranslateX Sprite</label>
<input type="range" id="move-sprite" min=-200 max=200 value=0 steps=1 />
</div>
<div>
<label for="move-sprite">TranslateY Sprite</label>
<input type="range" id="move-sprite-y" min=-200 max=200 value=0 steps=1 />
</div>
<button id="crop-btn">
Crop It
</button>
</div>
<div class="control" id="control">
<div>
<label for="resize-sprite">Resize</label>
<input type="range" id="resize-sprite" min=-200 max=200 value=0 steps=1 />
</div>
<div>
<label for="translate-x">Translate X</label>
<input type="range" id="translate-x" min=-200 max=200 value=0 steps=1 />
</div>
<div>
<label for="translate-y">Translate Y</label>
<input type="range" id="translate-y" min=-200 max=200 value=0 steps=1 />
</div>
</div>
<div class="control-crop hide" id="mask-control" style="display: none">
<div>
<label for="crop-x">Crop X</label>
<input type="range" id="crop-x" min=-200 max=200 value=0 steps=1 />
</div>
<div>
<label for="crop-y">Crop Y</label>
<input type="range" id="crop-y" min=-200 max=200 value=0 steps=1 />
</div>
</div>
<div id="shapes-container" class="shapes-container" style="display:none; z-index: 1">
<button id="btn-custom">Custom</button>
<button id="btn-heart">Heart</button>
<button id="btn-slime-shape">Slime</button>
<button id="btn-arrow-shape">Arrow</button>
<button id="btn-skull-shape">Skull</button>
</div>
CSS
body {
background-color: #eeeeee;
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
width: 100vw;
margin: 0;
box-sizing: border-box;
position: relative;
font-family: sans-serif, Arial, Helvetica;
font-size: 14px;
}
.cropper {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.crop-control {
display: flex;
position: absolute;
justify-content: space-evenly;
bottom: 45px;
width: 100%;
z-index: 1;
}
input,
label {
display: block;
}
label {
padding: 5px 0;
text-align: center;
}
button {}
.hide {
display: none;
}
.control {
position: absolute;
display: flex;
width: 100%;
top: 0;
justify-content: space-evenly;
}
.control-crop {
position: absolute;
display: flex;
width: 100%;
top: 50px;
justify-content: space-evenly;
flex-wrap: wrap;
}
.shapes-container {
display: flex;
flex-direction: column;
height: 100%;
position: absolute;
right: 10px;
justify-content: center;
}
.shapes-container button {
width: 50px;
height: 50px;
overflow: hidden;
margin-bottom: 10px;
cursor: pointer;
}
JavaScript
let slime = "https://s3.ap-south-1.amazonaws.com/invideo-block-assets/Template_Block_Assets/EXPRESSIONS/Shape_3.png";
let heart = "https://s3.ap-south-1.amazonaws.com/invideo-block-assets/Template_Block_Assets/EXPRESSIONS/Heart_02.png";
let arrow = "https://s3.ap-south-1.amazonaws.com/invideo-block-assets/Template_Block_Assets/EXPRESSIONS/Line_Zigzag_7.png";
let skull = "https://s3.ap-south-1.amazonaws.com/invideo-block-assets/Template_Block_Assets/EXPRESSIONS/Halloween_14.png";
class Node {
constructor(x, y, width, height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
// https://support.squarespace.com/hc/en-us/articles/115008538927-Understanding-aspect-ratios#:~:text=To%20create%20an%20exact%20aspect,ratio%3A%202%20%C3%B7%203%20%3D%20.
this.ratio = height / width;
this.crop = {
topX: 0.0,
topY: 0.0,
bottomX: 1.0,
bottomY: 1.0,
shape: 'custom'
}
}
getActualWidth() {
// https://sciencing.com/calculate-unknown-total-amount-percent-7442789.html
const spaceOnLeftAndRight = (this.crop.topX - 0) + (1.0 - this.crop.bottomX);
const temp = (1 - spaceOnLeftAndRight) * 100;
const temp2 = (this.width * 100) / temp;
return temp2;
}
getActualHeight() {
// https://sciencing.com/calculate-unknown-total-amount-percent-7442789.html
const spacingOnTopAndBottom = (element.crop.topY - 0) + (1.0 - element.crop.bottomY);
const temp = (1 - spacingOnTopAndBottom) * 100;
const temp2 = (this.height * 100) / temp;
return temp2;
}
getActualX() {
const left = this.crop.topX * this.getActualWidth();
return this.x - left;
}
getActualY() {
const top = this.crop.topY * this.getActualHeight();
return...