skip to Main Content

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)

2

Answers


  1. Chosen as BEST ANSWER

    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. 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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search