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 setup
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-front
– image -
nuxtjs-tshirt-design-visualizer/assets/tshirt-template-back
– image -
nuxtjs-tshirt-design-visualizer/assets/tshirt-template-side
– image -
nuxtjs-tshirt-design-visualizer/uploads/defaults/default-front
– image -
nuxtjs-tshirt-design-visualizer/uploads/defaults/default-back
– image -
nuxtjs-tshirt-design-visualizer/uploads/defaults/default-side
– image
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 the
side` 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: