const resultEl = document.getElementById('result')
const angleEl = document.getElementById('angle')
const xEl = document.getElementById('x')
const yEl = document.getElementById('y')
const sxEl = document.getElementById('sx')
const syEl = document.getElementById('sy')
const premulEl = document.getElementById('premul')
/** Counter clock-wise rotation */
function getXRotation(angle){
const c = Math.cos(angle)
const s = Math.sin(angle)
return [
+c, -s, 0, 0,
+s, +c, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1];
}
function getTranslation(x, y){
return [
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
x, y, 0, 1]
}
function getScale(sx, sy){
return [
sx, 0, 0, 0,
0,sy, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1]
}
function mat4mul(B, A){
const C = [];
for(let i = 0; i < 4; ++i){
for(let j = 0; j < 4; ++j){
let c = 0;
for(let k = 0; k < 4; ++k){
c += A[4*i+k] * B[4*k+j]
}
C.push(c);
}
}
return C
}
const update = (e) => {
const T1 = getTranslation(xEl.value, yEl.value)
const T2 = getXRotation(angleEl.value * Math.PI / 180)
const T3 = getScale(sxEl.value, syEl.value)
let T = '';
if(premul.checked){
T = `matrix3d(${
mat4mul(mat4mul(T1,T2),T3)
})`
resultEl.style.backgroundColor = 'yellow';
}else{
T = `
matrix3d(${T1})
matrix3d(${T2})
matrix3d(${T3})
`
resultEl.style.backgroundColor = 'gray'
}
resultEl.style.transform = T;
}
angleEl.addEventListener('input', update)
xEl.addEventListener('input', update)
yEl.addEventListener('input', update)
sxEl.addEventListener('input', update)
syEl.addEventListener('input', update)
premulEl.addEventListener('input', update)
div#result {
background-color: gray;
border: 2px solid black;
color: black;
width: 3cm;
height: 2cm;
}
<label>Rotation angle <input type=range id=angle min=0 max=360 value=0>
</label><br>
<label>Translation X <input type=range id=x min=0 max=360 value=0></label><br>
<label>Translation Y <input type=range id=y min=0 max=360 value=0></label><br>
<label>Scale X <input type=range id=sx min=0.5 max=2 value=1 step=0.01></label><br>
<label>Scale Y <input type=range id=sy min=0.5 max=2 value=1 step=0.01></label><br>
<label><input type=checkbox id=premul> Multiply matrices
<br>
<br>
<br>
<br>
<div id=result>Result</div>