<!DOCTYPE HTML>
<html style="height: 100%;">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Demo</title>
<style>
.demoMyColorBox {
will-change: left, top;
background-color: #062E4F;
border: 2px solid;
margin: 0.75rem;
border-radius: 25%;
position: relative;
}
</style>
<script id="sap-ui-bootstrap"
src="https://sdk.openui5.org/nightly/resources/sap-ui-core.js"
data-sap-ui-oninit="onUI5Init"
data-sap-ui-libs="sap.ui.core,sap.m"
data-sap-ui-async="true"
data-sap-ui-theme="sap_horizon_dark"
data-sap-ui-compatversion="edge"
data-sap-ui-excludejquerycompat="true"
data-sap-ui-resourceroots='{ "demo": "./" }'
data-sap-ui-xx-waitfortheme="init"
data-sap-ui-modules="demo/custom/control/MyColorBox,demo/custom/control/MyColorBoxRenderer"
></script>
<script>
globalThis.onUI5Init = () => sap.ui.require([
"sap/ui/core/mvc/XMLView",
"sap/ui/model/json/JSONModel",
], (XMLView, JSONModel) => {
"use strict";
const limit = 5000;
const model = new JSONModel({});
model.setDefaultBindingMode("OneWay");
model.setSizeLimit(limit);
const callback = (x, y) => {
model.setProperty("/x", x, null, true);
model.setProperty("/y", y, null, true);
};
let radius = 20;
let x = 0;
let y = -radius;
XMLView.create({
definition: `<mvc:View xmlns:mvc="sap.ui.core.mvc" height="100%" xmlns="sap.m">
<App autoFocus="false">
<Page enableScrolling="false"
class="sapUiContentPadding"
content="{
path: 'limit>/items',
templateShareable: false
}"
>
<customHeader>
<Bar>
<contentLeft>
<Title class="sapUiHideOnPhone"
text="🔩 UI5 Stress Test 🏋️"
titleStyle="H2"
/>
</contentLeft>
<contentMiddle>
<HBox renderType="Bare"
alignItems="Center"
justifyContent="SpaceBetween"
height="100%"
width="7rem"
xmlns:html="http://www.w3.org/1999/xhtml"
>
<HBox renderType="Bare"
height="100%"
width="2.5rem"
justifyContent="SpaceBetween"
alignItems="Center"
>
<html:span>x:</html:span>
<Text text="{/x}" textAlign="End"/>
</HBox>
<HBox renderType="Bare"
width="2.5rem"
justifyContent="SpaceBetween"
height="100%"
alignItems="Center"
>
<html:span>y:</html:span>
<Text text="{/y}" textAlign="End"/>
</HBox>
</HBox>
</contentMiddle>
<contentRight>
<StepInput
textAlign="Center"
min="1"
max="1000"
fieldWidth="80%"
description="items"
width="13rem"
value="{limit>/size}"
/>
</contentRight>
</Bar>
</customHeader>
<subHeader>
<Toolbar design="Info">
<ToolbarSpacer/>
<Text
text="DOM rendering, data synchronization, event dispatching, ..."
/>
</Toolbar>
</subHeader>
<myControl:MyColorBox xmlns:myControl="demo.custom.control"
class="demoMyColorBox"
x="{/x}"
y="{/y}"
/>
</Page>
</App>
</mvc:View>`,
afterInit: function() {
const changeHandler = event => this.getModel("limit").setProperty("/items", [
...Array(event.getParameter("value"))
], null, true);
this.getModel("limit").attachPropertyChange(changeHandler);
},
models: {
undefined: model,
limit: (() => {
const limit = 5000;
const size = 50;
const model = new JSONModel({
size: size,
items: [...Array(size)],
});
model.setSizeLimit(limit);
return model;
})(),
},
afterRendering: myFn,
}).then(view => view.placeAt("content"));
function myFn() {
if (!radius) {
return;
}
callback(x, y); // update element positions
let a = x, b = y;
if (y >= 0 && x > -radius) {
a--;
} else {
a++;
}
if (x <= 0 && y > -radius) {
b--;
} else {
b++;
}
x = a;
y = b;
window.requestAnimationFrame(myFn);
}
});
</script>
</head>
<body id="content" class="sapUiBody sapUiSizeCompact">
</body>
</html>
sap.ui.define([
"sap/ui/core/Control",
"./MyColorBoxRenderer",
], function(Control, MyColorBoxRenderer) {
"use strict";
return Control.extend("demo.custom.control.MyColorBox", {
renderer: MyColorBoxRenderer,
metadata: {
properties: {
"x": {
type: "int",
bindable: true
},
"y": {
type: "int",
bindable: true
},
},
},
// ...
});
});
sap.ui.define([
"sap/ui/core/Renderer",
], function(Renderer) {
"use strict";
const boxSize = "18";
return Renderer.extend("demo.custom.control.MyColorBoxRenderer", {
//============================================================
apiVersion: 4, // Aka. "incremental DOM" (apiVerison v2 available since 1.67.x)
render: (renderManager, control) => renderManager
.openStart("canvas", control)
.style("left", `${control.getX()}px`)
.style("top", `${control.getY()}px`)
.attr("width", boxSize)
.attr("height", boxSize)
.openEnd().close("canvas"),
//============================================================
render_: (renderManager, control) => renderManager // string-based
.write("<canvas").writeControlData(control)
.addStyle("left", `${control.getX()}px`)
.addStyle("top", `${control.getY()}px`)
.writeAttribute("width", boxSize)
.writeAttribute("height", boxSize)
.writeStyles()
.writeClasses()
.write("></canvas>")
});
});