如何响应式地缩放现有以px单位制作的应用程序。

huangapple go评论67阅读模式
英文:

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:

  &quot;devDependencies&quot;: {
    &quot;@rollup/plugin-commonjs&quot;: &quot;^17.0.0&quot;,
    &quot;@rollup/plugin-node-resolve&quot;: &quot;^11.0.0&quot;,
    &quot;rollup&quot;: &quot;^2.3.4&quot;,
    &quot;rollup-plugin-copy-assets&quot;: &quot;^2.0.3&quot;,
    &quot;rollup-plugin-css-only&quot;: &quot;^3.1.0&quot;,
    &quot;rollup-plugin-livereload&quot;: &quot;^2.0.0&quot;,
    &quot;rollup-plugin-svelte&quot;: &quot;^7.0.0&quot;,
    &quot;rollup-plugin-terser&quot;: &quot;^7.0.0&quot;,
    &quot;svelte&quot;: &quot;^3.0.0&quot;
  },
  &quot;dependencies&quot;: {
    &quot;@rollup/plugin-json&quot;: &quot;^4.1.0&quot;,
    &quot;convert-csv-to-json&quot;: &quot;^1.3.3&quot;,
    &quot;d3&quot;: &quot;^7.4.4&quot;,
    &quot;miragejs&quot;: &quot;^0.1.45&quot;,
    &quot;mock-socket&quot;: &quot;^9.1.5&quot;,
    &quot;sirv-cli&quot;: &quot;^2.0.0&quot;,
    &quot;svelte-i18n&quot;: &quot;^3.4.0&quot;,
    &quot;svelte-keyboard&quot;: &quot;^0.5.5&quot;,
    &quot;svelte-navigator&quot;: &quot;^3.2.2&quot;,
    &quot;svelte-preprocess-sass&quot;: &quot;^2.0.1&quot;,
    &quot;ws&quot;: &quot;^8.9.0&quot;
  }

To collect the dimesions, i tryed to use:

&lt;script&gt;
  let scale = 1;
  let innerHeight = 800;
  let innerWidth = 1024;

  $: scale = Math.min((innerWidth ? innerWidth : 0) / 1024, (innerHeight ? innerHeight : 0) / 800);
&lt;/script&gt;

&lt;svelte:window bind:innerWidth bind:innerHeight /&gt;

Then on the topmost div in the app i try to apply the style like this:

  &lt;div on:contextmenu|preventDefault style={bind({ transform: `scale(${scale})` })}&gt;

But i keep receiving this error:

index.mjs:362 Uncaught (in promise) TypeError: Cannot read properties of null (reading &#39;insertBefore&#39;)
    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:

  &lt;div class=&quot;zoom&quot; bind:clientHeight={cw} bind:clientWidth={ch}&gt;
    &lt;div class=&quot;app&quot; on:contextmenu|preventDefault style={scale}&gt;
  .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 &lt; 1024 &amp;&amp; cw &gt;= 600;
  $: scaleY = ch &gt;= 1024 &amp;&amp; cw &lt; 600;
  $: scaleXY = ch &lt; 1024 &amp;&amp; cw &lt; 600;
  $: rotation = ch &lt; 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将widthheight设置为相对于视口的比例,使用vhvw。这两者都非常好,因为您不再需要使用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.

huangapple
  • 本文由 发表于 2023年3月7日 20:51:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/75662215.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定