文章目录[隐藏]
一步步教你,集成在线设计工具与模板编辑器到你的网站,通过WordPress程序的代码二次开发实现常用互联网小工具功能
引言:为什么你的网站需要集成设计工具与编辑器?
在当今数字化时代,用户体验已成为网站成功的关键因素。无论是电商平台、内容发布网站还是企业官网,用户都期望获得更加个性化、互动性强的在线体验。集成在线设计工具与模板编辑器,可以让你的网站从“静态展示”转变为“动态创作平台”,从而显著提升用户参与度、延长停留时间并提高转化率。
想象一下,一个服装电商网站允许用户自定义T恤图案;一个营销公司网站让客户在线设计宣传海报;一个博客平台提供个性化的文章模板编辑器——这些功能不仅提升了网站的实用价值,也创造了独特的竞争优势。通过WordPress这一全球最流行的内容管理系统,我们可以通过代码二次开发,相对高效地实现这些高级功能。
本文将详细指导你如何一步步在WordPress网站中集成在线设计工具与模板编辑器,并实现一系列常用互联网小工具功能。无论你是WordPress开发者、网站管理员还是有一定技术基础的企业主,都能从本指南中获得实用的解决方案。
第一部分:前期准备与环境搭建
1.1 理解核心概念:什么是在线设计工具与模板编辑器?
在线设计工具是一种基于Web的应用程序,允许用户在浏览器中直接创建和编辑视觉内容,无需安装专业设计软件。常见的功能包括:拖放元素、调整尺寸、更改颜色、添加文字和上传图片等。而模板编辑器则是预设了布局和样式的设计工具,用户可以在模板基础上进行个性化修改,大大降低了设计门槛。
在WordPress中集成这类工具,意味着将这些功能无缝嵌入到你的网站页面中,让访问者能够直接使用。这通常需要结合前端界面库、后端处理逻辑和数据库存储等技术组件。
1.2 开发环境准备
在开始编码之前,你需要搭建合适的开发环境:
- 本地开发环境:建议使用Local by Flywheel、XAMPP或MAMP等工具,在本地计算机上搭建WordPress运行环境。这样可以避免在线上网站直接调试可能带来的风险。
- 代码编辑器:选择一款强大的代码编辑器,如Visual Studio Code、PHPStorm或Sublime Text。确保安装相关插件,如PHP智能提示、CSS自动补全和Git集成等。
- 浏览器开发者工具:熟悉Chrome或Firefox的开发者工具,这对前端调试至关重要。
- 版本控制系统:初始化Git仓库来管理代码变更,这是专业开发的基本实践。
- 备份方案:确保你有完整的网站备份,包括文件和数据库,以防开发过程中出现不可逆的错误。
1.3 创建子主题或自定义插件
为了避免主题更新覆盖你的修改,最佳实践是创建一个子主题或自定义插件:
创建子主题的方法:
- 在
/wp-content/themes/目录下创建新文件夹,如my-custom-design-tool -
创建
style.css文件,添加主题信息头:/* Theme Name: 我的设计工具子主题 Template: parent-theme-folder-name */ - 创建
functions.php文件,用于添加自定义功能
创建自定义插件的方法:
- 在
/wp-content/plugins/目录下创建新文件夹,如design-tool-integration -
创建主插件文件
design-tool-integration.php:<?php /** * Plugin Name: 设计工具集成插件 * Description: 为WordPress网站集成在线设计工具和模板编辑器 */
第二部分:集成基础在线设计工具
2.1 选择合适的前端设计库
集成设计工具的第一步是选择合适的前端库。以下是几个优秀的选择:
- Fabric.js:一个强大的Canvas库,专门用于创建交互式设计工具。它提供了丰富的对象模型、序列化功能和交互控制。
- Konva.js:另一个基于Canvas的2D绘图库,性能优异,支持桌面和移动设备。
- tldraw:开源的绘图库,提供流畅的绘图体验和丰富的图形工具。
- PixiJS:专注于性能的2D渲染引擎,适合需要处理大量图形元素的复杂设计工具。
对于大多数应用场景,Fabric.js提供了最全面的功能集和活跃的社区支持。我们将以Fabric.js为例进行后续讲解。
2.2 在WordPress中引入Fabric.js
有几种方法可以将Fabric.js引入WordPress:
方法一:使用CDN链接(最简单)
在主题或插件的PHP文件中添加:
function enqueue_design_tool_scripts() {
wp_enqueue_script('fabric-js', 'https://cdnjs.cloudflare.com/ajax/libs/fabric.js/4.5.0/fabric.min.js', array(), '4.5.0', true);
wp_enqueue_script('design-tool-main', get_stylesheet_directory_uri() . '/js/design-tool.js', array('fabric-js', 'jquery'), '1.0.0', true);
wp_enqueue_style('design-tool-style', get_stylesheet_directory_uri() . '/css/design-tool.css');
}
add_action('wp_enqueue_scripts', 'enqueue_design_tool_scripts');
方法二:本地托管(推荐,更稳定)
- 从Fabric.js官网下载最新版本
- 将文件放入主题的
/js/目录 - 修改上述代码中的CDN链接为本地路径
2.3 创建基础画布编辑器
接下来,我们创建一个基础的设计画布。首先,在页面模板中添加画布容器:
// 在主题模板文件中添加
function render_design_tool() {
ob_start(); ?>
<div class="design-tool-container">
<div class="tool-header">
<h2>在线设计工具</h2>
</div>
<div class="tool-body">
<div class="tool-sidebar">
<!-- 工具选项将在这里添加 -->
</div>
<div class="tool-main">
<canvas id="design-canvas" width="800" height="600"></canvas>
</div>
</div>
<div class="tool-footer">
<button id="save-design" class="btn btn-primary">保存设计</button>
<button id="export-png" class="btn btn-secondary">导出PNG</button>
</div>
</div>
<?php
return ob_get_clean();
}
add_shortcode('design_tool', 'render_design_tool');
然后,创建JavaScript文件初始化画布:
// js/design-tool.js
jQuery(document).ready(function($) {
// 初始化画布
var canvas = new fabric.Canvas('design-canvas', {
backgroundColor: '#ffffff',
preserveObjectStacking: true
});
// 设置画布尺寸
canvas.setDimensions({
width: 800,
height: 600
}, {
cssOnly: false
});
// 添加矩形工具
$('#add-rectangle').on('click', function() {
var rect = new fabric.Rect({
left: 100,
top: 100,
fill: '#ff0000',
width: 100,
height: 100
});
canvas.add(rect);
canvas.setActiveObject(rect);
});
// 添加文字工具
$('#add-text').on('click', function() {
var text = new fabric.Textbox('双击编辑文字', {
left: 50,
top: 50,
width: 200,
fontSize: 20,
fill: '#000000'
});
canvas.add(text);
canvas.setActiveObject(text);
});
// 保存设计到服务器
$('#save-design').on('click', function() {
var designData = JSON.stringify(canvas.toJSON());
$.ajax({
url: designToolAjax.ajax_url,
type: 'POST',
data: {
action: 'save_design',
design_data: designData,
nonce: designToolAjax.nonce
},
success: function(response) {
if(response.success) {
alert('设计已保存!');
} else {
alert('保存失败:' + response.data);
}
}
});
});
// 导出为PNG
$('#export-png').on('click', function() {
var dataURL = canvas.toDataURL({
format: 'png',
quality: 1
});
// 创建下载链接
var link = document.createElement('a');
link.download = 'my-design.png';
link.href = dataURL;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
});
});
2.4 实现后端保存功能
设计数据需要保存到服务器。在WordPress中,我们使用AJAX处理:
// 在functions.php或插件文件中添加
function save_design_callback() {
// 验证nonce
if (!wp_verify_nonce($_POST['nonce'], 'design_tool_nonce')) {
wp_die('安全验证失败');
}
$design_data = json_decode(stripslashes($_POST['design_data']), true);
// 获取当前用户ID
$user_id = get_current_user_id();
// 创建或更新设计
$design_id = wp_insert_post(array(
'post_type' => 'design',
'post_title' => '用户设计 ' . current_time('mysql'),
'post_status' => 'publish',
'post_author' => $user_id,
'meta_input' => array(
'_design_data' => $design_data,
'_design_preview' => generate_design_preview($design_data) // 生成预览图
)
));
if ($design_id) {
wp_send_json_success(array(
'design_id' => $design_id,
'message' => '设计保存成功'
));
} else {
wp_send_json_error('保存失败');
}
}
add_action('wp_ajax_save_design', 'save_design_callback');
add_action('wp_ajax_nopriv_save_design', 'save_design_callback'); // 如果允许未登录用户保存
// 注册设计自定义文章类型
function register_design_post_type() {
register_post_type('design',
array(
'labels' => array(
'name' => __('设计作品'),
'singular_name' => __('设计')
),
'public' => true,
'has_archive' => true,
'supports' => array('title', 'thumbnail'),
'show_in_rest' => true // 启用Gutenberg编辑器支持
)
);
}
add_action('init', 'register_design_post_type');
第三部分:构建模板编辑器系统
3.1 设计模板数据结构
模板编辑器需要一种结构化的方式来定义模板。我们使用JSON格式存储模板配置:
// 示例模板数据结构
$template_structure = array(
'name' => '社交媒体海报模板',
'width' => 1200,
'height' => 630,
'backgroundColor' => '#ffffff',
'objects' => array(
array(
'type' => 'image',
'src' => '/templates/images/placeholder.jpg',
'left' => 100,
'top' => 100,
'width' => 400,
'height' => 300,
'editable' => true,
'properties' => array(
'replaceable' => true,
'minWidth' => 100,
'minHeight' => 100
)
),
array(
'type' => 'textbox',
'text' => '点击编辑标题',
'left' => 550,
'top' => 150,
'fontSize' => 48,
'fontFamily' => 'Arial',
'fill' => '#333333',
'editable' => true,
'properties' => array(
'maxLength' => 100,
'textAlign' => 'center'
)
)
)
);
3.2 创建模板管理界面
我们需要一个管理界面来创建和管理模板。使用WordPress的Admin API创建管理页面:
// 添加模板管理菜单
function add_template_admin_menu() {
add_menu_page(
'设计模板管理',
'设计模板',
'manage_options',
'design-templates',
'render_template_admin_page',
'dashicons-layout',
30
);
add_submenu_page(
'design-templates',
'添加新模板',
'添加模板',
'manage_options',
'add-design-template',
'render_add_template_page'
);
}
add_action('admin_menu', 'add_template_admin_menu');
// 渲染模板管理页面
function render_template_admin_page() {
?>
<div class="wrap">
<h1 class="wp-heading-inline">设计模板管理</h1>
<a href="<?php echo admin_url('admin.php?page=add-design-template'); ?>" class="page-title-action">添加新模板</a>
<table class="wp-list-table widefat fixed striped">
<thead>
<tr>
<th>ID</th>
<th>模板名称</th>
<th>尺寸</th>
<th>创建时间</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<?php
$templates = get_posts(array(
'post_type' => 'design_template',
'posts_per_page' => -1
));
foreach ($templates as $template) {
$template_data = get_post_meta($template->ID, '_template_data', true);
?>
<tr>
<td><?php echo $template->ID; ?></td>
<td><?php echo $template->post_title; ?></td>
<td><?php echo isset($template_data['width']) ? $template_data['width'] . '×' . $template_data['height'] : '未设置'; ?></td>
<td><?php echo $template->post_date; ?></td>
<td>
<a href="<?php echo admin_url('admin.php?page=add-design-template&template_id=' . $template->ID); ?>">编辑</a> |
<a href="#" class="delete-template" data-id="<?php echo $template->ID; ?>">删除</a> |
<a href="#" class="preview-template" data-id="<?php echo $template->ID; ?>">预览</a>
</td>
</tr>
<?php
}
?>
</tbody>
</table>
</div>
<?php
}
3.3 实现模板加载与应用
在前端,我们需要从服务器加载模板并应用到画布:
// 加载模板功能
function loadTemplate(templateId) {
$.ajax({
url: designToolAjax.ajax_url,
type: 'GET',
data: {
action: 'load_template',
template_id: templateId
},
success: function(response) {
if(response.success) {
// 清空当前画布
canvas.clear();
// 设置画布尺寸
canvas.setWidth(response.data.width);
canvas.setHeight(response.data.height);
// 设置背景色
canvas.setBackgroundColor(response.data.backgroundColor, canvas.renderAll.bind(canvas));
// 加载模板对象
fabric.util.enlivenObjects(response.data.objects, function(objects) {
objects.forEach(function(obj) {
canvas.add(obj);
});
canvas.renderAll();
});
}
}
});
}
// 模板选择器UI
function renderTemplateSelector() {
$.ajax({
url: designToolAjax.ajax_url,
type: 'GET',
data: {
action: 'get_templates'
},
success: function(response) {
if(response.success) {
var $selector = $('#template-selector');
$selector.empty();
response.data.forEach(function(template) {
$selector.append(
'<div class="template-thumbnail" data-id="' + template.id + '">' +
'<img src="' + template.thumbnail + '" alt="' + template.name + '">' +
'<div class="template-name">' + template.name + '</div>' +
'</div>'
);
});
// 绑定点击事件
$('.template-thumbnail').on('click', function() {
var templateId = $(this).data('id');
loadTemplate(templateId);
});
}
}
});
}
第四部分:集成常用互联网小工具功能
4.1 图像处理工具集成
现代设计工具离不开图像处理功能。我们可以集成一些常见的图像处理工具:
// 图像处理功能后端
function process_image_callback() {
$action = $_POST['action_type'];
$image_data = $_POST['image_data'];
// 解码base64图像
$image_data = str_replace('data:image/png;base64,', '', $image_data);
$image_data = str_replace(' ', '+', $image_data);
$image_binary = base64_decode($image_data);
// 使用GD库处理图像
$image = imagecreatefromstring($image_binary);
switch($action) {
case 'grayscale':
imagefilter($image, IMG_FILTER_GRAYSCALE);
break;
case 'sepia':
// 实现棕褐色滤镜
imagefilter($image, IMG_FILTER_GRAYSCALE);
imagefilter($image, IMG_FILTER_COLORIZE, 112, 66, 20);
break;
case 'brightness':
$level = intval($_POST['level']);
imagefilter($image, IMG_FILTER_BRIGHTNESS, $level);
break;
case 'crop':
$x = intval($_POST['x']);
$y = intval($_POST['y']);
$width = intval($_POST['width']);
$height = intval($_POST['height']);
$image = imagecrop($image, ['x' => $x, 'y' => $y, 'width' => $width, 'height' => $height]);
4.2 字体管理与Google Fonts集成
设计工具中字体选择是核心功能。我们可以集成Google Fonts API,提供丰富的字体选择:
// 字体管理功能
class Font_Manager {
private $google_fonts_api_key = 'YOUR_GOOGLE_API_KEY';
public function __construct() {
add_action('wp_ajax_get_google_fonts', array($this, 'get_google_fonts_callback'));
add_action('wp_ajax_load_font_to_canvas', array($this, 'load_font_to_canvas_callback'));
}
// 获取Google Fonts列表
public function get_google_fonts_callback() {
$transient_key = 'google_fonts_list';
$fonts = get_transient($transient_key);
if (false === $fonts) {
$response = wp_remote_get(
'https://www.googleapis.com/webfonts/v1/webfonts?key=' . $this->google_fonts_api_key . '&sort=popularity'
);
if (!is_wp_error($response)) {
$body = wp_remote_retrieve_body($response);
$fonts_data = json_decode($body, true);
$fonts = array();
foreach ($fonts_data['items'] as $font) {
$fonts[] = array(
'family' => $font['family'],
'variants' => $font['variants'],
'category' => $font['category']
);
}
// 缓存24小时
set_transient($transient_key, $fonts, DAY_IN_SECONDS);
}
}
wp_send_json_success($fonts);
}
// 动态加载字体到画布
public function load_font_to_canvas_callback() {
$font_family = sanitize_text_field($_POST['font_family']);
$font_variant = sanitize_text_field($_POST['font_variant']);
// 生成字体CSS URL
$font_url = $this->generate_font_css_url($font_family, $font_variant);
// 将字体添加到页面
$font_face_css = "
@font-face {
font-family: '{$font_family}';
src: url('{$font_url}');
}";
wp_send_json_success(array(
'font_css' => $font_face_css,
'font_family' => $font_family
));
}
private function generate_font_css_url($family, $variant) {
$family_encoded = str_replace(' ', '+', $family);
return "https://fonts.googleapis.com/css2?family={$family_encoded}:wght@{$variant}&display=swap";
}
}
new Font_Manager();
前端字体选择器实现:
// 字体选择器组件
class FontSelector {
constructor(canvas) {
this.canvas = canvas;
this.fonts = [];
this.init();
}
async init() {
await this.loadFonts();
this.renderFontSelector();
}
async loadFonts() {
try {
const response = await $.ajax({
url: designToolAjax.ajax_url,
type: 'GET',
data: {
action: 'get_google_fonts'
}
});
if (response.success) {
this.fonts = response.data;
this.populateFontSelect();
}
} catch (error) {
console.error('加载字体失败:', error);
}
}
populateFontSelect() {
const $fontSelect = $('#font-family-select');
$fontSelect.empty();
// 添加系统字体
const systemFonts = ['Arial', 'Helvetica', 'Times New Roman', 'Georgia', 'Courier New'];
systemFonts.forEach(font => {
$fontSelect.append(`<option value="${font}">${font}</option>`);
});
// 添加Google Fonts
this.fonts.slice(0, 50).forEach(font => { // 限制显示数量
$fontSelect.append(`<option value="${font.family}">${font.family}</option>`);
});
}
renderFontSelector() {
const fontControls = `
<div class="font-controls">
<div class="font-control-group">
<label>字体:</label>
<select id="font-family-select" class="font-select">
<option value="Arial">Arial</option>
</select>
</div>
<div class="font-control-group">
<label>字号:</label>
<input type="range" id="font-size-slider" min="8" max="120" value="24">
<input type="number" id="font-size-input" value="24" min="8" max="120">
</div>
<div class="font-control-group">
<label>颜色:</label>
<input type="color" id="font-color-picker" value="#000000">
</div>
<div class="font-control-group">
<button id="bold-btn" class="font-style-btn">B</button>
<button id="italic-btn" class="font-style-btn">I</button>
<button id="underline-btn" class="font-style-btn">U</button>
</div>
</div>`;
$('.tool-sidebar').append(fontControls);
this.bindEvents();
}
bindEvents() {
// 字体选择变化
$('#font-family-select').on('change', async (e) => {
const fontFamily = $(e.target).val();
const activeObject = this.canvas.getActiveObject();
if (activeObject && activeObject.type === 'textbox') {
// 如果是Google Font,先加载
if (this.isGoogleFont(fontFamily)) {
await this.loadGoogleFont(fontFamily, '400');
}
activeObject.set('fontFamily', fontFamily);
this.canvas.renderAll();
}
});
// 字号调整
$('#font-size-slider, #font-size-input').on('input change', (e) => {
const fontSize = $(e.target).val();
const activeObject = this.canvas.getActiveObject();
if (activeObject && activeObject.type === 'textbox') {
activeObject.set('fontSize', parseInt(fontSize));
this.canvas.renderAll();
}
// 同步两个输入框的值
if (e.target.id === 'font-size-slider') {
$('#font-size-input').val(fontSize);
} else {
$('#font-size-slider').val(fontSize);
}
});
}
isGoogleFont(fontFamily) {
return this.fonts.some(font => font.family === fontFamily);
}
async loadGoogleFont(fontFamily, variant) {
try {
const response = await $.ajax({
url: designToolAjax.ajax_url,
type: 'POST',
data: {
action: 'load_font_to_canvas',
font_family: fontFamily,
font_variant: variant
}
});
if (response.success) {
// 动态添加字体CSS到页面
$('head').append(`<style>${response.data.font_css}</style>`);
return true;
}
} catch (error) {
console.error('加载Google字体失败:', error);
}
return false;
}
}
// 初始化字体选择器
const fontSelector = new FontSelector(canvas);
4.3 素材库与资源管理器
创建可搜索的素材库,包含图标、背景、贴纸等资源:
// 素材库管理
class Asset_Library {
private $asset_categories = array(
'icons' => '图标',
'backgrounds' => '背景',
'stickers' => '贴纸',
'shapes' => '形状',
'frames' => '边框'
);
public function __construct() {
add_action('init', array($this, 'register_asset_post_type'));
add_action('wp_ajax_search_assets', array($this, 'search_assets_callback'));
add_action('wp_ajax_upload_asset', array($this, 'upload_asset_callback'));
}
public function register_asset_post_type() {
register_post_type('design_asset',
array(
'labels' => array(
'name' => __('设计素材'),
'singular_name' => __('素材')
),
'public' => true,
'has_archive' => false,
'show_in_menu' => true,
'menu_position' => 31,
'menu_icon' => 'dashicons-images-alt2',
'supports' => array('title', 'thumbnail'),
'taxonomies' => array('asset_category'),
'show_in_rest' => true
)
);
// 注册素材分类
register_taxonomy('asset_category', 'design_asset',
array(
'labels' => array(
'name' => __('素材分类'),
'singular_name' => __('分类')
),
'hierarchical' => true,
'show_in_rest' => true
)
);
}
public function search_assets_callback() {
$search_term = sanitize_text_field($_GET['search']);
$category = sanitize_text_field($_GET['category']);
$page = intval($_GET['page']) ?: 1;
$per_page = 20;
$args = array(
'post_type' => 'design_asset',
'posts_per_page' => $per_page,
'paged' => $page,
'post_status' => 'publish'
);
if (!empty($search_term)) {
$args['s'] = $search_term;
}
if (!empty($category) && $category !== 'all') {
$args['tax_query'] = array(
array(
'taxonomy' => 'asset_category',
'field' => 'slug',
'terms' => $category
)
);
}
$query = new WP_Query($args);
$assets = array();
while ($query->have_posts()) {
$query->the_post();
$post_id = get_the_ID();
$assets[] = array(
'id' => $post_id,
'title' => get_the_title(),
'thumbnail' => get_the_post_thumbnail_url($post_id, 'medium'),
'full_url' => wp_get_attachment_url(get_post_thumbnail_id($post_id)),
'type' => $this->get_asset_type($post_id),
'category' => wp_get_post_terms($post_id, 'asset_category', array('fields' => 'names'))
);
}
wp_reset_postdata();
wp_send_json_success(array(
'assets' => $assets,
'total_pages' => $query->max_num_pages,
'current_page' => $page
));
}
private function get_asset_type($post_id) {
$mime_type = get_post_mime_type(get_post_thumbnail_id($post_id));
if (strpos($mime_type, 'image/svg') !== false) {
return 'svg';
} elseif (strpos($mime_type, 'image/') !== false) {
return 'image';
} else {
return 'other';
}
}
public function upload_asset_callback() {
// 检查用户权限
if (!current_user_can('upload_files')) {
wp_send_json_error('没有上传权限');
}
// 处理文件上传
if (!function_exists('wp_handle_upload')) {
require_once(ABSPATH . 'wp-admin/includes/file.php');
}
$uploadedfile = $_FILES['asset_file'];
$category = sanitize_text_field($_POST['category']);
$upload_overrides = array('test_form' => false);
$movefile = wp_handle_upload($uploadedfile, $upload_overrides);
if ($movefile && !isset($movefile['error'])) {
// 创建附件
$attachment = array(
'post_mime_type' => $movefile['type'],
'post_title' => sanitize_file_name($_POST['title']),
'post_content' => '',
'post_status' => 'inherit'
);
$attach_id = wp_insert_attachment($attachment, $movefile['file']);
// 生成缩略图
require_once(ABSPATH . 'wp-admin/includes/image.php');
$attach_data = wp_generate_attachment_metadata($attach_id, $movefile['file']);
wp_update_attachment_metadata($attach_id, $attach_data);
// 创建设计素材文章
$asset_post_id = wp_insert_post(array(
'post_type' => 'design_asset',
'post_title' => sanitize_text_field($_POST['title']),
'post_status' => 'publish',
'meta_input' => array(
'_asset_file_id' => $attach_id
)
));
// 设置特色图片
set_post_thumbnail($asset_post_id, $attach_id);
// 设置分类
if (!empty($category)) {
wp_set_post_terms($asset_post_id, array($category), 'asset_category');
}
wp_send_json_success(array(
'message' => '素材上传成功',
'asset_id' => $asset_post_id,
'url' => $movefile['url']
));
} else {
wp_send_json_error($movefile['error']);
}
}
}
new Asset_Library();
前端素材库界面:
// 素材库组件
class AssetLibrary {
constructor(canvas) {
this.canvas = canvas;
this.currentPage = 1;
this.totalPages = 1;
this.currentCategory = 'all';
this.searchTerm = '';
this.init();
}
init() {
this.renderLibraryUI();
this.loadAssets();
}
renderLibraryUI() {
const libraryHTML = `
<div class="asset-library">
<div class="library-header">
<h3>素材库</h3>
<div class="library-controls">
<input type="text" id="asset-search" placeholder="搜索素材...">
<select id="asset-category">
<option value="all">所有分类</option>
<option value="icons">图标</option>
<option value="backgrounds">背景</option>
<option value="stickers">贴纸</option>
<option value="shapes">形状</option>
<option value="frames">边框</option>
</select>
<button id="upload-asset-btn" class="btn-small">上传素材</button>
</div>
</div>
<div class="library-content" id="asset-grid">
<!-- 素材将在这里显示 -->
</div>
<div class="library-footer">
<div class="pagination">
<button id="prev-page" disabled>上一页</button>
<span id="page-info">第 1 页 / 共 1 页</span>
<button id="next-page" disabled>下一页</button>
</div>
</div>
</div>`;
$('.tool-sidebar').append(libraryHTML);
this.bindEvents();
}
bindEvents() {
// 搜索功能
$('#asset-search').on('keyup', debounce(() => {
this.searchTerm = $('#asset-search').val();
this.currentPage = 1;
this.loadAssets();
}, 500));
// 分类筛选
$('#asset-category').on('change', () => {
this.currentCategory = $('#asset-category').val();
this.currentPage = 1;
this.loadAssets();
});
// 分页
$('#prev-page').on('click', () => {
if (this.currentPage > 1) {
this.currentPage--;
this.loadAssets();
}
});
$('#next-page').on('click', () => {
if (this.currentPage < this.totalPages) {
this.currentPage++;
this.loadAssets();
}
});
// 上传素材
$('#upload-asset-btn').on('click', () => {
this.showUploadModal();
});
}
async loadAssets() {
try {
const response = await $.ajax({
url: designToolAjax.ajax_url,
type: 'GET',
data: {
action: 'search_assets',
search: this.searchTerm,
category: this.currentCategory,
page: this.currentPage
}
});
if (response.success) {
this.renderAssets(response.data.assets);
this.updatePagination(response.data);
}
} catch (error) {
console.error('加载素材失败:', error);
}
}
renderAssets(assets) {
const $assetGrid = $('#asset-grid');
$assetGrid.empty();
if (assets.length === 0) {
$assetGrid.html('<div class="no-assets">未找到素材</div>');
return;
}
assets.forEach(asset => {
const assetItem = `
<div class="asset-item" data-id="${asset.id}" data-url="${asset.full_url}" data-type="${asset.type}">
<div class="asset-thumbnail">
<img src="${asset.thumbnail}" alt="${asset.title}" loading="lazy">
</div>
<div class="asset-info">
<div class="asset-title">${asset.title}</div>
<div class="asset-category">${asset.category.join(', ')}</div>
</div>
</div>`;
$assetGrid.append(assetItem);
});
// 绑定点击事件
$('.asset-item').on('click', (e) => {
const $item = $(e.currentTarget);
this.addAssetToCanvas(
$item.data('url'),
$item.data('type')
);
});
}
addAssetToCanvas(url, type) {
