PluginProbe
Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor / 2.0.7
Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor v2.0.7
2.0.13 2.0.12 2.0.11 2.0.10 2.0.9 trunk 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8
blockenberg / blocks / drawing-canvas / index.js

index.js in Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor 2.0.7, at blocks/drawing-canvas/index.js

184 lines 12.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 ( function () {
2 var el = wp.element.createElement;
3 var registerBlockType = wp.blocks.registerBlockType;
4 var useBlockProps = wp.blockEditor.useBlockProps;
5 var InspectorControls = wp.blockEditor.InspectorControls;
6 var PanelColorSettings = wp.blockEditor.PanelColorSettings;
7 var RichText = wp.blockEditor.RichText;
8 var PanelBody = wp.components.PanelBody;
9 var RangeControl = wp.components.RangeControl;
10 var ToggleControl = wp.components.ToggleControl;
11 var SelectControl = wp.components.SelectControl;
12
13 var _drwTC, _drwTV;
14 function _tc() { return _drwTC || (_drwTC = window.bkbgTypographyControl); }
15 function _tv(t, p) { return (_drwTV || (_drwTV = window.bkbgTypoCssVars)) ? _drwTV(t, p) : {}; }
16
17 var TOOL_OPTIONS = [
18 { label: '✏️ Pen (freehand)', value: 'pen' },
19 { label: '🖊️ Marker (soft)', value: 'marker' },
20 { label: '📏 Line', value: 'line' },
21 { label: '□ Rectangle', value: 'rect' },
22 { label: '○ Ellipse', value: 'ellipse' },
23 { label: '🧹 Eraser', value: 'eraser' }
24 ];
25
26 var PRESET_PALETTE = [
27 '#1e1b4b','#ef4444','#f97316','#eab308',
28 '#22c55e','#06b6d4','#6366f1','#a855f7',
29 '#ec4899','#78716c','#ffffff','#000000'
30 ];
31
32 // ---- Editor preview component ----
33 function EditorPreview(props) {
34 var a = props.attributes;
35 var accent = a.accentColor || '#6366f1';
36 var titleColor = a.titleColor || '#1e1b4b';
37
38 return el('div', { className: 'bkbg-drw-editor-preview', style: { background: a.sectionBg || '#f8fafc', borderRadius: 14, padding: 28, fontFamily: 'inherit' } },
39 el('div', { className: 'bkbg-drw-editor-header', style: { marginBottom: 16, textAlign: 'center' } },
40 el(RichText, {
41 tagName: 'h3',
42 className: 'bkbg-drw-title',
43 style: { margin: 0, color: titleColor },
44 value: a.title,
45 onChange: function (v) { props.setAttributes({ title: v }); },
46 placeholder: 'Drawing Canvas'
47 }),
48 el(RichText, {
49 tagName: 'p',
50 className: 'bkbg-drw-subtitle',
51 style: { margin: '4px 0 0', color: titleColor, opacity: 0.65 },
52 value: a.subtitle,
53 onChange: function (v) { props.setAttributes({ subtitle: v }); },
54 placeholder: 'Draw anything...'
55 })
56 ),
57 // Toolbar preview
58 a.showToolbar !== false && el('div', { className: 'bkbg-drw-toolbar-preview', style: { display: 'flex', flexWrap: 'wrap', gap: 8, marginBottom: 12, alignItems: 'center' } },
59 ['✏️', '🖊️', '📏', '', '', '🧹'].map(function (icon, i) {
60 return el('div', { key: i, style: { background: i === 0 ? accent : '#e5e7eb', color: i === 0 ? '#fff' : '#374151', border: 'none', borderRadius: 7, padding: '6px 10px', fontSize: 16, cursor: 'pointer', fontWeight: i === 0 ? 700 : 400 } }, icon);
61 }),
62 el('div', { style: { flexGrow: 1 } }),
63 PRESET_PALETTE.slice(0, 8).map(function (col, i) {
64 return el('div', { key: i, style: { width: 20, height: 20, borderRadius: '50%', background: col, border: i === 0 ? '2.5px solid ' + accent : '1.5px solid rgba(0,0,0,0.15)', cursor: 'pointer' } });
65 })
66 ),
67 // Canvas preview (with a simple illustration)
68 el('div', { style: { position: 'relative', background: a.backgroundColor || '#ffffff', border: '1.5px solid #e5e7eb', borderRadius: 10, overflow: 'hidden', height: 200 } },
69 el('svg', { width: '100%', height: '100%', viewBox: '0 0 400 200', style: { position: 'absolute', inset: 0 } },
70 // Background check (grid dots)
71 el('defs', {},
72 el('pattern', { id: 'p', x: 0, y: 0, width: 20, height: 20, patternUnits: 'userSpaceOnUse' },
73 el('circle', { cx: 1, cy: 1, r: 1, fill: '#e5e7eb' })
74 )
75 ),
76 a.showGrid !== false && el('rect', { width: '100%', height: '100%', fill: 'url(#p)' }),
77 // A simple wave/doodle illustration
78 el('path', { d: 'M40,120 Q80,60 120,100 T200,80 T280,110 T360,70', stroke: accent, strokeWidth: 3, fill: 'none', strokeLinecap: 'round' }),
79 el('circle', { cx: 100, cy: 140, r: 30, stroke: '#ef4444', strokeWidth: 3, fill: 'none' }),
80 el('rect', { x: 220, y: 110, width: 60, height: 50, rx: 6, stroke: '#22c55e', strokeWidth: 3, fill: '#22c55e22' }),
81 el('path', { d: 'M60,160 L90,100 L120,160', stroke: '#f97316', strokeWidth: 3, fill: 'none', strokeLinejoin: 'round' })
82 ),
83 el('div', { style: { position: 'absolute', bottom: 8, right: 10, fontSize: 11, color: '#9ca3af', fontStyle: 'italic' } }, 'Interactive canvas on frontend')
84 ),
85 a.showDownload !== false && el('div', { style: { marginTop: 12, display: 'flex', gap: 8 } },
86 a.showUndo !== false && el('div', { style: { background: '#f3f4f6', border: '1.5px solid #e5e7eb', borderRadius: 7, padding: '6px 14px', fontSize: 13, color: '#374151', cursor: 'pointer' } }, '↩ Undo'),
87 el('div', { style: { background: '#f3f4f6', border: '1.5px solid #e5e7eb', borderRadius: 7, padding: '6px 14px', fontSize: 13, color: '#374151', cursor: 'pointer' } }, '🗑 Clear'),
88 el('div', { style: { background: accent, borderRadius: 7, padding: '6px 14px', fontSize: 13, color: '#fff', cursor: 'pointer', fontWeight: 700 } }, '⬇ Download PNG')
89 )
90 );
91 }
92
93 registerBlockType('blockenberg/drawing-canvas', {
94 edit: function (props) {
95 var a = props.attributes;
96 var setAttributes = props.setAttributes;
97 var blockProps = useBlockProps({ className: 'bkbg-drw-editor-wrap', style: Object.assign(
98 { '--bkbg-drw-ttl-fs': (a.fontSize || 26) + 'px', '--bkbg-drw-sub-fs': (a.subtitleSize || 14) + 'px' },
99 _tv(a.typoTitle || {}, '--bkbg-drw-ttl-'),
100 _tv(a.typoSubtitle || {}, '--bkbg-drw-sub-')
101 ) });
102 var accent = a.accentColor || '#6366f1';
103
104 return el('div', blockProps,
105 el(InspectorControls, {},
106 // Content
107 el(PanelBody, { title: 'Block Content', initialOpen: true },
108 ),
109 // Canvas Settings
110 el(PanelBody, { title: 'Canvas Settings', initialOpen: false },
111 el(RangeControl, { label: 'Canvas width (px)', value: a.canvasWidth || 800, onChange: function (v) { setAttributes({ canvasWidth: v }); }, min: 300, max: 1600, step: 10, __nextHasNoMarginBottom: true }),
112 el(RangeControl, { label: 'Canvas height (px)', value: a.canvasHeight || 480, onChange: function (v) { setAttributes({ canvasHeight: v }); }, min: 200, max: 1200, step: 10, __nextHasNoMarginBottom: true }),
113 el(RangeControl, { label: 'Default stroke width', value: a.defaultLineWidth || 4, onChange: function (v) { setAttributes({ defaultLineWidth: v }); }, min: 1, max: 40, __nextHasNoMarginBottom: true }),
114 el(SelectControl, { label: 'Default tool', value: a.defaultTool || 'pen', options: TOOL_OPTIONS, onChange: function (v) { setAttributes({ defaultTool: v }); }, __nextHasNoMarginBottom: true }),
115 el(ToggleControl, { label: 'Show background grid', checked: !!a.showGrid, onChange: function (v) { setAttributes({ showGrid: v }); }, __nextHasNoMarginBottom: true })
116 ),
117 // UI Options
118 el(PanelBody, { title: 'Toolbar & UI', initialOpen: false },
119 el(ToggleControl, { label: 'Show toolbar', checked: a.showToolbar !== false, onChange: function (v) { setAttributes({ showToolbar: v }); }, __nextHasNoMarginBottom: true }),
120 el(ToggleControl, { label: 'Show undo button', checked: a.showUndo !== false, onChange: function (v) { setAttributes({ showUndo: v }); }, __nextHasNoMarginBottom: true }),
121 el(ToggleControl, { label: 'Show download button', checked: a.showDownload !== false, onChange: function (v) { setAttributes({ showDownload: v }); }, __nextHasNoMarginBottom: true })
122 ),
123 // Colors
124
125 el( PanelBody, { title: 'Typography', initialOpen: false },
126 _tc() && el(_tc(), { label: 'Title', typo: a.typoTitle || {}, onChange: function (v) { setAttributes({ typoTitle: v }); }, defaultSize: a.fontSize || 26 }),
127 _tc() && el(_tc(), { label: 'Subtitle', typo: a.typoSubtitle || {}, onChange: function (v) { setAttributes({ typoSubtitle: v }); }, defaultSize: a.subtitleSize || 14 })
128 ),
129 el(PanelColorSettings, {
130 title: 'Colors',
131 initialOpen: false,
132 colorSettings: [
133 { label: 'Accent color', value: a.accentColor, onChange: function (v) { setAttributes({ accentColor: v || '#6366f1' }); } },
134 { label: 'Canvas background', value: a.backgroundColor, onChange: function (v) { setAttributes({ backgroundColor: v || '#ffffff' }); } },
135 { label: 'Grid lines', value: a.gridColor, onChange: function (v) { setAttributes({ gridColor: v || '#e5e7eb' }); } },
136 { label: 'Section background', value: a.sectionBg, onChange: function (v) { setAttributes({ sectionBg: v || '#f8fafc' }); } },
137 { label: 'Title color', value: a.titleColor, onChange: function (v) { setAttributes({ titleColor: v || '#1e1b4b' }); } }
138 ],
139 enableAlpha: true,
140 disableCustomGradients: true
141 })
142 ),
143 el(EditorPreview, { attributes: a, setAttributes: setAttributes })
144 );
145 },
146
147 save: function (props) {
148 var a = props.attributes;
149 var blockProps = useBlockProps.save();
150 var opts = {
151 canvasWidth: a.canvasWidth || 800,
152 canvasHeight: a.canvasHeight || 480,
153 defaultTool: a.defaultTool || 'pen',
154 defaultColor: a.defaultColor || '#1e1b4b',
155 defaultLineWidth: a.defaultLineWidth || 4,
156 showGrid: a.showGrid || false,
157 showToolbar: a.showToolbar !== false,
158 showDownload: a.showDownload !== false,
159 showUndo: a.showUndo !== false,
160 backgroundColor: a.backgroundColor || '#ffffff',
161 gridColor: a.gridColor || '#e5e7eb',
162 sectionBg: a.sectionBg || '#f8fafc',
163 titleColor: a.titleColor || '#1e1b4b',
164 accentColor: a.accentColor || '#6366f1',
165 fontSize: a.fontSize || 26,
166 fontWeight: a.fontWeight || '800',
167 lineHeight: a.lineHeight || 1.2,
168 subtitleSize: a.subtitleSize || 14,
169 subtitleFontWeight: a.subtitleFontWeight || '400',
170 subtitleLineHeight: a.subtitleLineHeight || 1.5,
171 typoTitle: a.typoTitle || {},
172 typoSubtitle: a.typoSubtitle || {}
173 };
174
175 return el('div', blockProps,
176 el('div', { className: 'bkbg-drw-app', 'data-opts': JSON.stringify(opts) },
177 el(RichText.Content, { tagName: 'h3', className: 'bkbg-drw-title', value: a.title }),
178 el(RichText.Content, { tagName: 'p', className: 'bkbg-drw-subtitle', value: a.subtitle })
179 )
180 );
181 }
182 });
183 }() );
184