Blog

Vision API Dynamic Components: How to Integrate Advanced Visualizations in Shopify Slider

Technology
Ekaterina Slesarchik
3min

Are you struggling to develop your own white-label visualizer? Creating one can be a time-consuming and expensive process that requires significant human resources. However, the benefits of implementing a visualizer can be significant, particularly in increasing sales by helping potential clients make faster decisions.

In this article, we will explore how the Vision API and Automation API can be leveraged to develop fast components for Shopify that can supplement or even replace a custom AI visualizer. 

Why use a dynamic component

The Vision API is an exceptional resource for implementing visualization functions with minimum development. This versatile tool can be employed to implement custom designs on carpets, murals, art objects, and surfaces, including ceilings.

However, the Vision API is not only useful for custom designs but it can also be leveraged to enhance product detail pages. As we know, rich content is essential to engage users and drive conversions by helping them make informed decisions. However, creating rich media for every product in your portfolio can be an arduous task that requires significant resources. 

With the Vision API, you can streamline the process and generate engaging dynamic components with minimal development effort. Such dynamic components offer tremendous potential to optimize the product visualization process as they can replace heavy AR visualizers with responsive versions that render efficiently on various platforms.

In this guide, we'll walk you through the steps of implementing such a component for rendering on-the-fly into media sliders within the Shopify CMS system which is beginner-friendly and easy to integrate.

Please note that for the correct operation, you need to create a PIM account and upload products.

How to create a PIM account and upload products

1. Create a PIM account by the link:

ec9247e3-f3cc-4f37-b970-225c79baaa7b.png

2. Go to the Web tab to get a PIM token:

8faf08a0-3c81-460e-9861-d3728bc039e8.png

3. Import all the necessary data into the PIM via the PIM Admin Tool (File upload requirements, User manual for PIM admin) by going to the Product tab and clicking Import.

fc52921e-f3ba-45b9-98f9-d91d7be0af9d.png

So now, we are ready to proceed with upgrading your product pages.

Imagine being able to visualize your product with just one additional section on the page. With the Wizart component, you can integrate dynamic visuals into your image slider and display additional renderings after your media files.

Below, we'll show you how to visualize your product using the Wizart component and display any amount of pictures with the selected product. Here is how it looks:

185f3c53-85bf-41f2-87fe-866dbf133d2f.png

Moreover, enable users to enlarge the rendered image by clicking on it:

15254c3a-792c-47e1-ac61-79eca2b038d0.png

So, how can we make this happen? It's simple! Here are 5 easy steps to get started.

How to integrate the component into your Shopify store

Please note that the following instructions only apply to the default Shopify theme. If you have a different design template, please contact support@wizart.ai for assistance.

1. To get started, go to the Online Store tab and click on the ellipsis (...) next to the Customize button. Then, select the Edit Code option.

00f327ed-7739-4fe4-baee-20edc5cfa228.png

2. Find the Section field and click the Add a new section button. Enter a name of your choice, for example, wizart-rendering.

cc3e9548-57e7-41db-95e5-efcddfad66ff.png

3. Next, copy and paste the provided code into the newly created section.

Keep in mind that the variables {{IMAGE_PATH_OF_INTERIOR}} and {{ROOM_UUID}} are not publicly available. To obtain these variables, you will need to send a request to the Wizart team.

 

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js" integrity="sha512-E8QSvWZ0eCLGk4km3hxSsNmGWbLtSCSUcewDQPQWZF6pEU8GlT8a5fF32wOl1i8ftdMhssTrF/OhyGWwonTcXA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
    <script async>
        document.addEventListener('DOMContentLoaded', function () {
            setTimeout(getProductData, 300);
        })
        function getProductData() {
            jQuery.ajax({
                url: 'https://pim-client.wizart.ai/api/articles/search?q={"$or":[{"$eq":["name","{{ product.selected_or_first_available_variant.sku }}"]},{"$eq":["vendor_code","{{ product.selected_or_first_available_variant.sku }}"]}]}',
                headers: {
                    "Authorization": "{{PIM_TOKEN}}"
                },
                success: function (result) {
                    callback(result.data[0]);
                }
            });
        }
        function callback(data) {
            let rooms = prepareData(data)
            setTimeout(sendToApply, 0, rooms[0], 0);
            setTimeout(sendToApply, 500, rooms[1], 1);
            setTimeout(sendToApply, 1000, rooms[2], 2);
        }
        function prepareData(data) {
            let rooms = [];
            let room1 = {
                room_data: {
                    room: {
                        id: "63a885b3-5417-4920-85f2-d02d81e40a1e",
                        image_path: "interiors/reserved/images/{{IMAGE_PATH_OF_FIRST_INTERIOR}}",
                        walls: [
                            {
                                custom_rotation_angle: 0,
                                is_active: false,
                                wall_id: 0,
                            },
                            {
                                custom_rotation_angle: 0,
                                is_active: false,
                                wall_id: 1,
                            },
                            {
                                custom_rotation_angle: 0,
                                is_active: false,
                                wall_id: 2,
                            }
                        ]
                    }
                }
            }
            let room2 = {
                room_data: {
                    room: {
                        id: "0ccc39c1-6379-4070-934d-f7459ce15247",
                        image_path: "interiors/reserved/images/{{IMAGE_PATH_OF_SECOND_INTERIOR}}",
                        walls: [
                            {
                                custom_rotation_angle: 0,
                                is_active: false,
                                wall_id: 0,
                            },
                            {
                                custom_rotation_angle: 0,
                                is_active: false,
                                wall_id: 1,
                            },
                            {
                                custom_rotation_angle: 0,
                                is_active: false,
                                wall_id: 2,
                            }
                        ]
                    }
                }
            }
            let room3 = {
                room_data: {
                    room: {
                        id: "184164cb-2a4d-49b7-a716-50685b3cd70d",
                        image_path: "interiors/reserved/images/{{IMAGE_PATH_OF_THIRD_INTERIOR}}",
                        walls: [
                            {
                                custom_rotation_angle: 0,
                                is_active: false,
                                wall_id: 0,
                            },
                        ]
                    }
                }
            }
            if (data.application_type[0] === 'wall') {
                Object.assign(room1.room_data.room, {
                    walls: [{
                        custom_rotation_angle: 0,
                        is_active: true,
                        wall_id: 0,
                        wallpaper: data,
                    },{
                        custom_rotation_angle: 0,
                        is_active: true,
                        wall_id: 1,
                        wallpaper: data,
                    },{
                        custom_rotation_angle: 0,
                        is_active: true,
                        wall_id: 2,
                        wallpaper: data,
                    }]
                });
                Object.assign(room2.room_data.room, {
                    walls: [{
                        custom_rotation_angle: 0,
                        is_active: true,
                        wall_id: 0,
                        wallpaper: data,
                    },{
                        custom_rotation_angle: 0,
                        is_active: true,
                        wall_id: 1,
                        wallpaper: data,
                    },{
                        custom_rotation_angle: 0,
                        is_active: true,
                        wall_id: 2,
                        wallpaper: data,
                    }]
                });
                Object.assign(room3.room_data.room, {
                    walls: [{
                        custom_rotation_angle: 0,
                        is_active: true,
                        wall_id: 0,
                        wallpaper: data,
                    }]
                });
            }
            if (data.application_type[0] === 'floor') {
                Object.assign(room1.room_data.room, {
                    floor: {
                        custom_rotation_angle: 0,
                        x: 47.6,
                        y: 78.3,
                        covering: data,
                    }
                });
                Object.assign(room2.room_data.room, {
                    floor: {
                        custom_rotation_angle: 0,
                        x: 43,
                        y: 88.5,
                        covering: data,
                    }
                });
                Object.assign(room3.room_data.room, {
                    floor: {
                        custom_rotation_angle: 0,
                        x: 78.8,
                        y: 92,
                        covering: data,
                    }
                });
            }
            if (data.application_type[0] === 'ceiling') {
                Object.assign(room1.room_data.room, {
                    covering: [{
                        custom_rotation_angle: 0,
                        x: 62,
                        y: 90,
                        covering: data,
                    }]
                });
                Object.assign(room2.room_data.room, {
                    covering: [{
                        custom_rotation_angle: 0,
                        x: 62,
                        y: 90,
                        covering: data,
                    }]
                });
                Object.assign(room3.room_data.room, {
                    covering: [{
                        custom_rotation_angle: 0,
                        x: 62,
                        y: 90,
                        covering: data,
                    }]
                });
            }
            rooms.push(room1)
            rooms.push(room2)
            rooms.push(room3)
            return rooms
        }
        let lastSliderComponent = jQuery('slider-component').last();
        jQuery('<div id="wizart-render-container" class="thumbnail-list list-unstyled slider slider--mobile"></div>').appendTo(lastSliderComponent);
        function sendToApply(data, index) {
            let json_data = JSON.stringify(data)
            let strHash = CryptoJS.MD5('shopify-{{YOUR_STORE_NAME}}'+json_data).toString();
            jQuery.ajax({
                url: 'https://rni.wizart.ai/apply/?resize=large&device=desktop&hash='+strHash,
                method: 'POST',
                headers: {
                    "Authorization": "{{PIM_TOKEN}}"
                },
                accept: "*/*",
                contentType: "application/json;",
                data: json_data,
                success: function (result) {
                     if(/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)){
                       let mobileSlider = jQuery(".slider-mobile-gutter").find('ul');
                       jQuery(`<li class="product__media-item grid__item slider__slide"><img id="render_image-${index}" style="width: 100%; height: auto;" class="wizart-img-render"></img></li>`).appendTo(mobileSlider);
                     } else {
                       jQuery(`<img id="render_image-${index}" sizes="(min-width: 990px) 550px, (min-width: 750px) 550px, calc(100vw - 30px)" class="wizart-img-render thumbnail-list__item slider__slide thumbnail global-media-settings global-media-settings--no-shadow thumbnail--wide"></img>`).appendTo('#wizart-render-container');
                     }
                    jQuery("#render_image-"+index).attr("src", "data:image/jpeg;base64," + result);
                    jQuery("#render_image-"+index).click(function () {
                      let currentModalElement = jQuery(".is-active").find('.product__modal-opener').find('.product__media');
                      let activeElement = jQuery(".is-active").find('.product__modal-opener');
                      activeElement.find(".wizart-render-full-width").remove();
                      jQuery(`<img class="wizart-render-full-width" style="height: 100%; width: 100%;" sizes="(min-width: 990px) 550px, (min-width: 750px) 550px, calc(100vw - 30px)" id="wizart-render-full-width-${index}" src="data:image/jpeg;base64,${result}"></img>`).appendTo(activeElement);
                      currentModalElement.css("display", "none");
                    });
                    jQuery(`.thumbnail:not(".wizart-img-render")`).click(function(){
                      let currentModalElement = jQuery(".is-active").find('.product__modal-opener').find('.product__media');
                      let activeElement = jQuery(".is-active").find('.product__modal-opener');
                      activeElement.find(".wizart-render-full-width").remove();
                      currentModalElement.css("display", "block");
                    });
                }
            });
            return true;
        }
    </script>
    {% schema %}
    {
      "name": "Wizart Multicolumn",
      "class": "section",
      "tag": "section",
      "settings": [],
      "presets": [
        {
          "name": "Render Examples"
        }
      ]
    }
    {% endschema %}
    

4. Afterward, go back to the Online Store tab and click on the Customize button. From there, open the Products template.

5f8da788-68d6-41c2-897d-e82d1ffab17e.png

5. Finally, click on the Add section button and select the previously created section. In this case, it would be wizart-rendering:

71b501a0-4159-4318-9c50-01c02d8bdedd.png

Here is the final result:

155bd9da-c082-43e3-9a02-cc0b97e57a49.png

Conclusion

By following these steps, you can easily integrate a convenient component that can significantly improve the visualization of your products. With this feature, you can use any interior designs you want, either from our library or your own, by simply uploading them to your PIM account. This can enhance the user experience on your website and potentially increase sales. So don't hesitate to try it out and see the difference it can make for your business.

If you have any issues with the component, please, feel free to send a message to support@wizart.ai. And our wonderful sales team will always be happy to help you with unique interiors and product images.