Skip to content

Clothing Design Visualizer

Hosting an event with cool merch? Running a printing business? In this article, we review how we can create a t-shirt design visualizer with some dynamic features such as color options using Nuxt.js and Cloudinary.

In addition to individual designs, our visualizer can integrate designs from multiple brands, similar to platforms like Boden and TrendMe. This allows for a diverse range of styles and greater creative freedom.

The complete project can be forked from this Codesandbox. To run the project, you need to specify your Cloudinary account Cloud name in the server control panel. In case you choose to use the Github repository codebase, create a .env file in the project’s root directory and add your cloudinary cloud name as follows :

 NUXT_ENV_CLOUDINARY_CLOUD_NAME= YOUR_CLOUD_NAME

A decent amount of knowledge and experience in Vue.Js, JavaScript is required for this tutorial. Knowledge and experience in Nuxt.Js is also recommended but not required.

Additionally, understanding the basics of AI outfit generators, similar to YouCam Perfect, will be beneficial. This understanding could help in adding features where users can upload a photo, and the system generates a variety of outfit styles automatically using AI technology.

We recommend that you have the most recent version of Node.Js installed in order to create a Nuxt.Js application.

To create a Nuxt.Js app, you may use create-nuxt-app. Make sure you have npx installed. It is now installed by default since npm 5.2.0 or npm v6.1 or yarn.

yarn create nuxt-app <project-name>
# OR
npx create-nuxt-app <project-name>
# OR
npm init nuxt-app <project-name>

Code language: HTML, XML (xml)

The command will give you a number of options. We do not have a strict preference required for this project. You may use the following setup:

  • Project Name: clothing-design-visualizer

  • Programming Language -> JavaScript

  • Package manager -> Yarn

  • UI Framework -> TailwindCSS

  • Nuxt.Js modules -> None

  • Linting tools -> None

  • Rendering mode -> Universal (SSR/SSG)

  • Deployment target -> Static (Static/JAMStack hosting)

  • Development tools -> None

  • Continuous integration -> None

  • Version control -> Git

This is the recommended Cloudinary integration for Nuxt.Js. Add it to your project using the following command.

yarn add @nuxtjs/cloudinary
# OR
npm install @nuxtjs/cloudinary
Code language: CSS (css)

After the installation is complete, add @nuxtjs/cloudinary as a module in the modules section of nuxt.config.js.


// nuxt.config.js

export  default  {

modules:  [

'@nuxtjs/cloudinary'

]

}

Code language: JavaScript (javascript)

To configure the plugin, we’ll add a cloudinary section to the nuxt.config.js file.


// nuxt.config.js

cloudinary:  {

cloudName:  process.env.NUXT_ENV_CLOUDINARY_CLOUD_NAME,

useComponent:  true,

secure:  true,

}
Code language: JavaScript (javascript)

For easy color selection, we recommend using this simple package. To install it, use the following command:


yarn add vue-swatches

# OR

npm install --save vue-swatches

Code language: PHP (php)

Vuex is a state management pattern and library for Vue.Js. It serves as the global data store for storing our data.

This is a single object that contains all your application-level state. We will store our T-shirt colors, templates, and designs here.


// store/index.js

export  const  state  =  ()  =>  ({

color:  "#ff0000",

frontTemplate:  "nuxtjs-tshirt-design-visualizer/assets/tshirt-template-front",

backTemplate:  "nuxtjs-tshirt-design-visualizer/assets/tshirt-template-back",

sideTemplate:  "nuxtjs-tshirt-design-visualizer/assets/tshirt-template-side",

frontDesign:  "nuxtjs-tshirt-design-visualizer/uploads/defaults/default-front-transparent",

backDesign:  "nuxtjs-tshirt-design-visualizer/uploads/defaults/default-back-transparent",

sideDesign:  "nuxtjs-tshirt-design-visualizer/uploads/defaults/default-side-transparent",

});

Code language: JavaScript (javascript)

Getters allow us to get computed data from the store state. We will use getters to get information from our store.


// store/index.js

export  const  getters  =  {

color:  state  =>  state.color,

frontTemplate:  state  =>  state.frontTemplate,

backTemplate:  state  =>  state.backTemplate,

sideTemplate:  state  =>  state.sideTemplate,

frontDesign:  state  =>  state.frontDesign,

backDesign:  state  =>  state.backDesign,

sideDesign:  state  =>  state.sideDesign,

};

Code language: JavaScript (javascript)

Mutations are the only way to change the state in the Vuex store. We’ll create the following mutations:


// store/index.js

export  const  mutations  =  {

updateColor(state,  color)  {

state.color  =  color;

return  state.color;

},

updateFrontDesign(state,  public_id)  {

state.frontDesign  =  public_id;

return  state.frontDesign;

},

updateBackDesign(state,  public_id)  {

state.backDesign  =  public_id;

return  state.backDesign;

},

updateSideDesign(state,  public_id)  {

state.sideDesign  =  public_id;

return  state.sideDesign;

}

}

Code language: JavaScript (javascript)

Actions allow us to change state by committing mutations. We can do additional operations in the actions before or after committing the mutations. We will however not need any in our actions for this project.


// store/index.js

export  const  actions  =  {

updateColor({  commit  },  color)  {

return  commit('updateColor',  color);

},

updateFrontDesign({  commit  },  public_id)  {

return  commit('updateFrontDesign',  public_id);

},

updateBackDesign({  commit  },  public_id)  {

return  commit('updateBackDesign',  public_id);

},

updateSideDesign({  commit  },  public_id)  {

return  commit('updateSideDesign',  public_id);

}

}

Code language: JavaScript (javascript)

We will provide our users with the ability to change the color of the T-shirts using a simple color swatch.


<!-- pages/index.vue -->

<v-swatches class="pt-10"  v-model="newColor"  inline></v-swatches>

Code language: HTML, XML (xml)

We will then ensure that when the newColor changes, the updateColor action is executed.


// pages/index.js

import  VSwatches  from  "vue-swatches";

export  default  {

components:  {  VSwatches  },

data()  {

return  {

newColor:  null,

colorChanging:  false,

};

},

watch:  {

newColor(color)  {

this.colorChanging  =  true;

this.$store

.dispatch("updateColor",  color)

.then(()  =>  (this.colorChanging  =  false));

},

},

};

</script>

Code language: PHP (php)

We will be using templates to show the shape of the T-shirts as well as some default designs we will use:

  • nuxtjs-tshirt-design-visualizer/assets/tshirt-template-frontimage

  • nuxtjs-tshirt-design-visualizer/assets/tshirt-template-backimage

  • nuxtjs-tshirt-design-visualizer/assets/tshirt-template-sideimage

  • nuxtjs-tshirt-design-visualizer/uploads/defaults/default-frontimage

  • nuxtjs-tshirt-design-visualizer/uploads/defaults/default-backimage

  • nuxtjs-tshirt-design-visualizer/uploads/defaults/default-sideimage

In order to render the t-shirt as desired, we’ll need to do a sequence of transformations. We will demonstrate how to do it for the front side of the T-shirt. The same logic applies to the backand theside` as well.

First, let us render the front template


<!-- pages/index.vue -->

<cld-image

:public-id="frontTemplate"

alt="Front side of T-shirt "

width="600"

>

</cld-image>

Code language: HTML, XML (xml)

To render an image, we are going to specify the public_id, alt, and width. For the above snippet to work, we will need to map the frontTemplate public_id from our Vuex store.


// pages/index.vue

import  {  mapGetters  }  from  "vuex";

export  default  {

computed:  {

...mapGetters({

frontTemplate:  "frontTemplate",

},

};

Code language: JavaScript (javascript)

With the T-shirt template now showing, we would like to be able to change the T-shirt color. To do this, we are going to use the colorize transformation.


<!-- pages/index.vue -->

<cld-transformation

effect="colorize:90"

:color="color"

/>

Code language: HTML, XML (xml)

To get the color from the Vuex store, we’ll need to map the relevant getter:


// pages/index.vue

computed:  {

...mapGetters({

color:  "color",

})

}

Code language: JavaScript (javascript)

Finally, we’ll place the design on top of the colored T-shirt template. We’ll use the overlay transformation, which allows us to fetch and overlay a remote image. We’ll limit its width to ensure it fits within the T-borders. shirt’s


<!-- pages/index.vue -->

<cld-transformation

:overlay="`fetch:${$cloudinary.image.url(

frontDesign

)}`"

width="500"

/>

Code language: HTML, XML (xml)

We will also map frontDesign from the Vuex store.


// pages/index.vue

computed:  {

...mapGetters({

frontDesign:  "frontDesign",

}),

},

Code language: JavaScript (javascript)

To render the back and the side of the T-shirts, the same code applies. All that is required is to change the mapped templates and designs.

We’ll only go over how to change the front design because it’s the same as changing the back and side designs. Only the mappings must be changed.

To allow file updates, we need to render the file input component. We will also need to display an upload status once uploading has begun.


<!-- pages/front.vue -->

<input

v-if="!uploading"

type="file"

accept=".jpeg,.jpg,.png,image/jpeg,image/png"

aria-label="upload image button"

@change="selectFile"

/>

<div v-else>Please wait, upload in progress</div>

Code language: HTML, XML (xml)

Once the file to be uploaded has been selected, we need to update our Vuex store and redirect the user back to the homepage where they can see the updated designs.


// pages/front.vue

methods:  {

async  selectFile(e)  {

this.uploading  =  true;

const  file  =  e.target.files[0];

/* Make sure file exists */

if  (!file)  return;

/* create a reader */

const  readData  =  (f)  =>

new  Promise((resolve)  =>  {

const  reader  =  new  FileReader();

reader.onloadend  =  ()  =>  resolve(reader.result);

reader.readAsDataURL(f);

});

/* Read data */

const  data  =  await  readData(file);

/* upload the converted data */

const  instance  =  await  this.$cloudinary.upload(data,  {

folder:  "nuxtjs-tshirt-design-visualizer/uploads",

uploadPreset:  "tshirt-design-upload",

});

  

this.$store

.dispatch("updateFrontDesign",  instance.public_id)

.then(()  =>  this.$router.push("/"))

.finally(()  =>  (this.uploading  =  false));

},

},

Code language: JavaScript (javascript)

As you can see in the code above, we specified the following upload preset: tshirt-design-upload. Upload presets allow us to specify a set of upload options instead of repeating the same options on every upload. For this project, no specific upload settings are required.

To create your own upload preset, login to your cloudinary dashboard. Proceed to the Settings page and select the Upload tab. Scroll downwards to the Upload Presets section. You may now create an upload preset by clicking the Add Upload Preset link. We recommend using the following options:

Upload preset name -> tshirt-design-upload

Signing mode -> Unsigned

Folder -> nuxtjs-tshirt-design-visualizer/uploads

Use filename or externally defined public ID -> Off

Overwrite -> On

Delivery Type -> Upload

Access Mode -> Public

Invalidate -> Off

Backup -> Account Default

Discard original file name -> Off

Live broadcast -> Off

You may learn more about upload presets in the official documentation .

Through what we have reviewed in this article, you can now create your own custom t-shirt design visualizer. The sky is the limit with the same set of skills. We can apply the same principles with other items that can be customized such as hoodies, vehicles amongst other items.

You might find the following links useful:

State Management with Vuex

Image Transformations with Cloudinary

Nuxtjs Documentation

Back to top

Featured Post