# Zjbcool-Draggable-Texture 插件教程

这个教程我们结合示例 (opens new window)讲解可拖拽纹理插件的使用方法。

mark

# 基础功能

DraggableTexture插件实现可拖拽纹理的过程是,首先在拼图环境下创建一张空白纹理,然后为纹理加载本地或服务器上的贴图,这个纹理通过对原生的when dragged拼图的支持,可以实现针对纹理的位移、旋转、缩放操作。

注:原生的when dragged拼图是针对物体进行拖拽,使用插件可以针对纹理进行拖拽。

此外,插件还提供了针对纹理的属性和变换操作提供了一些拼图,帮助我们实现更多纹理控制。

下面,我们首先实现示例程序中3个面片的纹理拖拽功能。

# 创建空白纹理

在创建纹理之前,在三维软件中需要在材质上指定一张贴图纹理,这个纹理的唯一功能是提供一个纹理的名字,稍后它会被替换掉,所以,可以给它一个最小的尺寸,比如1px*1px。在Blender中的操作如图:

mark

三维软件中指定好贴图后,导出glTF。

接下来,使用插件的create texture拼图创建一张空白的可拖拽纹理。然后使用原生的材质(Material)分类下的replace texture拼图用新建纹理替换三维软件中设置的原始贴图。

mark

# 加载贴图

现在我们需要为新建的可拖拽纹理加载图片。使用插件中的load image拼图可以从本地或远程服务器加载图片,它会返回一个HTML Image对象,可以用loaded image拼图接收它,然后使用插件的set prop拼图将加载的图片应用到可拖拽纹理。

mark

这时,面片A上就会出现加载的图片了。这里,我们使用set prop拼图设置了纹理的image属性,你还可以用同样的方法,设置纹理的backgroundrepeatsize等属性。

# 拖拽纹理

在原生的when dragged拼图上,通过左上角的齿轮图标打开高级设置,勾选enable start actionenable drop action选项,这时when dragged拼图会有这3个插槽:start: domove: dodrop: do。我们分别使用插件提供的start drag texture拼图、drag texture拼图和drop texture拼图放入这3个插槽。

mark

其中,drag texture拼图的mode参数决定拖拽的方式:位移、旋转、缩放。这里我们按照示例,分别为3个面片指定不同的拖拽方式。

至此,3个面片的功能就完成了。

# 高级功能

在实际开发中,我们一般是通过界面上的按钮去实现不同的功能的。下面,我们接着去实现示例程序中帽子自定义贴图的功能。

# 制作工具条

首先,我们使用HTML/CSS/JS制作一个工具条。HTML中我们使用无序列表来实现基本的布局。我们要实现移动、旋转、缩放、重复、重置和清除这些功能,所以要分别制作对应的按钮。

效果:

mark

HTML:

<ul class="btn-container">
  <li class="btn active" id="move">Move</li>
  <li class="btn" id="rotate">Rotate</li>
  <li class="btn" id="scale">Scale</li>
  <li class="btn" id="repeat">Repeat</li>
  <li class="btn" id="reset">Reset</li>
  <li class="btn" id="clear">Clear</li>
</ul>
1
2
3
4
5
6
7
8

CSS:

.btn-container {
    margin: 0;
    padding: 0;
    position: absolute;
    bottom: 1rem;
    left: 50%;
    width: 100%;
    transform: translateX(-50%);
    -webkit-transform: translateX(-50%);
    -moz-transform: translateX(-50%);
    -ms-transform: translateX(-50%);
    -o-transform: translateX(-50%);
    display: flex;
    flex-flow: row nowrap;
    justify-content: center;
}

.btn {
    list-style-type: none;
    font-size: 1.2rem;
    background: linear-gradient(0deg, #141415, #2f3132);
    color: #a0a2a3;
    border: 2px solid transparent;
    width: 80px;
    height: 50px;
    line-height: 50px;
    text-align: center;
    user-select: none;
    cursor: pointer;
}

.btn:first-child {
    border-radius: 12px 0 0 12px;
    -webkit-border-radius: 12px 0 0 12px;
    -moz-border-radius: 12px 0 0 12px;
    -ms-border-radius: 12px 0 0 12px;
    -o-border-radius: 12px 0 0 12px;
}

.btn:last-child {
    border-radius: 0 12px 12px 0;
    -webkit-border-radius: 0 12px 12px 0;
    -moz-border-radius: 0 12px 12px 0;
    -ms-border-radius: 0 12px 12px 0;
    -o-border-radius: 0 12px 12px 0;
}

.btn:hover {
    background: #141415;
}

.active {
    border: 2px solid #ddd;
    color: #ddd;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55

JS(在exec script拼图中执行):

const btnContainer = document.querySelector('.btn-container');

btnContainer.addEventListener('mousedown', buttonHighlight , false);
btnContainer.addEventListener('touchstart', buttonHighlight , false);

function buttonHighlight(event) {
    for (let btn of btnContainer.children) {
        btn.className = 'btn';
        if(event.target === btn) {
            event.target.classList.add('active');
            VARS.mode = event.target.id; // 设置拖拽模式
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 上传图片功能

首先,按照基础功能部分的步骤,先新建空白可拖拽纹理,然后使用新建纹理替换掉材质上的原有贴图。

接着,我们使用原生的add annotation拼图,在模型上添加一个注释标签,后面我们要通过点击这个注释标签实现上传图片的功能。这里同时实现了模型点击时的描边效果和注释标签的显示/隐藏效果。拼图如下:

mark

下面我们来实现功能部分。为了同时兼容PC端和移动端,我们为注释标签(id为upload)分别添加两个监听事件,事件类型分别是:mousedown和touchstart。

使用原生的HTML分类下的open file拼图和opened file拼图可以从本地打开一张图片,结合基础功能部分讲到的,我们可以使用插件提供的load image拼图将打开的图片加载到可拖拽纹理里面。拼图如下:

mark

注意:在图片加载完成时设置了一个imageLoaded变量,后面会用到。

至此,上传图片功能就实现了,拼图还是很简洁的,是吧。

# 拖拽纹理功能

在这里我们要在基础功能部分的基础上做出一点变化,也就是通过工具条上的按钮来切换拖拽模式。

首先,创建一个transformMode函数,参数是type,type表示拖拽模式。然后,在when dragged拼图的move: do插槽中调用这个函数,把全局变量mode作为参数传递给它。如图:

mark

变量mode的值通过点击工具条上的按钮设置。参见制作工具条JS代码部分。

现在,当点击工具条上的位移、旋转、缩放按钮的时候,就会切换到相应的拖拽模式,从而可以直接在模型上操作纹理。同样的功能,你还可以通过设置快捷键来实现,只要按下快捷键时设置mode变量的值就可以了。

# 纹理的重复度

设置纹理的重复度是通过set prop拼图修改repeat属性实现的。拼图如下:

mark

# 纹理重置

纹理重置即恢复纹理的默认属性设置,在这里包含恢复纹理的重复度为no-repeat,恢复纹理的变换。这两个操作我们分别使用set prop拼图和reset transform拼图来实现。

mark

# 清除纹理

清除纹理可以使用插件提供的clear texture拼图实现。

mark

至此,示例程序的全部功能就都实现了。这里面要留意一些小细节,比如标记图片加载状态的变量(imageLoaded)和标记图片重复度的变量(repeat),有时,你会在调试的时候发现一些小问题,就需要加入一些这样的代码。

上次更新: 2021/5/6 下午2:35:11