react和外部函数交互_带有React和Cloudinary的交互式产品页面

react和外部函数交互

Consumers today expect to have the ability to customize products they purchase online. Ecommerce sites must evolve to support greater personalization, and a key to that is enabling more functionality on their product retail page, also known as an order page. On this page is where buyers can customize the products they want to buy, changing product properties, such as size, color, delivery means, quantity and other criteria.

如今,消费者希望能够自定义在线购买的产品。 电子商务站点必须不断发展以支持更大的个性化,其关键是在其产品零售页面(也称为订单页面)上启用更多功能。 买家可以在此页面上自定义要购买的产品,并更改产品属性,例如尺寸,颜色,交货方式,数量和其他条件。

Amazon Retail Page

Amazon retail page

亚马逊零售页面

Proper UX demands that when these decisions are being made, the user deserves a visual feedback. For example, if the user is buying a shirt and prefers the red one, the developer should account for that by updating the shirt image to a red variant.

正确的用户体验要求在做出这些决定时,用户应获得视觉反馈。 例如,如果用户正在购买衬衫,并且偏爱红色,则开发人员应通过将衬衫图像更新为红色来解决这一问题。

The idea of implementing such features can be scary. We know how difficult it is to manipulate the color of a non SVG image. Fortunately, Cloudinary, a cloud-based image management and delivery solution, makes it very easy to implement this feature.

实现此类功能的想法可能会令人恐惧。 我们知道操纵非SVG图像的颜色有多困难。 幸运的是,基于云的图像管理和交付解决方案Cloudinary使实现此功能非常容易。

With Cloudinary, we will account for the following challenges in this article:

使用Cloudinary,我们将在本文中解决以下挑战:

  • Varying Image Sizes: Product images in multiple sizes (thumbnail, main image, hi-res zoom image). Cloudinary can deliver these easily, you only need to add the size into the URL and they various images are dynamically generated.

    不同的图像尺寸 :多种尺寸的产品图像(缩略图,主图像,高分辨率缩放图像)。 Cloudinary可以轻松交付这些内容,您只需要在URL中添加大小,它们就会动态生成各种图像。

  • Varying Colors - Some products come in multiple colors, and typically these are all shot as individual images, then they are all uploaded and processed. With Cloudinary, we can simply change the color of the product by calculating how much we have to adjust the RGB channels from the original color to arrive at the desired color. This allows infinite scaling, as we can switch to any color in the spectrum.

    多种颜色 -有些产品有多种颜色,通常这些都是作为单独的图像拍摄,然后全部上载和处理。 使用Cloudinary,我们可以通过计算从原始颜色调整RGB通道以达到所需颜色所需的颜色量,来简单地更改产品的颜色。 这允许无限缩放,因为我们可以切换到光谱中的任何颜色。

  • Custom Texts - Many retailers offer some personalized offerings, such as embroidering, adding logos and designing your own products. Cloudinary can overlay text and images on top of the shirt and can even make it look photorealistic with Displacement Mapping.

    自定义文本 -许多零售商提供一些个性化产品,例如刺绣,添加徽标和设计您自己的产品。 Cloudinary可以在衬衫顶部覆盖文本和图像,甚至可以通过“置换贴图”使它看起来像照片一样真实。

This is what the final demo looks like:

最终的演示如下所示:

设定环境 ( Setup Environment )

Cloudinary integrates well with any front-end framework. You have the option to use the JavaScript core library or a specific framework wrapper library. For the examples in this article, we will be using React. We can set it up using create-react-app:

Cloudinary与任何前端框架都可以很好地集成。 您可以选择使用JavaScript核心库或特定的框架包装器库。 对于本文中的示例,我们将使用React。 我们可以使用create-react-app

# 1. Install create-react-app globally
npm install -g create-react-app
# 2. Create new app
create-react-app cloudinary-retail-page
# 3. Install Cloudinary React library
npm install --save cloudinary-react

For simplicity, all our example code will live in the src/App.js folder.

为简单起见,我们所有的示例代码都位于src/App.js文件夹中。

问题1:更改图像大小 ( Problem 1: Varying Image Sizes )

Let's address the challenges we listed above, one after the other. Varying Image Sizes is the first on the list.

让我们一个接一个地解决上面列出的挑战。 更改图像大小是列表中的第一项。

The image above shows two sets of images: Thumbnails and main. The main image is for the buyers consumption, while the thumbs are for interaction.

上图显示了两组图像:缩略图和主图像。 主要图像用于购买者的消费,而拇指则用于交互。

The selected thumb and the main image are obviously the same, and the most common ways of delivering them are:

所选的拇指和主图像显然是相同的,最常见的传递方法是:

  1. Creating multiple images for a given product manually. This is not scalable considering the 100s of thousands of products available on the website.

    手动为给定产品创建多个图像。 考虑到网站上有成千上万的产品,这是不可扩展的。
  2. Using a high resolution image and resize them to fit the main or thumb section using CSS width and height properties. This is a terrible idea because if each image is 800kb with 3 variations, you end up with the following:

    使用高分辨率图像,并使用CSS width和height属性调整它们的大小以适合主要部分或拇指部分。 这是一个糟糕的主意,因为如果每个图像都是800kb,带有3个变体,您将得到以下结果:

1 main (800) + (1 thumb (800) x 3 models) = 3200kb = 3.2mb

1个主要(800)+(1个拇指(800)x 3个型号)= 3200kb = 3.2mb

Cloudinary enables you to specify the size you prefer during delivery using transformation. In that case, you would have one image on your Cloudinary sever and request a particular size. Let's see an example:

Cloudinary使您可以使用转换指定在交付过程中首选的大小。 在这种情况下,您将在Cloudinary服务器上拥有一个图像并请求特定大小。 让我们来看一个例子:

import React, { Component } from 'react';
import {Image, CloudinaryContext, Transformation} from 'cloudinary-react';

const ImageTransformations = ({width, selectedShirt}) => {
    return (
        <Image publicId={selectedShirt.main+'.jpg'}>
            <Transformation width={width} crop="scale" />
        </Image>
    );
};

class App extends Component {

    constructor(props) {
        super(props);
        const defaultShirt = {id: 1, main: 'shirt_only'};
        this.state = {
            shirts: [
                defaultShirt,
                {id: 2, main: 'laying-shirt'},
                {id: 3, main: 'hanging_t-shirt'}
            ],
            selectedShirt: defaultShirt,
        };
    }

    selectShirt(thumb) {
        this.setState({selectedShirt: thumb}, _ => this.forceUpdate())
    }

    render() {

        return (
          <div className="App">
              <CloudinaryContext cloudName="<YOUR_CLOUD_NAME>">
                  <div id="imageDemoContainer">
                      <div id="mainImage">
                          <ImageTransformations
                              width="600"
                              rgb={rgb}
                              selectedShirt={this.state.selectedShirt}
                              text={this.state.text} />
                      </div>
                      <div id="imageThumbs">
                          <ul id="thumbs">
                              {this.state.shirts.map(thumb => {
                                 return (
                                 <li className={thumb.main === this.state.selectedShirt.main ? 'active': ''} onClick={this.selectShirt.bind(this, thumb)} key={thumb.id}>
                                     {/*<Image publicId={thumb.main}>*/}
                                         {/*<Transformation width="75" crop="scale" />*/}
                                     {/*</Image>*/}
                                     <ImageTransformations
                                         width="75"
                                         rgb={rgb}
                                         selectedShirt={thumb}
                                         text={' '} />
                                 </li>
                                 )
                              })}
                          </ul>
                      </div>
                  </div>
              </CloudinaryContext>
          </div>
        );
    }
}

export default App;

Cloudinary's React library exposes 4 components:

Cloudinary的React库公开了4个组件:

  • Image: Delivering images using a publicId

    图片 :使用publicId传递图片
  • Video: Delivering videos using a publicId

    视频 :使用publicId传递视频
  • Transformation: Applying transformations to images and vidoes

    转换 :将转换应用于图像和视频
  • CloudinaryContext: Wraps multiple Images and Videos to provide them your cloud name. The cloud name is received once you sign up for free

    CloudinaryContext :包装多个ImageVideo 以为其提供您的云名称免费注册后即会收到云名称

Our React state holds an array of image public Ids, shirts, that are on the Cloudinary server.

我们的React状态包含Cloudinary服务器上的一系列图像公共ID( shirts

We iterate over this array of shirts and use the custom ImageTransformations component to request images of width 75px. These images are displayed as thumbs.

我们遍历这一系列衬衫,并使用自定义ImageTransformations组件请求宽度为75px的图像。 这些图像显示为拇指。

When the thumb is clicked, ImageTransformations is also used to render the main image of width 600px. This leaves us with an optimized solution:

单击拇指时,还将使用ImageTransformations渲染宽度为600px的主图像。 这为我们提供了优化的解决方案:

1 main (800) + 1 thumb (100) x 3 models = 1100kb = 1.1mb

1个主(800)+ 1个拇指(100)x 3个模型= 1100kb = 1.1mb

3200 - 1100 = 2100kb = 2.1mb

3200-1100 = 2100kb = 2.1mb

We stripped off more than 60% of xtra kilobytes with Cloudinary.

我们使用Cloudinary剥离了超过60%的Xtra千字节。

问题2:颜色变化 ( Problem 2: Varying Colors )

When buyers are allowed to choose a color, what we do most times is to create a clickable color palette and replace the images with the product image that has the selected color.

当允许购买者选择一种颜色时,我们大多数时候要做的是创建一个可点击的调色板,并将这些图像替换为具有所选颜色的产品图像。

This common pattern doesn't scale because a buyer might prefer a color that does not match the colors of the products you provided. This is limiting because a given product might have varying colors, or the product's colors can be customized to have the buyers color choice after purchase.

由于买家可能会喜欢与您所提供产品的颜色不匹配的颜色,因此这种通用模式无法缩放。 这是有限的,因为给定的产品可能具有不同的颜色,或者可以自定义产品的颜色以在购买后让购买者选择颜色。

Cloudinary makes it possible to use just one image and adjust the RGB channels from the original color with simple transformation.

Cloudinary使得仅使用一张图像并通过简单的转换即可从原始颜色调整RGB通道成为可能。

<Transformation effect="red:255" />
<Transformation effect="blue:255" />
<Transformation effect="green:255" />

We can apply it in the previous example as shown below:

我们可以在上一个示例中应用它,如下所示:

...
import { SketchPicker } from 'react-color';

const ImageTransformations = ({width, rgb, selectedShirt, text}) => {
    return (
        <Image publicId={selectedShirt.main+'.jpg'}>
            <Transformation width={width} crop="scale" />
            <Transformation effect={'red:'+((-1+rgb.r/255)*100).toFixed(0)} />
            <Transformation effect={'blue:'+((-1+rgb.b/255)*100).toFixed(0)} />
            <Transformation effect={'green:'+((-1+rgb.g/255)*100).toFixed(0)} />
            <Transformation underlay={selectedShirt.underlay}  flags="relative" width="1.0" />
            <Transformation overlay={selectedShirt.overlay}  flags="relative" width="1.0"  />
        </Image>
    );
};

class App extends Component {

    constructor(props) {
        super(props);
        const defaultShirt = {id: 1, main: 'shirt_only', underlay: 'model2', overlay: ''};
        this.state = {
            shirts: [
                defaultShirt,
                {id: 2, main: 'laying-shirt', underlay: '', overlay: ''},
                {id: 3, main: 'hanging_t-shirt', underlay: '', overlay: 'hanger'}
            ],
            text: ' ',
            selectedShirt: defaultShirt,
            background: {rgb:{r:255,g:255,b:255}}
        };
    }

    handleColorChange(color) {
        // Updates color
        this.setState({ background: color }, _ => this.forceUpdate());
    };

    selectShirt(thumb) {
        // Updates main image
        this.setState({selectedShirt: thumb}, _ => this.forceUpdate())
    }

    render() {
        const rgb = this.state.background.rgb;

        return (
          <div className="App">
              <CloudinaryContext cloudName="christekh">
                 <div id="demoContainer">
                      <div id="header">
                          <a href="http://cloudinary.com/">
                              <img width="172" height="38" src="http://res-1.cloudinary.com/cloudinary/image/asset/dpr_2.0/logo-e0df892053afd966cc0bfe047ba93ca4.png" alt="Cloudinary Logo" />
                          </a>
                          <h1>Product Personalization Demo</h1>
                      </div>
                  </div>
                  <div id="imageDemoContainer">
                      <div id="mainImage">
                          <ImageTransformations
                              width="600"
                              rgb={rgb}
                              selectedShirt={this.state.selectedShirt}
                              text={this.state.text} />
                      </div>
                      <div id="imageThumbs">
                          <ul id="thumbs">
                              {this.state.shirts.map(thumb => {
                                 return (
                                 <li className={thumb.main === this.state.selectedShirt.main ? 'active': ''} onClick={this.selectShirt.bind(this, thumb)} key={thumb.id}>
                                     {/*<Image publicId={thumb.main}>*/}
                                         {/*<Transformation width="75" crop="scale" />*/}
                                     {/*</Image>*/}
                                     <ImageTransformations
                                         width="75"
                                         rgb={rgb}
                                         selectedShirt={thumb}
                                         text={' '} />
                                 </li>
                                 )
                              })}
                          </ul>
                      </div>
                  </div>
                  <div id="demoInputContainer">
                      <div className="inputSelections">
                          <h2>Shirt Color:</h2>
                          <SketchPicker
                              color={ this.state.background.hex }
                              onChangeComplete={ this.handleColorChange.bind(this) }
                          />
                      </div>
                  </div>
              </CloudinaryContext>
          </div>
        );
    }
}

export default App;

We have extended our app with the following:

我们使用以下内容扩展了我们的应用程序:

  • react-color library is a color library with varieties of options. We use one of these options, SketchPicker, to select colors and set the background state with the selected color. The state is set using handleColorChange.

    react-color库是一个具有多种选项的颜色库。 我们使用以下选项之一SketchPicker来选择颜色并使用所选颜色设置background状态。 使用handleColorChange设置状态。
  • The r, g and b values are set to the image using Transformation component.

    使用Transformation组件将rgb值设置为图像。
  • The RGB values are negative because Cloudinary's red/blue/green adjusts the respective color channel by percentage and the color white in RGB is the max value of 256,256,256. The only way to go is down from white, hence the negative adjustments.

    RGB值为负,因为Cloudinary的红色/蓝色/绿色按百分比调整了相应的颜色通道,而RGB中的白色为最大值256,256,256。 唯一的方法是减少白色,因此进行负调整。
  • The trick for the model wearing a shirt and the hanger is using underlay and overlay transformation respectively. We just used this opportunity to include those.

    模型穿衬衫和衣架的技巧分别是使用underlayoverlay转换。 我们只是利用这个机会包括了那些。

We have been using component.forceUpdate() to manually update the view because component.setState() is async which makes changes happen very late.

我们一直在使用component.forceUpdate()手动更新视图,因为component.setState()是异步的,这使得更改很晚才发生。

问题3:自定义文本 ( Problem 3: Custom Text )

With the Cloudinary overlay feature, you can add text to images. This feature is common among companies that are known for printing custom text on fabrics. It is quite simple to accomplish using Cloudinary:

使用Cloudinary覆盖功能,您可以向图像添加文本。 该功能在以在织物上打印自定义文本而闻名的公司中很常见。 使用Cloudinary非常简单:

<Transformation overlay="text:Roboto_30Scotch.io" />

Then we will add a text, "Scotch.io", with Roboto font and 30px large. We can set that in our example, as well, by adding a text field to collect the text and updating the image with the text when a keystroke is received:

然后,我们将添加一个文本,“ Scotch.io”,它带有Roboto字体,大30px。 我们也可以在示例中进行设置,方法是添加一个文本字段以收集文本,并在接收到击键时使用该文本更新图像:

import React, { Component } from 'react';
import {Image, CloudinaryContext, Transformation} from 'cloudinary-react';
import { SketchPicker } from 'react-color';
import './App.css';

const ImageTransformations = ({width, rgb, selectedShirt, text}) => {
    return (
        <Image publicId={selectedShirt.main+'.jpg'}>
            <Transformation overlay={'text:Roboto_30:'+text} flags="relative" gravity="center" />
        </Image>
    );
};

class App extends Component {

    constructor(props) {
        super(props);
        this.state = {
            text: ' ',
          ...
        };
    }

   ...

    handleTextChange(event) {
        this.setState({text: event.target.value}, _ => this.forceUpdate())
    }

    render() {
        const rgb = this.state.background.rgb;

        return (
          <div className="App">
              <CloudinaryContext cloudName="christekh">
                  <div id="imageDemoContainer">
                  ..
                  </div>
                  <div id="demoInputContainer">
                      ...
                      <div className="inputSelections">
                          <h2>Text:</h2>
                          <input className="form-control" type="email" placeholder="Enter text" value={this.state.text} onChange={this.handleTextChange.bind(this)} />
                      </div>
                  </div>
              </CloudinaryContext>
          </div>
        );
    }
}

export default App;

The code sample has been truncated so you can see what is going on.

该代码示例已被截断,因此您可以查看发生了什么。

结论 ( Conclusion )

Using Cloudinary on your retail site makes the lives of everyone involved in the creative cycle easier and opens up new opportunities that wouldn’t be possible otherwise. Get started if you haven't by signing up for free on the Cloudinary website.

在零售网站上使用Cloudinary可以使参与创意周期的每个人的生活更加轻松,并开辟了其他方式无法实现的新机遇。 如果您还没有开始,请通过Cloudinary网站免费注册。

You can also access the repository HERE

您也可以在此处访问存储库

翻译自: https://scotch.io/tutorials/interactive-product-page-with-react-and-cloudinary

react和外部函数交互

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值