本文概述
尽管这种T恤设计器有多种实现, 其中包括SVG, 使用JavaScript甚至是Flash(Ewww)的纯画布操作等多种技术, 但其中大多数都包含至少对于新手开发人员而言难以理解的内容。旨在从更简单的代码开始。为了帮助开发人员开始一个非常简单的项目来使用JavaScript设计自定义T恤, 在Fabric.js的帮助下操作画布将是最简单的方法之一。
在本文中, 我们将简要介绍如何在Web应用程序中使用Fabric.js库从头开始创建自己的T恤设计器。
要求
本教程基本上将与Fabric.js库一起使用。 Fabric.js是一个框架, 可让你轻松使用HTML5 canvas元素。它是画布元素顶部的交互式对象模型。它也是SVG画布解析器。你可以从Github仓库的官方版本页面下载最新版本的Fabric.js。然后, 只需在脚本中包含带有script标签的脚本即可:
<!-- Include Fabric.js in the page -->
<script src="./fabric.min.js"></script>
你还将需要透明T恤的背景图像, 在我们的情况下, 将是以下图像, 当然, 只要你具有相同的透明样式, 就可以使用自己的T恤设计(另存为background_tshirt.png):
注意:直接下载图片, 因为其中包含透明度, 因此, 在这种情况下, 由于我们的网站背景为黑色, 因此你会看到T恤为黑色, 在编写一些代码后, 你会看到它工作。
在本教程中, 我们将实现2种Tee设计器, 一种允许用户以动态方式上传图像或调整其大小, 或者使用分辨率由应用程序管理器定义的固定图片来调整其大小。
A.静态映像的实现
对于我们的第一个实现, 对某些人可能有用而对其他人却无用的实现将基于以下条件:
- 用户将无法上传自己的图像。
- 你是设计将放置在T恤上的图片的人。
- 所有图片都将具有相同的分辨率, 在我们的情况下为580×1025(宽*高), 以获得良好的质量。
- 用户无法调整T恤上图像的大小。
第一步, 我们将定义T恤设计器的容器, 该容器由以下标记指定:
<!-- Create the container of the tool -->
<div id="tshirt-div">
<!--
Initially, the image will have the background tshirt that has transparency
So we can simply update the color with CSS or JavaScript dinamically
-->
<img id="tshirt-backgroundpicture" src="./background_tshirt.png"/>
<!--
The container where Fabric.js will work. Notice that in the the style of #canvas
the width and height need to match with the attributes
-->
<div id="drawingArea" class="drawing-area">
<div class="canvas-container">
<canvas id="canvas" width="200" height="400"></canvas>
</div>
</div>
</div>
此标记需要特殊的CSS才能正常工作, 因为容器内部将有一些div, 而这些div需要重叠。使它起作用的CSS将是以下之一:
.drawing-area{
position: absolute;
top: 60px;
left: 122px;
z-index: 10;
width: 200px;
height: 400px;
}
.canvas-container{
width: 200px;
height: 400px;
position: relative;
user-select: none;
}
#tshirt-div{
width: 452px;
height: 548px;
position: relative;
background-color: #fff;
}
#canvas{
position: absolute;
width: 200px;
height: 400px;
left: 0px;
top: 0px;
user-select: none;
cursor: default;
}
到此为止, 我们将拥有以前的标记和样式, 这是一个非常简单的HTML结构, 如下所示:
如前所述, 画布将覆盖div和T恤的图像背景。现在, 我们还将在页面上添加2个新控件, 共2个选择, 第一个选择允许用户仅使用CSS和JavaScript来指定T恤的颜色, 第二个选择使用户可以选择从你自己的图片集中在T恤上加载单个图像:
<!--
The select that will allow the user to pick one of the static designs
In our case, we only offer a single picture, namely the logo of Batman
-->
<label for="tshirt-design">T-Shirt Design:</label>
<select id="tshirt-design">
<option value="">Select one of our designs ...</option>
<option value="./batman.png">Batman</option>
</select>
<!-- The Select that allows the user to change the color of the T-Shirt -->
<label for="tshirt-color">T-Shirt Color:</label>
<select id="tshirt-color">
<!-- You can add any color with a new option and definings its hex code -->
<option value="#fff">White</option>
<option value="#000">Black</option>
<option value="#f00">Red</option>
<option value="#008000">Green</option>
<option value="#ff0">Yellow</option>
</select>
T恤的颜色选择器允许你作为开发人员通过简单地添加新选项并将其以十六进制表示为值来添加T恤的新颜色。 T恤设计选择, 允许用户选择可以在T恤上绘制的设计之一。对于具体的实现, 建议使用图片的上述尺寸, 例如, 在我们的案例中, Batman徽标如下:
它将完全适合我们的T恤。现在, 我们需要开始处理项目的JavaScript逻辑:
// Select the canvas an make it accesible for all the snippets of this article
let canvas = new fabric.Canvas('tshirt-canvas');
/**
* Method that defines a picture as background image of the canvas.
*
* @param {String} imageUrl The server URL of the image that you want to load on the T-Shirt.
*
* @return {void} Return value description.
*/
function updateTshirtImage(imageURL){
// If the user doesn't pick an option of the select, clear the canvas
if(!imageURL){
canvas.clear();
}
// Create a new image that can be used in Fabric with the URL
fabric.Image.fromURL(imageURL, function(img) {
// Define the image as background image of the Canvas
canvas.setBackgroundImage(img, canvas.renderAll.bind(canvas), {
// Scale the image to the canvas size
scaleX: canvas.width / img.width, scaleY: canvas.height / img.height
});
});
}
在这段代码中, 我们在script标签中本地显示了Fabric的画布, 我们将在其中运行该项目的代码。所有代码都依赖于包含Fabric.js实例的canvas变量, 包括updateTshirtImage方法, 该方法在T恤上绘制你的一种设计。现在, 我们将需要在文档中注册2个事件监听器, 它们将对先前添加的两个选择中的选项更改做出反应:
// 1. When the T-Shirt color select changes:
// Update the TShirt color according to the selected color by the user
document.getElementById("tshirt-color").addEventListener("change", function(){
document.getElementById("tshirt-div").style.backgroundColor = this.value;
}, false);
// 2. When the user picks a design:
// Update the TShirt background image according to the selected image by the user
document.getElementById("tshirt-design").addEventListener("change", function(){
// Call the updateTshirtImage method providing as first argument the URL
// of the image provided by the select
updateTshirtImage(this.value);
}, false);
有了我们项目中的所有这些代码, 我们最终将获得一个带有以下标记的文档:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Static Tee Designer</title>
<style>
.drawing-area{
position: absolute;
top: 60px;
left: 122px;
z-index: 10;
width: 200px;
height: 400px;
}
.canvas-container{
width: 200px;
height: 400px;
position: relative;
user-select: none;
}
#tshirt-div{
width: 452px;
height: 548px;
position: relative;
background-color: #fff;
}
#canvas{
position: absolute;
width: 200px;
height: 400px;
left: 0px;
top: 0px;
user-select: none;
cursor: default;
}
</style>
</head>
<body>
<!-- Create the container of the tool -->
<div id="tshirt-div">
<!--
Initially, the image will have the background tshirt that has transparency
So we can simply update the color with CSS or JavaScript dinamically
-->
<img id="tshirt-backgroundpicture" src="./background_tshirt.png"/>
<div id="drawingArea" class="drawing-area">
<div class="canvas-container">
<canvas id="tshirt-canvas" width="200" height="400"></canvas>
</div>
</div>
</div>
<!-- The select that will allow the user to pick one of the static designs -->
<br>
<label for="tshirt-design">T-Shirt Design:</label>
<select id="tshirt-design">
<option value="">Select one of our designs ...</option>
<option value="./batman.png">Batman</option>
</select>
<!-- The Select that allows the user to change the color of the T-Shirt -->
<br><br>
<label for="tshirt-color">T-Shirt Color:</label>
<select id="tshirt-color">
<!-- You can add any color with a new option and definings its hex code -->
<option value="#fff">White</option>
<option value="#000">Black</option>
<option value="#f00">Red</option>
<option value="#008000">Green</option>
<option value="#ff0">Yellow</option>
</select>
<!-- Include Fabric.js in the page -->
<script src="./fabric.min.js"></script>
<script>
let canvas = new fabric.Canvas('tshirt-canvas');
function updateTshirtImage(imageURL){
// If the user doesn't pick an option of the select, clear the canvas
if(!imageURL){
canvas.clear();
}
// Create a new image that can be used in Fabric with the URL
fabric.Image.fromURL(imageURL, function(img) {
// Define the image as background image of the Canvas
canvas.setBackgroundImage(img, canvas.renderAll.bind(canvas), {
// Scale the image to the canvas size
scaleX: canvas.width / img.width, scaleY: canvas.height / img.height
});
});
}
// Update the TShirt color according to the selected color by the user
document.getElementById("tshirt-color").addEventListener("change", function(){
document.getElementById("tshirt-div").style.backgroundColor = this.value;
}, false);
// Update the TShirt color according to the selected color by the user
document.getElementById("tshirt-design").addEventListener("change", function(){
// Call the updateTshirtImage method providing as first argument the URL
// of the image provided by the select
updateTshirtImage(this.value);
}, false);
</script>
</body>
</html>
本文档将使用所有资源生成一个非常简单的T恤设计器, 该设计器具有静态设计和颜色, 你可以通过选择输入来更改它们:
B.动态图像实现
但是, 如果你不是由谁来决定将在T恤衫上显示哪种尺寸以及哪种尺寸的照片呢?好吧, 那么我们显然需要针对这种情况的更动态解决方案!此实现将基于以下条件:
- 用户应该能够上传自定义图片, 并将其放置在T恤上。
- 用户将能够调整图像大小并加载你自己的设计。
在这种情况下, 我们将从与第一个实现相同的标记开始:
<!-- Create the container of the tool -->
<div id="tshirt-div">
<!--
Initially, the image will have the background tshirt that has transparency
So we can simply update the color with CSS or JavaScript dinamically
-->
<img id="tshirt-backgroundpicture" src="./background_tshirt.png"/>
<!--
The container where Fabric.js will work. Notice that in the the style of #canvas
the width and height need to match with the attributes
-->
<div id="drawingArea" class="drawing-area">
<div class="canvas-container">
<canvas id="canvas" width="200" height="400"></canvas>
</div>
</div>
</div>
和相同的CSS:
.drawing-area{
position: absolute;
top: 60px;
left: 122px;
z-index: 10;
width: 200px;
height: 400px;
}
.canvas-container{
width: 200px;
height: 400px;
position: relative;
user-select: none;
}
#tshirt-div{
width: 452px;
height: 548px;
position: relative;
background-color: #fff;
}
#canvas{
position: absolute;
width: 200px;
height: 400px;
left: 0px;
top: 0px;
user-select: none;
cursor: default;
}
这些控件也将相同, 但是将存在另一个控件, 该控件将允许用户上传自定义图片以添加到T恤中:
<p>To remove a loaded picture on the T-Shirt select it and press the <kbd>DEL</kbd> key.</p>
<!-- The select that will allow the user to pick one of the static designs -->
<br>
<label for="tshirt-design">T-Shirt Design:</label>
<select id="tshirt-design">
<option value="">Select one of our designs ...</option>
<option value="./batman_small.png">Batman</option>
</select>
<!-- The Select that allows the user to change the color of the T-Shirt -->
<br><br>
<label for="tshirt-color">T-Shirt Color:</label>
<select id="tshirt-color">
<!-- You can add any color with a new option and definings its hex code -->
<option value="#fff">White</option>
<option value="#000">Black</option>
<option value="#f00">Red</option>
<option value="#008000">Green</option>
<option value="#ff0">Yellow</option>
</select>
<br><br>
<label for="tshirt-custompicture">Upload your own design:</label>
<input type="file" id="tshirt-custompicture" />
现在, 对于JavaScript逻辑, 我们将使用几乎相同的功能从Web URL加载图像, 但稍作修改, 因为我们将图像作为对象作为对象处理, 而不是将图像作为Fabric.js的背景加载。面料帆布:
// Select the canvas an make it accesible for all the snippets of this article
let canvas = new fabric.Canvas('tshirt-canvas');
/**
* Method that adds an image to the T-Shirt canvas from a web URL.
*
* @param {String} imageUrl The server URL of the image that you want to load on the T-Shirt.
*
* @return {void} Return value description.
*/
function updateTshirtImage(imageURL){
fabric.Image.fromURL(imageURL, function(img) {
img.scaleToHeight(300);
img.scaleToWidth(300);
canvas.centerObject(img);
canvas.add(img);
canvas.renderAll();
});
}
我们还将添加多个侦听器, 它们的工作方式如下:
- T恤颜色选择将通过CSS更改T恤的颜色。
- T恤设计选择将从你自己的设计(而不是用户设计)中的Fabric.js画布中加载可调整大小的对象。
- T恤自定义图片文件输入将允许用户从PC中选择自定义图片以直接加载到T恤中。
- 当用户按下德尔 键入文档中的键(键代码46), Fabric.js画布上的选定元素将被删除。
// Update the TShirt color according to the selected color by the user
document.getElementById("tshirt-color").addEventListener("change", function(){
document.getElementById("tshirt-div").style.backgroundColor = this.value;
}, false);
// Update the TShirt color according to the selected color by the user
document.getElementById("tshirt-design").addEventListener("change", function(){
// Call the updateTshirtImage method providing as first argument the URL
// of the image provided by the select
updateTshirtImage(this.value);
}, false);
// When the user clicks on upload a custom picture
document.getElementById('tshirt-custompicture').addEventListener("change", function(e){
var reader = new FileReader();
reader.onload = function (event){
var imgObj = new Image();
imgObj.src = event.target.result;
// When the picture loads, create the image in Fabric.js
imgObj.onload = function () {
var img = new fabric.Image(imgObj);
img.scaleToHeight(300);
img.scaleToWidth(300);
canvas.centerObject(img);
canvas.add(img);
canvas.renderAll();
};
};
// If the user selected a picture, load it
if(e.target.files[0]){
reader.readAsDataURL(e.target.files[0]);
}
}, false);
// When the user selects a picture that has been added and press the DEL key
// The object will be removed !
document.addEventListener("keydown", function(e) {
var keyCode = e.keyCode;
if(keyCode == 46){
console.log("Removing selected element on Fabric.js on DELETE key !");
canvas.remove(canvas.getActiveObject());
}
}, false);
最后, 在我们的项目中使用所有这些代码之后, 动态T恤设计器将允许用户上传自己的图片并根据需要调整其大小, 最终结果如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Dynamic and Resizable Tee Designer</title>
<style>
.drawing-area{
position: absolute;
top: 60px;
left: 122px;
z-index: 10;
width: 200px;
height: 400px;
}
.canvas-container{
width: 200px;
height: 400px;
position: relative;
user-select: none;
}
#tshirt-div{
width: 452px;
height: 548px;
position: relative;
background-color: #fff;
}
#canvas{
position: absolute;
width: 200px;
height: 400px;
left: 0px;
top: 0px;
user-select: none;
cursor: default;
}
</style>
</head>
<body>
<!-- Create the container of the tool -->
<div id="tshirt-div">
<!--
Initially, the image will have the background tshirt that has transparency
So we can simply update the color with CSS or JavaScript dinamically
-->
<img id="tshirt-backgroundpicture" src="./background_tshirt.png"/>
<div id="drawingArea" class="drawing-area">
<div class="canvas-container">
<canvas id="tshirt-canvas" width="200" height="400"></canvas>
</div>
</div>
</div>
<p>To remove a loaded picture on the T-Shirt select it and press the <kbd>DEL</kbd> key.</p>
<!-- The select that will allow the user to pick one of the static designs -->
<br>
<label for="tshirt-design">T-Shirt Design:</label>
<select id="tshirt-design">
<option value="">Select one of our designs ...</option>
<option value="./batman_small.png">Batman</option>
</select>
<!-- The Select that allows the user to change the color of the T-Shirt -->
<br><br>
<label for="tshirt-color">T-Shirt Color:</label>
<select id="tshirt-color">
<!-- You can add any color with a new option and definings its hex code -->
<option value="#fff">White</option>
<option value="#000">Black</option>
<option value="#f00">Red</option>
<option value="#008000">Green</option>
<option value="#ff0">Yellow</option>
</select>
<br><br>
<label for="tshirt-custompicture">Upload your own design:</label>
<input type="file" id="tshirt-custompicture" />
<!-- Include Fabric.js in the page -->
<script src="./fabric.min.js"></script>
<script>
let canvas = new fabric.Canvas('tshirt-canvas');
function updateTshirtImage(imageURL){
fabric.Image.fromURL(imageURL, function(img) {
img.scaleToHeight(300);
img.scaleToWidth(300);
canvas.centerObject(img);
canvas.add(img);
canvas.renderAll();
});
}
// Update the TShirt color according to the selected color by the user
document.getElementById("tshirt-color").addEventListener("change", function(){
document.getElementById("tshirt-div").style.backgroundColor = this.value;
}, false);
// Update the TShirt color according to the selected color by the user
document.getElementById("tshirt-design").addEventListener("change", function(){
// Call the updateTshirtImage method providing as first argument the URL
// of the image provided by the select
updateTshirtImage(this.value);
}, false);
// When the user clicks on upload a custom picture
document.getElementById('tshirt-custompicture').addEventListener("change", function(e){
var reader = new FileReader();
reader.onload = function (event){
var imgObj = new Image();
imgObj.src = event.target.result;
// When the picture loads, create the image in Fabric.js
imgObj.onload = function () {
var img = new fabric.Image(imgObj);
img.scaleToHeight(300);
img.scaleToWidth(300);
canvas.centerObject(img);
canvas.add(img);
canvas.renderAll();
};
};
// If the user selected a picture, load it
if(e.target.files[0]){
reader.readAsDataURL(e.target.files[0]);
}
}, false);
// When the user selects a picture that has been added and press the DEL key
// The object will be removed !
document.addEventListener("keydown", function(e) {
var keyCode = e.keyCode;
if(keyCode == 46){
console.log("Removing selected element on Fabric.js on DELETE key !");
canvas.remove(canvas.getActiveObject());
}
}, false);
</script>
</body>
</html>
生成类似于以下内容的应用程序:
导出T恤图像
最后一步, 一旦用户设计了T恤, 每个人都需要导出设计的图片。为了在我们的两个实现中使用JavaScript轻松导出它, 我们建议你使用DomToImage库。 dom-to-image是一个库, 可以将任意DOM节点转换为用JavaScript编写的矢量(SVG)或光栅(PNG或JPEG)图像。它基于Paul Bakaus的domvas进行了完全重写, 已修复了一些错误, 并添加了一些新功能(如Web字体和图像支持)。
你可以在此处从Github的存储库的官方发行版页面下载此库, 然后将该脚本包含在你的文档中:
<!-- Include DomToImage in the page -->
<script src="./domtoimage.min.js"></script>
并将其导出为所需的格式, 例如PNG, JPEG, 然后从T恤创建图片, 例如PNG:
// Define as node the T-Shirt Div
var node = document.getElementById('tshirt-div');
domtoimage.toPng(node).then(function (dataUrl) {
// Print the data URL of the picture in the Console
console.log(dataUrl);
// You can for example to test, add the image at the end of the document
var img = new Image();
img.src = dataUrl;
document.body.appendChild(img);
}).catch(function (error) {
console.error('oops, something went wrong!', error);
});
变量dataUrl包含PNG格式的Base64图像, 例如库生成的图像的data:image / png; base64, iVBORw0KGg。你可以查看库的文档, 以了解有关使用JavaScript导出图片的不同方式的更多信息。使用此工具导出的图像的示例:
编码愉快!
评论前必须登录!
注册