magr0s / vue-scrollmagic

Vue.js plugin
MIT License
72 stars 24 forks source link

Gridsome build fail #11

Closed Berkmann18 closed 4 years ago

Berkmann18 commented 4 years ago

After experiencing this error when using scrollmagic+scrollmagic-plugin-gsap+gsap I was looking for a Vue/Gridsome compatible version which brought me here, however I'm getting a similar error which is surprising since this should work on Vue apps that uses NodeJS (or am I wrong)?

Here's the error:

ReferenceError: window is not defined
    at Object.<anonymous> (/home/maxie/Projects/SCC/Website/node_modules/vue-scrollmagic/dist/vue-scrollmagic.common.js:11522:2)
    at /home/maxie/Projects/SCC/Website/node_modules/vue-scrollmagic/dist/vue-scrollmagic.common.js:11508:37
    at Object.cd29 (/home/maxie/Projects/SCC/Website/node_modules/vue-scrollmagic/dist/vue-scrollmagic.common.js:11512:2)
    at __webpack_require__ (/home/maxie/Projects/SCC/Website/node_modules/vue-scrollmagic/dist/vue-scrollmagic.common.js:21:30)
    at Module.fb15 (/home/maxie/Projects/SCC/Website/node_modules/vue-scrollmagic/dist/vue-scrollmagic.common.js:16857:19)
    at __webpack_require__ (/home/maxie/Projects/SCC/Website/node_modules/vue-scrollmagic/dist/vue-scrollmagic.common.js:21:30)
    at /home/maxie/Projects/SCC/Website/node_modules/vue-scrollmagic/dist/vue-scrollmagic.common.js:85:18
    at Object.<anonymous> (/home/maxie/Projects/SCC/Website/node_modules/vue-scrollmagic/dist/vue-scrollmagic.common.js:88:10)
    at Module._compile (internal/modules/cjs/loader.js:776:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:787:10)

Environment:

vue-scrollmagic: v1.2.0 node -v && npm -v: v12.6.0, 6.13.1 gridsome: v0.7.11

magr0s commented 4 years ago

Hi. The error indicates that the window is undefined, you may need to first make sure that the window is initialized. Show me your code, maybe I can help you.

Berkmann18 commented 4 years ago

The main.js is as follows:

import Vuetify from 'vuetify';
import VueScrollmagic from 'vue-scrollmagic';

// eslint-disable-next-line node/no-missing-import
import DefaultLayout from '~/layouts/Default.vue';

import 'vuetify/dist/vuetify.min.css';
import '../static/global.css';

export default function(Vue, {appOptions, head}) {
  head.link.push({
    rel: 'stylesheet',
    href: 'https://fonts.googleapis.com/icon?family=Material+Icons'
  });
  head.link.push({
    rel: 'stylesheet',
    href: 'https://use.fontawesome.com/releases/v5.10.2/css/all.css'
  });
  head.script.push({
    src: 'http://scrollmagic.io/assets/js/lib/greensock/TweenMax.min.js'
  });

  const opts = {
    icons: {
      iconfont: 'md' // 'mdi' || 'mdiSvg' || 'md' || 'fa' || 'fa4'
    },
    // adjust the theme if you would like to
    theme: {
      themes: {
        dark: {
          primary: '#5294e2',
          secondary: '#e2d152',
          accent: '#c052e2',
          error: '#FF5252',
          info: '#2196F3',
          success: '#4CAF50',
          warning: '#FFC107'
        }
      }
    }
  };
  Vue.use(Vuetify);
  appOptions.vuetify = new Vuetify(opts);

  Vue.use(VueScrollmagic);

  // Set default layout as a global component
  Vue.component('Layout', DefaultLayout);
}

The component which uses this plugin is:

<template>
  <v-row id="products" style="width: 100vw" dark class="primary">
    <v-col cols="2" md="2" sm="2">
      <v-navigation-drawer floating dark dense class="primary" id="prodMenu" height="41.68vh">
        <v-list dense rounded>
          <v-list-item
            v-for="item in extProducts"
            :key="item.name"
            link
            :to="`#${item.name}`"
            :id="`${item.name}_btn`"
            @click="productScroll(`#${item.name}`)"
          >
            <v-list-item-content>
              <v-list-item-title>{{ item.action }}</v-list-item-title>
            </v-list-item-content>
          </v-list-item>
        </v-list>
      </v-navigation-drawer>
    </v-col>
    <v-col cols="5" md="5" sm="5" style="text-align: center">
      <h2 class="display-2">Our Products</h2>
      <h3 class="font-weight-thin">Some text here</h3>
      <v-card color="primary" dark flat>
        <v-card-title class="justify-center" id="Overview">The PrineSec stack</v-card-title>
        <v-card-text>Our tools provide X and Y</v-card-text>
      </v-card>
      <v-card
        color="primary"
        dark
        flat
        v-for="item in products"
        :key="item.name"
        class="my-12"
        :id="`${item.name}_parent`"
      >
        <v-card-title class="justify-center" :id="item.name">{{item.name}}</v-card-title>
        <v-card-text>Lorem ipsum dolor sit amet consectetur adipisicing elit. Quidem ad dolorem placeat qui.</v-card-text>
        <v-card-actions>
          <router-link class="routerLink justify-center" :to="item.url">Learn more</router-link>
        </v-card-actions>
        <v-card-actions>
          <router-link class="routerLink justify-center" :to="item.website || '#'">Get started</router-link>
        </v-card-actions>
      </v-card>
    </v-col>
    <v-col cols="5" md="5" sm="5">
      <div id="stackLayer">
        <!-- <v-img src="/stack.png" width="70%"></v-img> -->
        <img src="/stack.png" alt style="width: 70%" id="stackImg" />
        <!-- <v-img v-for="item in products" :key="item.name" :src="`/stack-${item.name.toLowerCase()}.png`" width="70%" style="display: none"></v-img> -->
      </div>
      <!-- <v-parallax dark src="/stack.png" style=""></v-parallax> -->
    </v-col>
  </v-row>
</template>

<script>
export default {
  name: 'products',
  props: {
    products: {
      type: Array,
      required: true
    }
  },
  computed: {
    extProducts() {
      return [
        {
          name: 'Overview',
          action: 'Overview',
          type: '',
          url: '#Overview',
          image: ''
        },
        ...this.products
      ];
    }
  },
  methods: {
    productScroll: id => evt => {
      evt.preventDefault();
      console.log(`Scrolling to #${id}`); //TODO Check if it's being called
      controller.scrollTo(id);

      //If supported by the browser we can even update the URL.
      if (window.history && window.history.pushState) {
        history.pushState('', document.title, id);
      }
    }
  },
  mounted() {
    const productHeight = parseFloat(getComputedStyle(document.getElementById('products')).height);

    const stackImgs = ['/stack.png'];
    this.products.forEach(prod => stackImgs.push(`/stack-${prod.name.toLowerCase()}.png`));

    const leftScene = this.$scrollmagic
      .scene({
        triggerElement: '#products',
        duration: 0.767918 * productHeight
      })
      .setPin('#prodMenu');

    this.$scrollmagic.addScene(leftScene);

    const btnScenes = this.extProducts.map(prod => {
      const scene = this.$scrollmagic
        .scene({
          triggerElement: `#${prod.name}`,
          duration: 100
        })
        .setClassToggle(`#${prod.name}_btn`, 'v-list-item--active');
      this.$scrollmagic.addScene(scene);
      return scene;
    });

    const rightHandHeight = 0.59727 * productHeight;
    const rightScene = this.$scrollmagic
      .scene({
        triggerElement: '#products',
        duration: rightHandHeight
      })
      .setPin('#stackLayer');
    this.$scrollmagic.addScene(rightScene);

    const lastStackImgIndex = stackImgs.length - 1;
    const stackScene = this.$scrollmagic.scene({
      triggerElement: '#products',
      duration: rightHandHeight
    }).on('progress', e => {
      let current = Math.round(e.progress * lastStackImgIndex);
      document.getElementById('stackImg').setAttribute('src', stackImgs[current]);

    })
    this.$scrollmagic.addScene(stackScene);
  }
};
</script>

The error only happens when I run gridsome build.

magr0s commented 4 years ago

This is not a Vue-scrollmagic error. Please see here

Berkmann18 commented 4 years ago

@magr0s Is it possible for this library to support SSR or not have any window calls on what would be called on the server-side?

Or is there a Gridsome/SSR-friendly alternative?

kriskbx commented 3 years ago

This works for me:

// This is the main.js file. Import global CSS and scripts here.
// The Client API can be used here. Learn more: gridsome.org/docs/client-api
import DefaultLayout from '~/layouts/Default.vue'

export default function (Vue, { router, head, isClient }) {
  // Set default layout as a global component
  Vue.component('Layout', DefaultLayout)

  if (isClient) {
    const VueScrollmagic = require('vue-scrollmagic').default
    Vue.use(VueScrollmagic)
  }
})