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 / pixel-art / index.js

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

172 lines 10.0 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 Fragment = wp.element.Fragment;
4 var registerBlockType = wp.blocks.registerBlockType;
5 var __ = wp.i18n.__;
6 var InspectorControls = wp.blockEditor.InspectorControls;
7 var PanelColorSettings = wp.blockEditor.PanelColorSettings;
8 var useBlockProps = wp.blockEditor.useBlockProps;
9 var RichText = wp.blockEditor.RichText;
10 var SelectControl = wp.components.SelectControl;
11 var PanelBody = wp.components.PanelBody;
12 var RangeControl = wp.components.RangeControl;
13 var ToggleControl = wp.components.ToggleControl;
14
15 var _tc, _tv;
16 function getTypoControl() { return _tc || (_tc = window.bkbgTypographyControl); }
17 function getTypoCssVars() { return _tv || (_tv = window.bkbgTypoCssVars); }
18
19 // Demo pixel art: a small heart pattern for the 32x32 canvas preview
20 var HEART = [
21 ' ## ## ',
22 ' ###### ## ',
23 '##########',
24 '##########',
25 ' ######## ',
26 ' ###### ',
27 ' #### ',
28 ' ## '
29 ];
30
31 var DEFAULT_PALETTE = ['#000000','#ffffff','#ef4444','#f97316','#f59e0b','#22c55e','#06b6d4','#3b82f6','#8b5cf6','#ec4899','#78716c','#94a3b8'];
32
33 function EditorPreview(props) {
34 var a = props.attributes;
35 var setAttributes = props.setAttributes;
36 var cols = a.gridCols || 32;
37 var rows = a.gridRows || 32;
38 var cs = Math.min(a.cellSize || 16, 20); // cap preview cell size
39 var W = cols * cs;
40 var H = rows * cs;
41
42 var blockProps = useBlockProps((function () {
43 var tv = getTypoCssVars();
44 var s = { background: a.sectionBg || '#f8fafc', padding: '24px 20px' };
45 Object.assign(s, tv(a.titleTypo, '--bkbg-pxa-tt-'));
46 Object.assign(s, tv(a.subtitleTypo, '--bkbg-pxa-st-'));
47 return { style: s };
48 })());
49
50 // Preview canvas (static)
51 var cells = [];
52 for (var r = 0; r < rows; r++) {
53 for (var c = 0; c < cols; c++) {
54 // Put heart near center
55 var hr = r - Math.floor(rows / 2 - 4);
56 var hc = c - Math.floor(cols / 2 - 5);
57 var isHeart = hr >= 0 && hr < HEART.length && hc >= 0 && hc < HEART[hr].length && HEART[hr][hc] === '#';
58 cells.push(el('div', { key: r + '_' + c, style: {
59 width: cs, height: cs,
60 background: isHeart ? '#ef4444' : (a.canvasBg || '#ffffff'),
61 borderRight: a.showGrid ? '1px solid ' + (a.gridLineColor || '#e5e7eb') : 'none',
62 borderBottom: a.showGrid ? '1px solid ' + (a.gridLineColor || '#e5e7eb') : 'none',
63 boxSizing: 'border-box'
64 } }));
65 }
66 }
67
68 return el(Fragment, null,
69 el(InspectorControls, null,
70 el(PanelBody, { title: __('Content', 'blockenberg'), initialOpen: true },
71 ),
72 el(PanelBody, { title: __('Canvas Settings', 'blockenberg'), initialOpen: false },
73 el(RangeControl, { label: __('Grid Columns', 'blockenberg'), value: a.gridCols, min: 8, max: 64,
74 onChange: function (v) { setAttributes({ gridCols: v }); } }),
75 el(RangeControl, { label: __('Grid Rows', 'blockenberg'), value: a.gridRows, min: 8, max: 64,
76 onChange: function (v) { setAttributes({ gridRows: v }); } }),
77 el(ToggleControl, { __nextHasNoMarginBottom: true, label: __('Show Grid Lines', 'blockenberg'), checked: a.showGrid,
78 onChange: function (v) { setAttributes({ showGrid: v }); } }),
79 el(ToggleControl, { __nextHasNoMarginBottom: true, label: __('Show Download Button', 'blockenberg'), checked: a.showDownload,
80 onChange: function (v) { setAttributes({ showDownload: v }); } })
81 ),
82
83 el( PanelBody, { title: __( 'Typography', 'blockenberg' ), initialOpen: false },
84 el(getTypoControl(), { label: __('Title', 'blockenberg'), value: a.titleTypo, onChange: function(v) { setAttributes({ titleTypo: v }); } }),
85 el(getTypoControl(), { label: __('Subtitle', 'blockenberg'), value: a.subtitleTypo, onChange: function(v) { setAttributes({ subtitleTypo: v }); } }),
86 el(RangeControl, { label: __('Cell Size (px)', 'blockenberg'), value: a.cellSize, min: 6, max: 40,
87 onChange: function (v) { setAttributes({ cellSize: v }); } })
88 ),
89 el(PanelColorSettings, {
90 title: __('Colors', 'blockenberg'), initialOpen: false,
91 colorSettings: [
92 { label: __('Canvas Background', 'blockenberg'), value: a.canvasBg, onChange: function (v) { setAttributes({ canvasBg: v || '#ffffff' }); } },
93 { label: __('Grid Line Color', 'blockenberg'), value: a.gridLineColor, onChange: function (v) { setAttributes({ gridLineColor: v || '#e5e7eb' }); } },
94 { label: __('Section Background', 'blockenberg'), value: a.sectionBg, onChange: function (v) { setAttributes({ sectionBg: v || '#f8fafc' }); } },
95 { label: __('Title Color', 'blockenberg'), value: a.titleColor, onChange: function (v) { setAttributes({ titleColor: v || '#1e1b4b' }); } },
96 { label: __('Accent Color', 'blockenberg'), value: a.accentColor, onChange: function (v) { setAttributes({ accentColor: v || '#6366f1' }); } }
97 ]
98 })
99 ),
100 el('div', blockProps,
101 el(RichText, { tagName: 'h3', className: 'bkbg-pxa-title', value: a.title,
102 onChange: function (v) { setAttributes({ title: v }); },
103 placeholder: 'Pixel Art',
104 style: { color: a.titleColor, textAlign: 'center', margin: '0 0 4px' } }),
105 el(RichText, { tagName: 'p', className: 'bkbg-pxa-subtitle', value: a.subtitle,
106 onChange: function (v) { setAttributes({ subtitle: v }); },
107 placeholder: 'Draw something pixel by pixel!',
108 style: { color: a.titleColor, opacity: 0.65, textAlign: 'center', margin: '0 0 14px' } }),
109 // Toolbar preview
110 el('div', { style: { display: 'flex', justifyContent: 'center', gap: 6, marginBottom: 10, flexWrap: 'wrap' } },
111 ['✏️ Draw', '🪣 Fill', '⬜ Erase'].map(function (t) { return el('div', { key: t, style: { background: a.accentColor + '22', color: a.titleColor, borderRadius: 6, padding: '5px 12px', fontSize: 12, fontWeight: 600 } }, t); }),
112 (a.palette || DEFAULT_PALETTE).map(function (c, i) { return el('div', { key: i, style: { width: 22, height: 22, background: c, borderRadius: 4, border: i === 0 ? '2px solid ' + a.accentColor : '2px solid transparent', cursor: 'pointer' } }); })
113 ),
114 // Canvas preview
115 el('div', { style: { display: 'flex', justifyContent: 'center', overflow: 'auto' } },
116 el('div', { style: { display: 'grid', gridTemplateColumns: 'repeat(' + cols + ', ' + cs + 'px)', width: W, height: H, border: '1px solid ' + (a.gridLineColor || '#e5e7eb'), borderRadius: 4, overflow: 'hidden', flexShrink: 0 } }, cells)
117 )
118 )
119 );
120 }
121
122 registerBlockType('blockenberg/pixel-art', {
123 edit: EditorPreview,
124 save: function (props) {
125 var a = props.attributes;
126 var bpSave = useBlockProps.save((function () {
127 var tv = getTypoCssVars();
128 var s = {};
129 Object.assign(s, tv(a.titleTypo, '--bkbg-pxa-tt-'));
130 Object.assign(s, tv(a.subtitleTypo, '--bkbg-pxa-st-'));
131 return { style: s };
132 })());
133 return el('div', bpSave,
134 el('div', { className: 'bkbg-pxa-app', 'data-opts': JSON.stringify(a) },
135 el(RichText.Content, { tagName: 'h3', className: 'bkbg-pxa-title', value: a.title }),
136 el(RichText.Content, { tagName: 'p', className: 'bkbg-pxa-subtitle', value: a.subtitle })
137 )
138 );
139 },
140 deprecated: [{
141 attributes: {
142 title: { type: 'string', default: 'Pixel Art' },
143 subtitle: { type: 'string', default: 'Draw something pixel by pixel!' },
144 fontSize: { type: 'number', default: 26 },
145 subtitleSize: { type: 'number', default: 14 },
146 gridCols: { type: 'number', default: 32 },
147 gridRows: { type: 'number', default: 32 },
148 cellSize: { type: 'number', default: 16 },
149 showGrid: { type: 'boolean', default: true },
150 showDownload: { type: 'boolean', default: true },
151 palette: { type: 'array', default: ['#000000','#ffffff','#ef4444','#f97316','#f59e0b','#22c55e','#06b6d4','#3b82f6','#8b5cf6','#ec4899','#78716c','#94a3b8'] },
152 canvasBg: { type: 'string', default: '#ffffff' },
153 gridLineColor: { type: 'string', default: '#e5e7eb' },
154 sectionBg: { type: 'string', default: '#f8fafc' },
155 titleColor: { type: 'string', default: '#1e1b4b' },
156 accentColor: { type: 'string', default: '#6366f1' },
157 fontWeight: { type: 'string', default: '700' },
158 subtitleFontWeight: { type: 'string', default: '400' }
159 },
160 save: function (props) {
161 var a = props.attributes;
162 return el('div', useBlockProps.save(),
163 el('div', { className: 'bkbg-pxa-app', 'data-opts': JSON.stringify(a) },
164 el(RichText.Content, { tagName: 'h3', className: 'bkbg-pxa-title', value: a.title }),
165 el(RichText.Content, { tagName: 'p', className: 'bkbg-pxa-subtitle', value: a.subtitle })
166 )
167 );
168 }
169 }]
170 });
171 }() );
172