Notification texts go here Contact Us Buy Now!

Single Text Dimension Tool_DimensionsWithMarqueeSelection_Photoshop

KHTM


#target photoshop

function generateDimensionsWithMarqueeSelection() {
    if (!app.documents.length) {
        alert("សូមបើក Document ជាមុនសិន!");
        return;
    }

    var doc = app.activeDocument;
    var startRulerUnits = app.preferences.rulerUnits;

    try {
        var dpi = doc.resolution;

        // Helper: បំប្លែង Point (1/72 inch) ទៅ Canvas Pixel
        function getCanvasPixel(anchorVal) {
            var num = 0;
            if (typeof anchorVal === "object" && anchorVal !== null) {
                if (typeof anchorVal.as === "function") return anchorVal.as('px');
                if ("value" in anchorVal) num = Number(anchorVal.value);
            } else {
                num = Number(anchorVal);
            }
            return (num / 72.0) * dpi;
        }

        // ១. ពិនិត្យមើល Rectangular Marquee Selection (បើមាន)
        var hasSelection = false;
        var selBounds = null; // [left, top, right, bottom] ជា pixels
        try {
            var sb = doc.selection.bounds;
            selBounds = [sb[0].as('px'), sb[1].as('px'), sb[2].as('px'), sb[3].as('px')];
            hasSelection = true;
        } catch (e) {
            hasSelection = false;
        }

        // Helper: ពិនិត្យមើលថាតើចំណុចកណ្ដាលនៃខ្សែបន្ទាត់ស្ថិតក្នុង Selection ឬទេ
        function isPointInSelection(px, py, bounds) {
            if (!bounds) return true;
            return (px >= bounds[0] && px <= bounds[2] && py >= bounds[1] && py <= bounds[3]);
        }

        // ២. ស្វែងរក Path/Line ទាំងអស់ក្នុង Document
        var targetPaths = [];
        try {
            if (doc.activePathItem) {
                targetPaths.push(doc.activePathItem);
            }
        } catch (e) {}

        if (targetPaths.length === 0 && doc.pathItems.length > 0) {
            for (var p = 0; p < doc.pathItems.length; p++) {
                targetPaths.push(doc.pathItems[p]);
            }
        }

        if (targetPaths.length === 0) {
            return;
        }

        // ៣. ស្រង់ទិន្នន័យពី Path និង Filter តាម Marquee Selection
        var rawSegments = [];

        for (var tp = 0; tp < targetPaths.length; tp++) {
            var pathItem = targetPaths[tp];
            if (!pathItem.subPathItems) continue;

            for (var s = 0; s < pathItem.subPathItems.length; s++) {
                var subPath = pathItem.subPathItems[s];
                var pts = subPath.pathPoints;
                if (!pts || pts.length < 2) continue;

                var count = subPath.closed ? pts.length : pts.length - 1;

                for (var i = 0; i < count; i++) {
                    var p1 = pts[i].anchor;
                    var p2 = pts[(i + 1) % pts.length].anchor;

                    var x1 = getCanvasPixel(p1[0]);
                    var y1 = getCanvasPixel(p1[1]);
                    var x2 = getCanvasPixel(p2[0]);
                    var y2 = getCanvasPixel(p2[1]);

                    var midX = (x1 + x2) / 2;
                    var midY = (y1 + y2) / 2;

                    // បើមាន Selection ត្រូវពិនិត្យថាតើខ្សែស្ថិតក្នុង Selection ដែរឬទេ
                    if (hasSelection && !isPointInSelection(midX, midY, selBounds)) {
                        continue;
                    }

                    var dx = x2 - x1;
                    var dy = y2 - y1;
                    var distPx = Math.sqrt(dx * dx + dy * dy);

                    // រំលងជ្រុងខ្លីៗ (< 15px)
                    if (distPx < 15) continue;

                    rawSegments.push({ x1: x1, y1: y1, x2: x2, y2: y2, distPx: distPx });
                }
            }
        }

        // ៤. ប្រព័ន្ធលុបខ្សែស្របស្ទួន (Deduplication) ធានាចេញអក្សរតែ ១ គត់
        var cleanSegments = [];

        function isDuplicate(newSeg, existingList) {
            var midX1 = (newSeg.x1 + newSeg.x2) / 2;
            var midY1 = (newSeg.y1 + newSeg.y2) / 2;
            var ang1 = Math.atan2(newSeg.y2 - newSeg.y1, newSeg.x2 - newSeg.x1) * (180 / Math.PI);
            if (ang1 < 0) ang1 += 180;

            for (var e = 0; e < existingList.length; e++) {
                var ex = existingList[e];
                var midX2 = (ex.x1 + ex.x2) / 2;
                var midY2 = (ex.y1 + ex.y2) / 2;
                var ang2 = Math.atan2(ex.y2 - ex.y1, ex.x2 - ex.x1) * (180 / Math.PI);
                if (ang2 < 0) ang2 += 180;

                var dMid = Math.sqrt((midX1 - midX2)*(midX1 - midX2) + (midY1 - midY2)*(midY1 - midY2));
                var dAng = Math.abs(ang1 - ang2);
                if (dAng > 90) dAng = 180 - dAng;

                var lenDiff = Math.abs(newSeg.distPx - ex.distPx);

                if (dMid < 35 && dAng < 10 && lenDiff < 30) {
                    return true;
                }
            }
            return false;
        }

        for (var r = 0; r < rawSegments.length; r++) {
            if (!isDuplicate(rawSegments[r], cleanSegments)) {
                cleanSegments.push(rawSegments[r]);
            }
        }

        if (cleanSegments.length === 0) {
            alert(hasSelection ? "មិនមានខ្សែបន្ទាត់ នៅក្នុងតំបន់ Selection ទេ!" : "រកមិនឃើញ ខ្សែបន្ទាត់ ត្រឹមត្រូវទេ!");
            return;
        }

        // ៥. បង្កើត UI Dialog ជាមួយ ពុម្ពអក្សរ Khmer OS
        var titleText = hasSelection ? "Marquee Selected Dimensions Tool" : "Single Text Dimension Tool";
        var win = new Window("dialog", titleText, undefined, {resizeable: false});
        win.orientation = "column";
        win.alignChildren = ["fill", "top"];
        win.spacing = 10;
        win.margins = 12;

        var scaleGroup = win.add("group");
        scaleGroup.add("statictext", undefined, "Scale:");
        var scaleDropdown = scaleGroup.add("dropdownlist", undefined, ["1:1", "1:10", "1:100"]);
        scaleDropdown.selection = 0;

        var decGroup = win.add("group");
        decGroup.add("statictext", undefined, "ខ្ទង់ក្បៀស:");
        var decDropdown = decGroup.add("dropdownlist", undefined, ["00.0 cm", "00.00 cm"]);
        decDropdown.selection = 1;

        var chkShowAngle = win.add("checkbox", undefined, "បង្ហាញ មុំ Angle (°)");
        chkShowAngle.value = true;

        var fontGroup = win.add("group");
        fontGroup.add("statictext", undefined, "Font Size (pt):");
        var txtFontSize = fontGroup.add("edittext", undefined, "42");
        txtFontSize.characters = 5;

        var offsetGroup = win.add("group");
        offsetGroup.add("statictext", undefined, "Offset Gap (px):");
        var txtOffset = offsetGroup.add("edittext", undefined, "120");
        txtOffset.characters = 5;

        var btnAction = win.add("button", undefined, "បង្កើតខ្នាត (" + cleanSegments.length + " ខ្សែ)");
        btnAction.size = [240, 35];
        var btnClose = win.add("button", undefined, "Close");

        // -------------------------------------------------------------
        // កំណត់ពុម្ពអក្សរ Khmer OS សម្រាប់ UI Dialog
        // -------------------------------------------------------------
        var khmerOSFont;
        try {
            khmerOSFont = ScriptUI.newFont("Khmer OS Siemreap", "REGULAR", 12);
        } catch (f1) {
            try {
                khmerOSFont = ScriptUI.newFont("Khmer OS", "REGULAR", 12);
            } catch (f2) {
                khmerOSFont = ScriptUI.newFont("Khmer OS System", "REGULAR", 12);
            }
        }

        function applyKhmerFont(container) {
            if (container.graphics && khmerOSFont) {
                container.graphics.font = khmerOSFont;
            }
            if (container.children) {
                for (var c = 0; c < container.children.length; c++) {
                    applyKhmerFont(container.children[c]);
                }
            }
        }

        applyKhmerFont(win);
        // -------------------------------------------------------------

        var confirmed = false;
        var opts = {};

        btnAction.onClick = function() {
            opts.scaleMult = (scaleDropdown.selection.text === "1:10") ? 10 : ((scaleDropdown.selection.text === "1:100") ? 100 : 1);
            opts.decimals = (decDropdown.selection.index === 0) ? 1 : 2;
            opts.showAngle = chkShowAngle.value;
            opts.fontSize = parseInt(txtFontSize.text) || 42;
            opts.offsetPx = parseInt(txtOffset.text) || 120;
            confirmed = true;
            win.close();
        };

        btnClose.onClick = function() { win.close(); };

        win.center();
        win.show();

        if (!confirmed) return;

        // ៦. Deselect Marquee Selection រួចបង្កើត Text Layer
        if (hasSelection) {
            doc.selection.deselect();
        }

        app.preferences.rulerUnits = Units.PIXELS;

        var dimGroup = doc.layerSets.add();
        dimGroup.name = "Marquee_Text_Dimensions_Group";

        var redColor = new SolidColor();
        redColor.rgb.red = 255;
        redColor.rgb.green = 0;
        redColor.rgb.blue = 0;

        for (var j = 0; j < cleanSegments.length; j++) {
            var seg = cleanSegments[j];
            var x1 = seg.x1, y1 = seg.y1, x2 = seg.x2, y2 = seg.y2;
            var distPx = seg.distPx;

            if (x1 > x2 || (Math.abs(x1 - x2) < 0.1 && y1 > y2)) {
                var tempX = x1; x1 = x2; x2 = tempX;
                var tempY = y1; y1 = y2; y2 = tempY;
            }

            var dx = x2 - x1;
            var dy = y2 - y1;

            var angleRad = Math.atan2(dy, dx);
            var angleDeg = angleRad * (180 / Math.PI);

            var distCm = (distPx / dpi) * 2.54;
            var actualCm = distCm * opts.scaleMult;

            var textVal = actualCm.toFixed(opts.decimals) + " cm";
            if (opts.showAngle) {
                textVal += " ( " + angleDeg.toFixed(2) + "° )";
            }

            // Vector កែងរំកិលឡើងលើ
            var ux = dx / distPx;
            var uy = dy / distPx;
            var nx = -uy;
            var ny = ux;

            // ទីតាំងអក្សរ
            var midX = (x1 + x2) / 2;
            var midY = (y1 + y2) / 2;
            var targetX = midX + nx * opts.offsetPx;
            var targetY = midY + ny * opts.offsetPx;

            // បង្កើត Text Layer
            var textLayer = dimGroup.artLayers.add();
            textLayer.kind = LayerKind.TEXT;
            textLayer.name = "Dim_" + textVal;

            var textItem = textLayer.textItem;
            textItem.contents = textVal;
            textItem.justification = Justification.CENTER;
            textItem.size = opts.fontSize;
            textItem.color = redColor;
            textItem.position = [targetX, targetY];

            textLayer.rotate(angleDeg, AnchorPosition.MIDDLECENTER);

            // តម្រឹម Bounding Box
            var b = textLayer.bounds;
            var curCenterX = (b[0].value + b[2].value) / 2;
            var curCenterY = (b[1].value + b[3].value) / 2;

            var shiftX = targetX - curCenterX;
            var shiftY = targetY - curCenterY;

            textLayer.translate(shiftX, shiftY);
        }

    } catch (err) {
        alert("Error: " + err);
    } finally {
        app.preferences.rulerUnits = startRulerUnits;
    }
}

generateDimensionsWithMarqueeSelection();


إرسال تعليق

Cookie Consent
We serve cookies on this site to analyze traffic, remember your preferences, and optimize your experience.
Oops!
It seems there is something wrong with your internet connection. Please connect to the internet and start browsing again.
AdBlock Detected!
We have detected that you are using adblocking plugin in your browser.
The revenue we earn by the advertisements is used to manage this website, we request you to whitelist our website in your adblocking plugin.
Site is Blocked
Sorry! This site is not available in your country.
/* Calculate Coil Length-Meter */ /* Calculate Coil Length-Meter-function */