文章目录
-
- 在当今数字化时代,用户体验已成为网站成功的关键因素。无论是电商平台、内容发布网站还是企业官网,用户都期望获得更加个性化、互动性强的在线体验。集成在线设计工具与模板编辑器,可以让你的网站从“静态展示”转变为“动态创作平台”,从而显著提升用户参与度、延长停留时间并提高转化率。 想象一下,一个服装电商网站允许用户自定义T恤图案;一个营销公司网站让客户在线设计宣传海报;一个博客平台提供个性化的文章模板编辑器——这些功能不仅提升了网站的实用价值,也创造了独特的竞争优势。通过WordPress这一全球最流行的内容管理系统,我们可以通过代码二次开发,相对高效地实现这些高级功能。 本文将详细指导你如何一步步在WordPress网站中集成在线设计工具与模板编辑器,并实现一系列常用互联网小工具功能。无论你是WordPress开发者、网站管理员还是有一定技术基础的企业主,都能从本指南中获得实用的解决方案。
-
- 在线设计工具是一种基于Web的应用程序,允许用户在浏览器中直接创建和编辑视觉内容,无需安装专业设计软件。常见的功能包括:拖放元素、调整尺寸、更改颜色、添加文字和上传图片等。而模板编辑器则是预设了布局和样式的设计工具,用户可以在模板基础上进行个性化修改,大大降低了设计门槛。 在WordPress中集成这类工具,意味着将这些功能无缝嵌入到你的网站页面中,让访问者能够直接使用。这通常需要结合前端界面库、后端处理逻辑和数据库存储等技术组件。
- 在开始编码之前,你需要搭建合适的开发环境: 本地开发环境:建议使用Local by Flywheel、XAMPP或MAMP等工具,在本地计算机上搭建WordPress运行环境。这样可以避免在线上网站直接调试可能带来的风险。 代码编辑器:选择一款强大的代码编辑器,如Visual Studio Code、PHPStorm或Sublime Text。确保安装相关插件,如PHP智能提示、CSS自动补全和Git集成等。 浏览器开发者工具:熟悉Chrome或Firefox的开发者工具,这对前端调试至关重要。 版本控制系统:初始化Git仓库来管理代码变更,这是专业开发的基本实践。 备份方案:确保你有完整的网站备份,包括文件和数据库,以防开发过程中出现不可逆的错误。
- 为了避免主题更新覆盖你的修改,最佳实践是创建一个子主题或自定义插件: 创建子主题的方法: 在/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网站集成在线设计工具和模板编辑器 */
-
- 集成设计工具的第一步是选择合适的前端库。以下是几个优秀的选择: Fabric.js:一个强大的Canvas库,专门用于创建交互式设计工具。它提供了丰富的对象模型、序列化功能和交互控制。 Konva.js:另一个基于Canvas的2D绘图库,性能优异,支持桌面和移动设备。 tldraw:开源的绘图库,提供流畅的绘图体验和丰富的图形工具。 PixiJS:专注于性能的2D渲染引擎,适合需要处理大量图形元素的复杂设计工具。 对于大多数应用场景,Fabric.js提供了最全面的功能集和活跃的社区支持。我们将以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链接为本地路径
- 接下来,我们创建一个基础的设计画布。首先,在页面模板中添加画布容器: // 在主题模板文件中添加 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); }); });
- 设计数据需要保存到服务器。在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');
-
- 模板编辑器需要一种结构化的方式来定义模板。我们使用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' ) ) ) );
- 我们需要一个管理界面来创建和管理模板。使用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 }
- 在前端,我们需要从服务器加载模板并应用到画布: // 加载模板功能 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); }); } } }); }
-
- 现代设计工具离不开图像处理功能。我们可以集成一些常见的图像处理工具: // 图像处理功能后端 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]);
- 设计工具中字体选择是核心功能。我们可以集成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);
- 创建可搜索的素材库,包含图标、背景、贴纸等资源: // 素材库管理 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) {
在当今数字化时代,用户体验已成为网站成功的关键因素。无论是电商平台、内容发布网站还是企业官网,用户都期望获得更加个性化、互动性强的在线体验。集成在线设计工具与模板编辑器,可以让你的网站从“静态展示”转变为“动态创作平台”,从而显著提升用户参与度、延长停留时间并提高转化率。
想象一下,一个服装电商网站允许用户自定义T恤图案;一个营销公司网站让客户在线设计宣传海报;一个博客平台提供个性化的文章模板编辑器——这些功能不仅提升了网站的实用价值,也创造了独特的竞争优势。通过WordPress这一全球最流行的内容管理系统,我们可以通过代码二次开发,相对高效地实现这些高级功能。
本文将详细指导你如何一步步在WordPress网站中集成在线设计工具与模板编辑器,并实现一系列常用互联网小工具功能。无论你是WordPress开发者、网站管理员还是有一定技术基础的企业主,都能从本指南中获得实用的解决方案。
在线设计工具是一种基于Web的应用程序,允许用户在浏览器中直接创建和编辑视觉内容,无需安装专业设计软件。常见的功能包括:拖放元素、调整尺寸、更改颜色、添加文字和上传图片等。而模板编辑器则是预设了布局和样式的设计工具,用户可以在模板基础上进行个性化修改,大大降低了设计门槛。
在WordPress中集成这类工具,意味着将这些功能无缝嵌入到你的网站页面中,让访问者能够直接使用。这通常需要结合前端界面库、后端处理逻辑和数据库存储等技术组件。
在开始编码之前,你需要搭建合适的开发环境:
- 本地开发环境:建议使用Local by Flywheel、XAMPP或MAMP等工具,在本地计算机上搭建WordPress运行环境。这样可以避免在线上网站直接调试可能带来的风险。
- 代码编辑器:选择一款强大的代码编辑器,如Visual Studio Code、PHPStorm或Sublime Text。确保安装相关插件,如PHP智能提示、CSS自动补全和Git集成等。
- 浏览器开发者工具:熟悉Chrome或Firefox的开发者工具,这对前端调试至关重要。
- 版本控制系统:初始化Git仓库来管理代码变更,这是专业开发的基本实践。
- 备份方案:确保你有完整的网站备份,包括文件和数据库,以防开发过程中出现不可逆的错误。
为了避免主题更新覆盖你的修改,最佳实践是创建一个子主题或自定义插件:
创建子主题的方法:
- 在
/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网站集成在线设计工具和模板编辑器 */
集成设计工具的第一步是选择合适的前端库。以下是几个优秀的选择:
- Fabric.js:一个强大的Canvas库,专门用于创建交互式设计工具。它提供了丰富的对象模型、序列化功能和交互控制。
- Konva.js:另一个基于Canvas的2D绘图库,性能优异,支持桌面和移动设备。
- tldraw:开源的绘图库,提供流畅的绘图体验和丰富的图形工具。
- PixiJS:专注于性能的2D渲染引擎,适合需要处理大量图形元素的复杂设计工具。
对于大多数应用场景,Fabric.js提供了最全面的功能集和活跃的社区支持。我们将以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链接为本地路径
接下来,我们创建一个基础的设计画布。首先,在页面模板中添加画布容器:
// 在主题模板文件中添加
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);
});
});
设计数据需要保存到服务器。在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');
模板编辑器需要一种结构化的方式来定义模板。我们使用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'
)
)
)
);
我们需要一个管理界面来创建和管理模板。使用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
}
在前端,我们需要从服务器加载模板并应用到画布:
// 加载模板功能
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);
});
}
}
});
}
现代设计工具离不开图像处理功能。我们可以集成一些常见的图像处理工具:
// 图像处理功能后端
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]);
设计工具中字体选择是核心功能。我们可以集成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);
创建可搜索的素材库,包含图标、背景、贴纸等资源:
// 素材库管理
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) {


