I would strongly consider storing the various variables that define the transformation in a structured object like this:
let transformConfig = {
rotate: {
x: ...,
y: ...,
z: ...
},
scale: {
x: ...,
y: ...
},
translate: {
x: ...,
y: ...,
z: ...
},
skew: {
x: ...,
y: ...
}
};
That gives you the ability to easily iterate over this object to create transformation strings. An example of this iteration might be:
function createTransformString(transformConfig) {
// a variable to store array of individual transform strings
var transformStrings = [];
// store functions that build strings for each transform type
// not shown here but you may want to consider ECMA6 templating
var getString = {
rotate: function(rotate) {
for (dim in rotate) {
transformStrings.push('rotate' + dim + '(' + rotate[dim] + 'deg)';
}
},
scale: function(scale) {
scale.x = scale.x || 1;
scale.y = scale.y || 1;
transformStrings.push('scale(' + scale.x + ',' + scale.y + ')');
},
translate: function(translate) {
for (dim in translate) {
transformStrings.push('translate' + dim + '(' + translate[dim] + 'px)';
}
},
skew: function(skew) {
skew.x = skew.x || 0;
skew.y = skew.y || 0;
transformStrings.push('skew(' + skew.x + 'deg,' + skew.y + 'deg)');
}
};
// iterate the config object to generate strings
for (transformAction in transformConfig) {
let transform = transformConfig[transformAction];
getString[transformAction](transform);
}
return transformStrings.join(' ');
};
Usage:
let transformConfig = { ... };
let transformString = createTransformString(transformConfig);
This approach would limit the repeat code you have for each transformation string and would also take care of your if concern in that only those transformation types specified in the config would be executed.
This also more directly injects the transformation configuration information into the function that generates the strings, meaning you no longer have to rely on variables that may or may not be present in inherited scope. This means you could now have your createTransformString() function declared in a wholly separate include file from the code where the actual transformation(s) values are generated, promoting code re-use.
Since you are using ECMA6, I would also consider building this as a class (or classes).
Finally, from a stylistic standpoint, I would recommend sticking with camelCase instead of snake_case, as this is pretty much the de facto standard for javascript.