PluginProbe
Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor / 2.0.11
Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor v2.0.11
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 / icon-cloud / index.js

index.js in Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor 2.0.11, at blocks/icon-cloud/index.js

174 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 = React.createElement;
3 var registerBlockType = wp.blocks.registerBlockType;
4 var useBlockProps = wp.blockEditor.useBlockProps;
5 var InspectorControls = wp.blockEditor.InspectorControls;
6 var PanelBody = wp.components.PanelBody;
7 var RangeControl = wp.components.RangeControl;
8 var SelectControl = wp.components.SelectControl;
9 var TextControl = wp.components.TextControl;
10 var ToggleControl = wp.components.ToggleControl;
11 var Button = wp.components.Button;
12 var PanelColorSettings = wp.blockEditor.PanelColorSettings;
13
14 var _TypographyControl, _typoCssVars;
15 function getTypographyControl() { return _TypographyControl || (_TypographyControl = window.bkbgTypographyControl); }
16 function getTypoCssVars() { return _typoCssVars || (_typoCssVars = window.bkbgTypoCssVars); }
17
18 var COLOR_MODES = [
19 { value: 'gradient', label: 'Gradient (depth-based)' },
20 { value: 'solid', label: 'Solid color' },
21 { value: 'multi', label: 'Multi-color (random)' }
22 ];
23
24 /** Place N items on a sphere using Fibonacci spiral */
25 function fibonacciSphere(n, r) {
26 var points = [];
27 var phi = Math.PI * (3 - Math.sqrt(5));
28 for (var i = 0; i < n; i++) {
29 var y = 1 - (i / (n - 1)) * 2;
30 var radius = Math.sqrt(1 - y * y);
31 var theta = phi * i;
32 points.push({
33 x: Math.cos(theta) * radius * r,
34 y: y * r,
35 z: Math.sin(theta) * radius * r
36 });
37 }
38 return points;
39 }
40
41 function CloudPreview(props) {
42 var a = props.attr;
43 var items = a.items || [];
44 var r = a.cloudRadius || 220;
45 var pts = fibonacciSphere(items.length, r);
46 var perspective = a.perspective || 900;
47
48 return el('div', {
49 style: { position:'relative', width:'100%', height:(a.cloudHeight||500)+'px', background:a.showBackground && a.bgColor ? a.bgColor : 'transparent', overflow:'hidden', borderRadius:12 }
50 },
51 el('div', {
52 style: { position:'absolute', inset:0, display:'flex', alignItems:'center', justifyContent:'center' }
53 },
54 items.map(function(item, i) {
55 var pt = pts[i] || {x:0,y:0,z:0};
56 var cx = 0, cy = 0;
57 var persp = perspective / (perspective - pt.z);
58 var x2d = pt.x * persp + cx;
59 var y2d = pt.y * persp + cy;
60 var depth = (pt.z + r) / (2 * r); /* 0=back 1=front */
61 var opacity = a.depthFade ? (0.3 + depth * 0.7) : 1;
62 var scale = 0.6 + depth * 0.6;
63 var color = a.colorMode === 'gradient'
64 ? lerpColor(a.colorFrom||'#7c3aed', a.colorTo||'#ec4899', depth)
65 : a.colorFrom||'#7c3aed';
66
67 return el('div', {
68 key:i,
69 style: {
70 position:'absolute',
71 left:'50%', top:'50%',
72 transform:'translate(-50%,-50%) translate('+x2d+'px,'+y2d+'px) scale('+scale+')',
73 opacity:opacity,
74 background:a.itemBg||'#1e1b4b',
75 border:'1px solid '+(a.itemBorder||'#7c3aed44'),
76 color:color,
77 fontSize:(a.fontSize||14)+'px',
78 fontWeight:a.fontWeight||'600',
79 lineHeight:a.lineHeight||1.4,
80 padding:(a.itemPadding||6)+'px '+(((a.itemPadding||6)+6))+'px',
81 borderRadius:(a.itemBorderRadius||6)+'px',
82 whiteSpace:'nowrap',
83 cursor:'default',
84 userSelect:'none',
85 zIndex:Math.round(depth*100)
86 }
87 }, item);
88 })
89 )
90 );
91 }
92
93 function lerpColor(a, b, t) {
94 if (!a || !b) return a||b||'#fff';
95 var ah = a.replace('#',''), bh = b.replace('#','');
96 var ar=parseInt(ah.substr(0,2),16), ag=parseInt(ah.substr(2,2),16), ab2=parseInt(ah.substr(4,2),16);
97 var br=parseInt(bh.substr(0,2),16), bg=parseInt(bh.substr(2,2),16), bb2=parseInt(bh.substr(4,2),16);
98 var rr=Math.round(ar+(br-ar)*t), rg=Math.round(ag+(bg-ag)*t), rb2=Math.round(ab2+(bb2-ab2)*t);
99 return 'rgba('+rr+','+rg+','+rb2+',1)';
100 }
101
102 registerBlockType('blockenberg/icon-cloud', {
103 title: 'Icon Cloud',
104 icon: 'cloud',
105 category: 'bkbg-effects',
106
107 edit: function (props) {
108 var attr = props.attributes; var setAttr = props.setAttributes;
109
110 function updateItem(i, val) {
111 var arr = (attr.items||[]).slice(); arr[i] = val; setAttr({items:arr});
112 }
113 function addItem() { setAttr({items:(attr.items||[]).concat(['New Item'])}); }
114 function removeItem(i) { setAttr({items:(attr.items||[]).filter(function(_,j){return j!==i;})}); }
115
116 return el(React.Fragment, null,
117 el(InspectorControls, null,
118 el(PanelBody, {title:'Items', initialOpen:true},
119 (attr.items||[]).map(function(item, i){
120 return el('div',{key:i,style:{display:'flex',gap:8,marginBottom:4,alignItems:'center'}},
121 el(TextControl,{__nextHasNoMarginBottom:true,value:item,onChange:function(v){updateItem(i,v);},style:{flex:1}}),
122 el(Button,{variant:'tertiary',isSmall:true,isDestructive:true,onClick:function(){removeItem(i);}},'')
123 );
124 }),
125 el(Button,{variant:'secondary',isSmall:true,style:{marginTop:4},onClick:addItem},'+ Add Item')
126 ),
127 el(PanelBody, {title:'Cloud Shape', initialOpen:false},
128 el(RangeControl,{__nextHasNoMarginBottom:true,label:'Cloud Radius (px)',value:attr.cloudRadius,min:100,max:500,onChange:function(v){setAttr({cloudRadius:v});}}),
129 el(RangeControl,{__nextHasNoMarginBottom:true,label:'Container Height (px)',value:attr.cloudHeight,min:200,max:900,onChange:function(v){setAttr({cloudHeight:v});}}),
130 el(RangeControl,{__nextHasNoMarginBottom:true,label:'Perspective (px)',value:attr.perspective,min:300,max:2000,onChange:function(v){setAttr({perspective:v});}})
131 ),
132 el(PanelBody, {title:'Animation', initialOpen:false},
133 el(RangeControl,{__nextHasNoMarginBottom:true,label:'Auto-Rotate X Speed',value:attr.autoRotateX,min:0,max:0.02,step:0.001,onChange:function(v){setAttr({autoRotateX:v});}}),
134 el(RangeControl,{__nextHasNoMarginBottom:true,label:'Auto-Rotate Y Speed',value:attr.autoRotateY,min:0,max:0.02,step:0.001,onChange:function(v){setAttr({autoRotateY:v});}}),
135 el(ToggleControl,{__nextHasNoMarginBottom:true,label:'Mouse Interaction',checked:attr.mouseEffect,onChange:function(v){setAttr({mouseEffect:v});}}),
136 attr.mouseEffect && el(RangeControl,{__nextHasNoMarginBottom:true,label:'Mouse Strength',value:attr.mouseStrength,min:0.01,max:0.2,step:0.01,onChange:function(v){setAttr({mouseStrength:v});}})
137 ),
138 el(PanelBody, {title:'Item Style', initialOpen:false},
139 el(RangeControl,{__nextHasNoMarginBottom:true,label:'Padding (px)',value:attr.itemPadding,min:2,max:20,onChange:function(v){setAttr({itemPadding:v});}}),
140 el(RangeControl,{__nextHasNoMarginBottom:true,label:'Border Radius (px)',value:attr.itemBorderRadius,min:0,max:50,onChange:function(v){setAttr({itemBorderRadius:v});}}),
141 el(ToggleControl,{__nextHasNoMarginBottom:true,label:'Depth Fade',checked:attr.depthFade,onChange:function(v){setAttr({depthFade:v});}})
142 ),
143 el(PanelBody, {title:'Background', initialOpen:false},
144 el(ToggleControl,{__nextHasNoMarginBottom:true,label:'Show Background',checked:attr.showBackground,onChange:function(v){setAttr({showBackground:v});}})
145 ),
146
147 el( PanelBody, { title: 'Typography', initialOpen: false },
148 getTypographyControl() && el(getTypographyControl(), { label: 'Item Text', typo: attr.itemTypo || {}, onChange: function(v){ setAttr({ itemTypo: v }); } })
149 ),
150 el(PanelColorSettings, {
151 title:'Colors',initialOpen:false,
152 colorSettings:[
153 {value:attr.colorFrom, onChange:function(v){setAttr({colorFrom:v||'#7c3aed'});},label:'Color From (front)'},
154 {value:attr.colorTo, onChange:function(v){setAttr({colorTo:v||'#ec4899'});},label:'Color To (back)'},
155 {value:attr.itemBg, onChange:function(v){setAttr({itemBg:v||'#1e1b4b'});},label:'Item Background'},
156 {value:attr.textColor, onChange:function(v){setAttr({textColor:v||'#e2e8f0'});},label:'Text (solid mode)'},
157 {value:attr.hoverBg, onChange:function(v){setAttr({hoverBg:v||'#7c3aed'});},label:'Hover Background'},
158 {value:attr.hoverColor, onChange:function(v){setAttr({hoverColor:v||'#ffffff'});},label:'Hover Text'},
159 attr.showBackground && {value:attr.bgColor, onChange:function(v){setAttr({bgColor:v||'#000'});},label:'Section Background'}
160 ].filter(Boolean)
161 })
162 ),
163 el('div', useBlockProps(), el(CloudPreview, {attr:attr}))
164 );
165 },
166
167 save: function (props) {
168 return el('div', useBlockProps.save(),
169 el('div', { className:'bkbg-ic-app', 'data-opts':JSON.stringify(props.attributes) })
170 );
171 }
172 });
173 }() );
174