Merge pull request #51 from outis1one/claude/peaceful-gauss-9tfiw0
Claude/peaceful gauss 9tfiw0
This commit is contained in:
Generated
+2
-2
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "miniPaint",
|
||||
"version": "4.13.0",
|
||||
"version": "4.14.2",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "miniPaint",
|
||||
"version": "4.13.0",
|
||||
"version": "4.14.2",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.14.5",
|
||||
|
||||
@@ -1,47 +1,73 @@
|
||||
import app from './../../app.js';
|
||||
import config from './../../config.js';
|
||||
import Base_gui_class from './../../core/base-gui.js';
|
||||
import Base_layers_class from './../../core/base-layers.js';
|
||||
import Dialog_class from './../../libs/popup.js';
|
||||
import alertify from './../../../../node_modules/alertifyjs/build/alertify.min.js';
|
||||
import Tools_settings_class from './../tools/settings.js';
|
||||
import Helper_class from './../../libs/helpers.js';
|
||||
import Pica from './../../../../node_modules/pica/dist/pica.js';
|
||||
|
||||
// Common print sizes at 300 DPI: [width_px, height_px, display_label]
|
||||
const PRINT_SIZES = [
|
||||
[1500, 2100, '5x7" Portrait'],
|
||||
[2100, 1500, '5x7" Landscape'],
|
||||
[2400, 3000, '8x10" Portrait'],
|
||||
[3000, 2400, '8x10" Landscape'],
|
||||
[3300, 4200, '11x14" Portrait'],
|
||||
[4200, 3300, '11x14" Landscape'],
|
||||
];
|
||||
|
||||
class Image_size_class {
|
||||
|
||||
constructor() {
|
||||
this.Base_gui = new Base_gui_class();
|
||||
this.Base_layers = new Base_layers_class();
|
||||
this.POP = new Dialog_class();
|
||||
this.Tools_settings = new Tools_settings_class();
|
||||
this.Helper = new Helper_class();
|
||||
this.pica = Pica();
|
||||
this._lastUnits = 'pixels';
|
||||
}
|
||||
|
||||
size() {
|
||||
var _this = this;
|
||||
var common_dimensions = this.Base_gui.common_dimensions;
|
||||
var units = this.Tools_settings.get_setting('default_units');
|
||||
var global_units = this.Tools_settings.get_setting('default_units');
|
||||
var resolution = this.Tools_settings.get_setting('resolution');
|
||||
var enable_autoresize = this.Tools_settings.get_setting('enable_autoresize');
|
||||
|
||||
var displayUnits = (global_units === 'inches') ? 'inches' : 'pixels';
|
||||
this._lastUnits = displayUnits;
|
||||
|
||||
var resolutions = ['Custom'];
|
||||
for (var i in common_dimensions) {
|
||||
var value = common_dimensions[i];
|
||||
resolutions.push(value[0] + 'x' + value[1] + ' - ' + value[2]);
|
||||
}
|
||||
// Print size presets — WxH format is parsed by existing resolution logic
|
||||
for (var ps of PRINT_SIZES) {
|
||||
resolutions.push(ps[0] + 'x' + ps[1] + ' - ' + ps[2] + ' Print');
|
||||
}
|
||||
|
||||
//convert units
|
||||
var width = this.Helper.get_user_unit(config.WIDTH, units, resolution);
|
||||
var height = this.Helper.get_user_unit(config.HEIGHT, units, resolution);
|
||||
var width = this.Helper.get_user_unit(config.WIDTH, displayUnits, resolution);
|
||||
var height = this.Helper.get_user_unit(config.HEIGHT, displayUnits, resolution);
|
||||
|
||||
var settings = {
|
||||
title: 'Canvas Size',
|
||||
params: [
|
||||
{name: "w", title: "Width:", value: width, placeholder: width, comment: units},
|
||||
{name: "h", title: "Height:", value: height, placeholder: height, comment: units},
|
||||
{name: "units", title: "Units:", value: displayUnits, values: ["pixels", "inches"]},
|
||||
{name: "w", title: "Width:", value: width, placeholder: width, comment: displayUnits},
|
||||
{name: "h", title: "Height:", value: height, placeholder: height, comment: displayUnits},
|
||||
{name: "resolution", title: "Resolution:", values: resolutions},
|
||||
{name: "layout", title: "Layout:", value: "Custom", values: ["Custom", "Landscape", "Portrait"]},
|
||||
{name: "enable_autoresize", title: "Enable autoresize:", value: enable_autoresize},
|
||||
{name: "in_proportion", title: "In proportion:", value: false},
|
||||
{name: "resize_image", title: "Resize & crop image:", value: false},
|
||||
],
|
||||
on_change: function(params) {
|
||||
_this.units_change_handler(params);
|
||||
},
|
||||
on_finish: function (params) {
|
||||
_this.size_handler(params);
|
||||
},
|
||||
@@ -49,33 +75,46 @@ class Image_size_class {
|
||||
this.POP.show(settings);
|
||||
}
|
||||
|
||||
size_handler(data) {
|
||||
var width = parseFloat(data.w);
|
||||
var height = parseFloat(data.h);
|
||||
var ratio = config.WIDTH / config.HEIGHT;
|
||||
var units = this.Tools_settings.get_setting('default_units');
|
||||
units_change_handler(params) {
|
||||
var units = params.units;
|
||||
if (units === this._lastUnits) return;
|
||||
|
||||
this._lastUnits = units;
|
||||
var resolution = this.Tools_settings.get_setting('resolution');
|
||||
|
||||
if (width < 0){
|
||||
width = 1;
|
||||
}
|
||||
if (height < 0){
|
||||
height = 1;
|
||||
var newWidth = this.Helper.get_user_unit(config.WIDTH, units, resolution);
|
||||
var newHeight = this.Helper.get_user_unit(config.HEIGHT, units, resolution);
|
||||
|
||||
var wInput = document.getElementById('pop_data_w');
|
||||
var hInput = document.getElementById('pop_data_h');
|
||||
if (wInput) wInput.value = newWidth;
|
||||
if (hInput) hInput.value = newHeight;
|
||||
|
||||
// Update the unit label shown next to each field
|
||||
var wComment = wInput ? wInput.nextElementSibling : null;
|
||||
var hComment = hInput ? hInput.nextElementSibling : null;
|
||||
if (wComment && wComment.classList.contains('field_comment')) wComment.textContent = units;
|
||||
if (hComment && hComment.classList.contains('field_comment')) hComment.textContent = units;
|
||||
}
|
||||
|
||||
async size_handler(data) {
|
||||
var width = parseFloat(data.w);
|
||||
var height = parseFloat(data.h);
|
||||
var canvasRatio = config.WIDTH / config.HEIGHT;
|
||||
var units = data.units || this.Tools_settings.get_setting('default_units');
|
||||
var resolution = this.Tools_settings.get_setting('resolution');
|
||||
|
||||
if (width < 0) width = 1;
|
||||
if (height < 0) height = 1;
|
||||
|
||||
this.Tools_settings.save_setting('enable_autoresize', data.enable_autoresize);
|
||||
|
||||
//aspect ratio
|
||||
if (isNaN(width) && isNaN(height)){
|
||||
if (isNaN(width) && isNaN(height)) {
|
||||
alertify.error('Wrong dimensions');
|
||||
return;
|
||||
}
|
||||
if (isNaN(width)){
|
||||
width = height * ratio;
|
||||
}
|
||||
if (isNaN(height)){
|
||||
height = width / ratio;
|
||||
}
|
||||
if (isNaN(width)) width = height * canvasRatio;
|
||||
if (isNaN(height)) height = width / canvasRatio;
|
||||
|
||||
if (data.resolution != 'Custom') {
|
||||
var dim = data.resolution.split(" ");
|
||||
@@ -83,58 +122,113 @@ class Image_size_class {
|
||||
width = parseInt(dim[0]);
|
||||
height = parseInt(dim[1]);
|
||||
|
||||
if(data.layout == 'Portrait'){
|
||||
// Don't apply layout swap for print presets (orientation is already encoded)
|
||||
if (data.layout == 'Portrait' && !data.resolution.includes('Print')) {
|
||||
var tmp = width;
|
||||
width = height;
|
||||
height = tmp;
|
||||
}
|
||||
}
|
||||
else{
|
||||
//convert units
|
||||
} else {
|
||||
width = this.Helper.get_internal_unit(width, units, resolution);
|
||||
height = this.Helper.get_internal_unit(height, units, resolution);
|
||||
}
|
||||
|
||||
width = parseInt(width);
|
||||
height = parseInt(height);
|
||||
|
||||
var actions = [
|
||||
new app.Actions.Prepare_canvas_action('undo'),
|
||||
new app.Actions.Update_config_action({
|
||||
WIDTH: parseInt(width),
|
||||
HEIGHT: parseInt(height)
|
||||
WIDTH: width,
|
||||
HEIGHT: height
|
||||
}),
|
||||
];
|
||||
|
||||
if(data.in_proportion == true) {
|
||||
//resize object and change coordinates
|
||||
// Proportional layer repositioning (only when not doing full resize+crop)
|
||||
if (data.in_proportion == true && data.resize_image != true) {
|
||||
var width_ratio = config.WIDTH / width;
|
||||
var height_ratio = config.HEIGHT / height;
|
||||
var ratio = Math.max(width_ratio, height_ratio);
|
||||
var maxRatio = Math.max(width_ratio, height_ratio);
|
||||
|
||||
for (var i in config.layers) {
|
||||
var layer = config.layers[i];
|
||||
if(layer.x != null && layer.y != null) {
|
||||
var data_new = {
|
||||
if (layer.x != null && layer.y != null) {
|
||||
actions.push(new app.Actions.Update_layer_action(layer.id, {
|
||||
x: Math.round(layer.x / width_ratio),
|
||||
y: Math.round(layer.y / height_ratio),
|
||||
};
|
||||
actions.push(new app.Actions.Update_layer_action(layer.id, data_new));
|
||||
}));
|
||||
}
|
||||
if(layer.width != null && layer.height != null) {
|
||||
var data_new = {
|
||||
width: Math.round(layer.width / ratio),
|
||||
height: Math.round(layer.height / ratio),
|
||||
};
|
||||
actions.push(new app.Actions.Update_layer_action(layer.id, data_new));
|
||||
if (layer.width != null && layer.height != null) {
|
||||
actions.push(new app.Actions.Update_layer_action(layer.id, {
|
||||
width: Math.round(layer.width / maxRatio),
|
||||
height: Math.round(layer.height / maxRatio),
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Resize & center-crop image layers to fill the new canvas
|
||||
if (data.resize_image == true) {
|
||||
try {
|
||||
var cropActions = await this.get_resize_crop_actions(width, height);
|
||||
actions = actions.concat(cropActions);
|
||||
} catch (error) {
|
||||
alertify.error('Could not resize image: ' + error.message);
|
||||
}
|
||||
}
|
||||
|
||||
actions.push(new app.Actions.Prepare_canvas_action('do'));
|
||||
|
||||
//execute
|
||||
app.State.do_action(
|
||||
new app.Actions.Bundle_action('set_image_size', 'Set Image Size', actions)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates actions to scale-and-center-crop all image layers to fill targetWidth × targetHeight.
|
||||
* Uses "cover" scaling: the image is scaled so it fills the target, then cropped from the center.
|
||||
*/
|
||||
async get_resize_crop_actions(targetWidth, targetHeight) {
|
||||
var actions = [];
|
||||
var srcWidth = config.WIDTH;
|
||||
var srcHeight = config.HEIGHT;
|
||||
|
||||
var scale = Math.max(targetWidth / srcWidth, targetHeight / srcHeight);
|
||||
var scaledW = Math.round(srcWidth * scale);
|
||||
var scaledH = Math.round(srcHeight * scale);
|
||||
var cropX = Math.round((scaledW - targetWidth) / 2);
|
||||
var cropY = Math.round((scaledH - targetHeight) / 2);
|
||||
|
||||
for (var i in config.layers) {
|
||||
var layer = config.layers[i];
|
||||
if (layer.type !== 'image') continue;
|
||||
if (layer.width == null || layer.height == null) continue;
|
||||
|
||||
var canvas = this.Base_layers.convert_layer_to_canvas(layer.id, true, false);
|
||||
var newLayerW = Math.round(layer.width * scale);
|
||||
var newLayerH = Math.round(layer.height * scale);
|
||||
|
||||
var tmp = document.createElement('canvas');
|
||||
tmp.width = newLayerW;
|
||||
tmp.height = newLayerH;
|
||||
await this.pica.resize(canvas, tmp, {alpha: true});
|
||||
|
||||
var newX = Math.round(layer.x * scale) - cropX;
|
||||
var newY = Math.round(layer.y * scale) - cropY;
|
||||
|
||||
actions.push(new app.Actions.Update_layer_image_action(tmp, layer.id));
|
||||
actions.push(new app.Actions.Update_layer_action(layer.id, {
|
||||
x: newX,
|
||||
y: newY,
|
||||
width: newLayerW,
|
||||
height: newLayerH,
|
||||
width_original: newLayerW,
|
||||
height_original: newLayerH,
|
||||
}));
|
||||
}
|
||||
|
||||
return actions;
|
||||
}
|
||||
}
|
||||
|
||||
export default Image_size_class;
|
||||
|
||||
Reference in New Issue
Block a user