英文:
How to responsive scale existing App made in px units
问题
我有一个现有的应用程序,其中所有单位都是以像素(px)为单位的。这个东西的响应性做得很差,但我现在不想改变整个东西。
我对Svelte相当新,但看到可以从svelte:window元素动态收集客户端的宽度和高度。
有没有办法通过CSS的transform: scale(?, ?)动态应用这个?这样,宽度和高度始终使用给定设备的整个显示。
我使用这个配置:
"devDependencies": {
"@rollup/plugin-commonjs": "^17.0.0",
"@rollup/plugin-node-resolve": "^11.0.0",
"rollup": "^2.3.4",
"rollup-plugin-copy-assets": "^2.0.3",
"rollup-plugin-css-only": "^3.1.0",
"rollup-plugin-livereload": "^2.0.0",
"rollup-plugin-svelte": "^7.0.0",
"rollup-plugin-terser": "^7.0.0",
"svelte": "^3.0.0"
},
"dependencies": {
"@rollup/plugin-json": "^4.1.0",
"convert-csv-to-json": "^1.3.3",
"d3": "^7.4.4",
"miragejs": "^0.1.45",
"mock-socket": "^9.1.5",
"sirv-cli": "^2.0.0",
"svelte-i18n": "^3.4.0",
"svelte-keyboard": "^0.5.5",
"svelte-navigator": "^3.2.2",
"svelte-preprocess-sass": "^2.0.1",
"ws": "^8.9.0"
}
为了收集尺寸,我尝试使用:
<script>
let scale = 1;
let innerHeight = 800;
let innerWidth = 1024;
$: scale = Math.min((innerWidth ? innerWidth : 0) / 1024, (innerHeight ? innerHeight : 0) / 800);
</script>
<svelte:window bind:innerWidth bind:innerHeight />
然后在应用程序中最顶层的div上,我尝试这样应用样式:
<div on:contextmenu|preventDefault style={bind({ transform: `scale(${scale})` })}>
但我一直收到这个错误:
index.mjs:362 Uncaught (in promise) TypeError: Cannot read properties of null (reading 'insertBefore')
at insert (index.mjs:362:12)
at insert_dev (index.mjs:2011:5)
at Object.mount [as m] (Router.svelte:197:1)
at mount_component (index.mjs:1827:26)
at Object.mount [as m] (Route.svelte:117:24)
at Object.update [as p] (Route.svelte:98:14)
at update (index.mjs:1093:36)
at flush (index.mjs:1060:13)
英文:
I have a existing App where all units are made in px.
The thing was done with poorly responsivenes, but i don't want to change the whole thing now.
Im pretty new to Svelte, but saw there is a possibility to collect the clientWith and height dynamically from the svelte:window element.
Is there a way to apply this dnamically via transform: scale(?,?) css? so that with and height allways use the whole display of a given device.
I use this configuration:
"devDependencies": {
"@rollup/plugin-commonjs": "^17.0.0",
"@rollup/plugin-node-resolve": "^11.0.0",
"rollup": "^2.3.4",
"rollup-plugin-copy-assets": "^2.0.3",
"rollup-plugin-css-only": "^3.1.0",
"rollup-plugin-livereload": "^2.0.0",
"rollup-plugin-svelte": "^7.0.0",
"rollup-plugin-terser": "^7.0.0",
"svelte": "^3.0.0"
},
"dependencies": {
"@rollup/plugin-json": "^4.1.0",
"convert-csv-to-json": "^1.3.3",
"d3": "^7.4.4",
"miragejs": "^0.1.45",
"mock-socket": "^9.1.5",
"sirv-cli": "^2.0.0",
"svelte-i18n": "^3.4.0",
"svelte-keyboard": "^0.5.5",
"svelte-navigator": "^3.2.2",
"svelte-preprocess-sass": "^2.0.1",
"ws": "^8.9.0"
}
To collect the dimesions, i tryed to use:
<script>
let scale = 1;
let innerHeight = 800;
let innerWidth = 1024;
$: scale = Math.min((innerWidth ? innerWidth : 0) / 1024, (innerHeight ? innerHeight : 0) / 800);
</script>
<svelte:window bind:innerWidth bind:innerHeight />
Then on the topmost div in the app i try to apply the style like this:
<div on:contextmenu|preventDefault style={bind({ transform: `scale(${scale})` })}>
But i keep receiving this error:
index.mjs:362 Uncaught (in promise) TypeError: Cannot read properties of null (reading 'insertBefore')
at insert (index.mjs:362:12)
at insert_dev (index.mjs:2011:5)
at Object.mount [as m] (Router.svelte:197:1)
at mount_component (index.mjs:1827:26)
at Object.mount [as m] (Route.svelte:117:24)
at Object.update [as p] (Route.svelte:98:14)
at update (index.mjs:1093:36)
at flush (index.mjs:1060:13)
答案1
得分: 2
以下是代码的中文翻译部分:
<div class="zoom" bind:clientHeight={cw} bind:clientWidth={ch}>
<div class="app" on:contextmenu|preventDefault style={scale}>
.zoom {
position: relative;
transform-origin: top left;
width: 100vw;
height: 100vh;
}
.app {
min-width: 1000px;
min-height: 600px;
width: 100%;
height: 100%;
position: relative;
transform-origin: top left;
background-color: $color--black;
white-space: pre-line; // 添加换行功能以支持 svelte-i18n 插件
}
// 在屏幕宽度小于 1024 或高度小于 600 时进行屏幕缩放
$: scaleX = ch < 1024 && cw >= 600;
$: scaleY = ch >= 1024 && cw < 600;
$: scaleXY = ch < 1024 && cw < 600;
$: rotation = ch < cw;
$: scale = scaleXY
? `transform: scale(${((100 / 1024) * ch) / 100 + hFix},${((100 / 600) * cw) / 100 + wFix}`
: scaleX
? `transform: scale(${((100 / 1024) * ch) / 100 + hFix},1)`
: scaleY
? `transform: scale(1,${((100 / 600) * cw) / 100 + wFix})`
: `transform: scale(1,1)`;
请注意,代码中的变量和注释保持不变。
英文:
So i managed to get it running for Svelte:
<div class="zoom" bind:clientHeight={cw} bind:clientWidth={ch}>
<div class="app" on:contextmenu|preventDefault style={scale}>
.zoom {
position: relative;
transform-origin: top left;
width: 100vw;
height: 100vh;
}
.app {
min-width: 1000px;
min-height: 600px;
width: 100%;
height: 100%;
position: relative;
transform-origin: top left;
background-color: $color--black;
white-space: pre-line; //adds newline possibility to svelte-i18n plugin
}
//screenscaling below 1024 / 600
$: scaleX = ch < 1024 && cw >= 600;
$: scaleY = ch >= 1024 && cw < 600;
$: scaleXY = ch < 1024 && cw < 600;
$: rotation = ch < cw;
$: scale = scaleXY
? `transform: scale(${((100 / 1024) * ch) / 100 + hFix},${((100 / 600) * cw) / 100 + wFix}`
: scaleX
? `transform: scale(${((100 / 1024) * ch) / 100 + hFix},1)`
: scaleY
? `transform: scale(1,${((100 / 600) * cw) / 100 + wFix})`
: `transform: scale(1,1)`;
答案2
得分: 0
你可以使用CSS将width
和height
设置为相对于视口的比例,使用vh
和vw
。这两者都非常好,因为您不再需要使用JS获取视口大小。
在MDN上查看。 这两个属性都表示当前视口高度/宽度的百分比。
英文:
You can use CSS to set the width
and height
to be proportional to the viewport using vh
and vw
. Both of these are great since you don't need to get the viewport size with JS anymore.
Check it out on MDN. Both properties express a percentage of the current viewport height/width.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论