TwinCAT HMI - Zugriff auf Control-Eigenschaften im Skript und Responsive Layout - Bild skalieren und zentrieren

mgl

Level-2
Beiträge
115
Reaktionspunkte
14
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Zusammen,

ich möchte meine HMI Responsive aufbauen und möchte Bilder so skalieren, dass das Seitenverhältnis gleich und das Bild mittig bleibt. Wahrscheinlich geht das auch einfacher als ich es versucht habe. Dennoch würde ich gern wissen wie man auf die Controls über die API zugreifen kann.

Ich verwende für einen eigenen Button ein UserControl "ucButton"



In den Eigenschaften Height / Width des Image wollte ich nun Breite / Höhe und Left, Top berechnen und habe daher folgendes in Function-Binding eingetragen jedoch bekomme ich da eine

Javascript:
var ctrlRectangle = TcHmi.Controls.get('Button.RectangleBackground');

var nHeight = 60;
var nWidth = 60;

if (ctrlRectangle !== undefined) {
    var ctrlHeight =ctrlRectangle.getHeight();
    var ctrlWidth =ctrlRectangle.getWidth();
// ...

In der Console erhalte ich folgenden Fehler:
least one error occurred while parsing the function expression.
Domain: TcHmi.System.FunctionExpression
as result of: Code: 4120/0x1018, Message: E_FUNCTION_EXPRESSION_EXCEPTION
Reason: An uncaught exception occurred in target function expression "var ctrlRectangle = TcHmi.Controls.get('BtnAutomatic.Button.RectangleBackground');


Wobei BtnAutomatic das eingebettete UserControl in der View ist (wird automatisch eingefügt), "Button" das oberste Element im UserControl ist.


Ich habe es auch schon mit TcHmi.Symbol.readEx probiert aber ebenfalls ohne Erfolg. Ich habe keine Ahnung wie man es richtig macht.

Anmerkung:
Sehr wahrscheinlich ist mein Lösungsansatz auch falsch, da im ctrlRectangle.getHeight wohl nur "100" (%) heraus kommt.
 
Du fragst die Konfigurationsparameter ab, anstatt der Werte von "rendered".

Das JS kannst du dir für diese einfache Aufgabenstellung aber sparen. Erstelle ein GRID mit 3 Spalten. Spalte 0+2 mit Breite Faktor 1, Spalte 1 mit der gewünschten Darstellungsbreite deines Usercontrols, oder ggf. auch 100% von Content. So ist dein UC immer in Bildschirmmitte.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Das JS kannst du dir für diese einfache Aufgabenstellung aber sparen. Erstelle ein GRID mit 3 Spalten. Spalte 0+2 mit Breite Faktor 1, Spalte 1 mit der gewünschten Darstellungsbreite deines Usercontrols, oder ggf. auch 100% von Content. So ist dein UC immer in Bildschirmmitte.
Aber dann passt doch die Skalierung immer noch nicht oder? Das heißt beim Wechsel von einem 4:3 Monitor auf 16:9, zieht es das Bild dann auseinander.

Aber das mit dem Grid ist dennoch eine gute Idee um etwas zu zentrieren.
 
Also ich habe es jetzt so gelöst, dass ich ein Rechteck eingefügt habe, und da dann das Background Image verwende.

Das Background Image, kann man einfach zentrieren über die Eigenschaften BackgroundImageHorizontalAlignment und BackgroundImageVerticalAlignment.

Im .onResized - Event habe ich dann folgendes Script eingefügt:
Javascript:
const container = document.getElementById('RectangleLogo');

let maxSizeFactor = 0.7   // maximum size of background image 70% in height or width of rectangle

let containerWidth = 0
let containerHeight = 0
   
if (container != null) {
    containerWidth = container.clientWidth;
    containerHeight = container.clientHeight;
} else {
    console.error("Elemente RectangleLogo nicht gefunden");
}

const aspectRatio = 576 / 71;

let newWidth = 0, newHeight = 0;

// Calculate new size based on the aspect ratio
if (containerWidth / containerHeight > aspectRatio) {
    newWidth = containerHeight * aspectRatio * maxSizeFactor;
    newHeight = containerHeight * maxSizeFactor;
} else {
    newWidth = containerWidth * maxSizeFactor;
    newHeight = containerWidth / aspectRatio*maxSizeFactor;
}



if (newWidth > 0
    && newHeight > 0)
{
     console.log("Logo Width: " + newWidth + " Height: " + newHeight);
   
    TcHmi.Symbol.writeEx('%ctrl%RectangleLogo::BackgroundImageHeight%/ctrl%', newHeight, function (data) {
        if (data.error === TcHmi.Errors.NONE) {
            console.log("Write Height success");
        } else {
           console.log("Write Height error");
        }
                     
    });
   
     TcHmi.Symbol.writeEx('%ctrl%RectangleLogo::BackgroundImageWidth%/ctrl%', newWidth, function (data) {
        if (data.error === TcHmi.Errors.NONE) {
            console.log("Write Width success");
        } else {
               console.log("Write Width error");
        }
    });    
 }
 
Zuletzt bearbeitet:
Ich habe es jetzt verstanden:

Screenshot 2025-08-26 132253.png

Was ich allerdings nicht verstehe. Ich habe eine halbe Ewigkeit jetzt herum probiert und versucht es mit dem "Image" Control hinzubekommen.
 
Zurück
Oben