3 Комплементарное, Триадное, Аналоговое
Файл: color-harmony-wheel.php плагин для всех
<?php
/**
* Plugin Name: Color Harmony Wheel Pro
* Plugin URI: https://1promtai.ru/
* Description: Интерактивный цветовой круг с 3, 4, 5 или 6 гармониями. HEX, русские названия, копирование по клику, адаптив.
* Version: 2.0
* Author: PromtAI
* License: GPL2
*/
if (!defined('ABSPATH')) exit;
class ColorHarmonyWheelPro {
private static $instance = null;
public static function getInstance() {
if (self::$instance === null) {
self::$instance = new self();
}
return self::$instance;
}
private function __construct() {
add_action('wp_head', [$this, 'printStyles']);
add_action('wp_footer', [$this, 'printScript']);
add_shortcode('color_wheel_3', [$this, 'shortcode3']);
add_shortcode('color_wheel_4', [$this, 'shortcode4']);
add_shortcode('color_wheel_5', [$this, 'shortcode5']);
add_shortcode('color_wheel_6', [$this, 'shortcode6']);
}
// ==================== СТИЛИ ====================
public function printStyles() {
?>
<style id="chw-pro-styles">
/* Базовые стили */
.chw-widget {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
max-width: 1000px;
margin: 30px auto;
padding: 28px 20px;
background: #fff;
border-radius: 22px;
box-shadow: 0 8px 32px rgba(0,0,0,0.06);
text-align: center;
box-sizing: border-box;
}
.chw-widget * {
box-sizing: border-box;
}
.chw-widget h2 {
margin: 0 0 6px;
font-size: 24px;
color: #1a1a2e;
}
.chw-widget .chw-subtitle {
font-size: 14px;
color: #888;
margin-bottom: 20px;
}
/* Цветовой круг */
.chw-wheel-wrap {
position: relative;
width: 250px;
height: 250px;
margin: 0 auto 22px;
max-width: 100%;
}
.chw-wheel-wrap canvas {
width: 100%;
height: 100%;
border-radius: 50%;
cursor: grab;
box-shadow: 0 0 0 6px #fff, 0 8px 28px rgba(0,0,0,0.10);
transition: box-shadow 0.2s;
display: block;
}
.chw-wheel-wrap canvas:active {
cursor: grabbing;
box-shadow: 0 0 0 6px #fff, 0 12px 36px rgba(0,0,0,0.16);
}
.chw-marker {
position: absolute;
top: 50%;
left: 50%;
width: 22px;
height: 22px;
background: #fff;
border: 3px solid #222;
border-radius: 50%;
transform: translate(-50%, -50%);
pointer-events: none;
box-shadow: 0 0 0 4px rgba(255,255,255,0.9), 0 2px 8px rgba(0,0,0,0.25);
z-index: 5;
}
/* Инфо-блок с выбранным цветом */
.chw-info {
display: inline-flex;
align-items: center;
gap: 10px;
background: #f4f4fb;
padding: 9px 20px;
border-radius: 40px;
font-size: 14px;
margin-bottom: 24px;
flex-wrap: wrap;
justify-content: center;
}
.chw-info-swatch {
width: 24px;
height: 24px;
border-radius: 6px;
box-shadow: 0 1px 4px rgba(0,0,0,0.15);
flex-shrink: 0;
}
.chw-info-name {
font-weight: 700;
color: #222;
}
.chw-info-hex {
font-weight: 700;
letter-spacing: 0.4px;
}
/* Карточки палитр */
.chw-palettes {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 16px;
margin-bottom: 24px;
}
.chw-card {
background: #fafbfd;
border-radius: 16px;
padding: 18px 14px;
flex: 1 1 180px;
min-width: 170px;
max-width: 260px;
box-shadow: 0 3px 12px rgba(0,0,0,0.04);
border: 1px solid #eef0f5;
transition: transform 0.15s, box-shadow 0.15s;
}
.chw-card:hover {
transform: translateY(-3px);
box-shadow: 0 6px 20px rgba(0,0,0,0.08);
}
.chw-card-title {
font-weight: 700;
font-size: 13px;
margin-bottom: 12px;
color: #444;
letter-spacing: 0.3px;
}
/* Строка с цветом */
.chw-swatch {
display: flex;
align-items: center;
gap: 10px;
margin-bottom: 8px;
padding: 6px 8px;
border-radius: 10px;
cursor: pointer;
transition: background 0.15s;
position: relative;
}
.chw-swatch:hover {
background: rgba(0,0,0,0.03);
}
.chw-swatch:active {
background: rgba(0,0,0,0.06);
}
.chw-swatch-block {
width: 32px;
height: 32px;
border-radius: 7px;
box-shadow: 0 2px 6px rgba(0,0,0,0.10);
flex-shrink: 0;
}
.chw-swatch-hex {
font-weight: 700;
font-size: 13px;
transition: color 0.2s;
}
.chw-swatch-name {
font-size: 11px;
color: #777;
}
.chw-swatch-copy-hint {
position: absolute;
right: 8px;
top: 50%;
transform: translateY(-50%);
font-size: 10px;
color: #bbb;
opacity: 0;
transition: opacity 0.2s;
pointer-events: none;
}
.chw-swatch:hover .chw-swatch-copy-hint {
opacity: 1;
}
/* Уведомление о копировании */
.chw-copy-toast {
position: fixed;
background: #222;
color: #fff;
padding: 10px 20px;
border-radius: 30px;
font-size: 14px;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
z-index: 99999;
pointer-events: none;
animation: chwFadeInOut 1.8s ease forwards;
box-shadow: 0 4px 16px rgba(0,0,0,0.2);
}
@keyframes chwFadeInOut {
0% { opacity: 0; transform: translateY(10px); }
15% { opacity: 1; transform: translateY(0); }
75% { opacity: 1; transform: translateY(0); }
100% { opacity: 0; transform: translateY(-10px); }
}
/* Статья */
.chw-article {
text-align: left;
background: #f9fafc;
border-radius: 16px;
padding: 22px 26px;
margin-top: 10px;
border: 1px solid #eef1f5;
font-size: 14px;
line-height: 1.7;
color: #333;
}
.chw-article h3 {
margin: 16px 0 6px;
font-size: 17px;
color: #1a1a2e;
}
.chw-article h3:first-child {
margin-top: 0;
}
.chw-article p {
margin: 0 0 10px;
}
.chw-article ul {
margin: 0 0 10px 18px;
padding: 0;
}
.chw-article ul li {
margin-bottom: 4px;
}
.chw-article .chw-tip {
background: #fff8e1;
border-left: 4px solid #ffb300;
padding: 10px 14px;
border-radius: 0 10px 10px 0;
margin: 12px 0;
font-style: italic;
}
/* Планшет */
@media (max-width: 768px) {
.chw-widget {
margin: 20px 10px;
padding: 22px 16px;
border-radius: 18px;
}
.chw-widget h2 { font-size: 21px; }
.chw-subtitle { font-size: 13px; margin-bottom: 16px; }
.chw-wheel-wrap { width: 200px; height: 200px; }
.chw-marker { width: 18px; height: 18px; border-width: 2px; }
.chw-palettes { gap: 12px; }
.chw-card {
flex: 1 1 160px;
min-width: 150px;
max-width: 48%;
padding: 14px 10px;
}
.chw-card-title { font-size: 12px; }
.chw-swatch-hex { font-size: 12px; }
.chw-swatch-name { font-size: 10px; }
.chw-swatch-block { width: 26px; height: 26px; }
.chw-article { padding: 16px 18px; font-size: 13px; line-height: 1.6; }
.chw-article h3 { font-size: 15px; }
.chw-info { font-size: 12px; padding: 7px 16px; gap: 7px; }
.chw-info-swatch { width: 20px; height: 20px; }
}
/* Телефон */
@media (max-width: 480px) {
.chw-widget {
margin: 15px 6px;
padding: 18px 10px;
border-radius: 14px;
}
.chw-widget h2 { font-size: 18px; margin-bottom: 4px; }
.chw-subtitle { font-size: 11px; margin-bottom: 14px; }
.chw-wheel-wrap { width: 170px; height: 170px; margin-bottom: 16px; }
.chw-marker { width: 16px; height: 16px; border-width: 2px; }
.chw-info { font-size: 11px; padding: 6px 14px; gap: 6px; border-radius: 30px; margin-bottom: 16px; }
.chw-info-swatch { width: 18px; height: 18px; }
.chw-palettes { flex-direction: column; align-items: stretch; gap: 10px; }
.chw-card { flex: 1 1 auto; min-width: 100%; max-width: 100%; padding: 12px 12px; border-radius: 12px; }
.chw-card-title { font-size: 12px; margin-bottom: 8px; }
.chw-swatch { gap: 8px; margin-bottom: 6px; }
.chw-swatch-block { width: 24px; height: 24px; border-radius: 5px; }
.chw-swatch-hex { font-size: 11px; }
.chw-swatch-name { font-size: 10px; }
.chw-article { padding: 12px 14px; font-size: 12px; line-height: 1.5; border-radius: 12px; }
.chw-article h3 { font-size: 14px; margin: 12px 0 4px; }
.chw-article .chw-tip { padding: 8px 10px; font-size: 11px; }
}
/* Маленький телефон */
@media (max-width: 360px) {
.chw-widget { padding: 14px 6px; }
.chw-widget h2 { font-size: 16px; }
.chw-wheel-wrap { width: 150px; height: 150px; }
.chw-marker { width: 14px; height: 14px; }
.chw-info { font-size: 10px; padding: 5px 10px; }
.chw-card { padding: 10px 8px; }
.chw-swatch-block { width: 22px; height: 22px; }
.chw-swatch-hex { font-size: 10px; }
.chw-article { font-size: 11px; padding: 10px; }
}
/* Тёмная тема */
@media (prefers-color-scheme: dark) {
.chw-widget { background: #1e1e2e; box-shadow: 0 8px 32px rgba(0,0,0,0.3); }
.chw-widget h2 { color: #e0e0f0; }
.chw-subtitle { color: #aaa; }
.chw-info { background: #2a2a3e; }
.chw-info-name { color: #e0e0f0; }
.chw-info-hex { color: #ddd; }
.chw-card { background: #252535; border-color: #333348; }
.chw-card-title { color: #ccc; }
.chw-swatch:hover { background: rgba(255,255,255,0.04); }
.chw-swatch:active { background: rgba(255,255,255,0.08); }
.chw-swatch-name { color: #aaa; }
.chw-swatch-hex { color: #ddd; }
.chw-article { background: #252535; border-color: #333348; color: #ccc; }
.chw-article h3 { color: #e0e0f0; }
.chw-article .chw-tip { background: #2a2a1e; border-left-color: #ffb300; color: #ddd; }
.chw-copy-toast { background: #555; }
}
</style>
<?php
}
// ==================== СКРИПТ ====================
public function printScript() {
?>
<script id="chw-pro-script">
(function() {
// Словарь цветов
const colorNames = [
{hex:'#FF0000',name:'Красный'},{hex:'#FF4500',name:'Оранжево-красный'},
{hex:'#FFA500',name:'Оранжевый'},{hex:'#FFD700',name:'Золотой'},
{hex:'#FFFF00',name:'Жёлтый'},{hex:'#ADFF2F',name:'Жёлто-зелёный'},
{hex:'#00FF00',name:'Лаймовый'},{hex:'#008000',name:'Зелёный'},
{hex:'#00FF7F',name:'Весенний зелёный'},{hex:'#00CED1',name:'Циан'},
{hex:'#00BFFF',name:'Небесный'},{hex:'#1E90FF',name:'Синий'},
{hex:'#0000FF',name:'Тёмно-синий'},{hex:'#4B0082',name:'Индиго'},
{hex:'#8A2BE2',name:'Фиолетовый'},{hex:'#FF00FF',name:'Маджента'},
{hex:'#FF69B4',name:'Ярко-розовый'},{hex:'#FFC0CB',name:'Розовый'},
{hex:'#A52A2A',name:'Коричневый'},{hex:'#808080',name:'Серый'},
{hex:'#FF8C00',name:'Тёмно-оранжевый'},{hex:'#DC143C',name:'Малиновый'},
{hex:'#20B2AA',name:'Морская волна'},{hex:'#FF6347',name:'Томатный'},
{hex:'#7FFFD4',name:'Аквамарин'},{hex:'#DAA520',name:'Золотистый'},
{hex:'#6A5ACD',name:'Сланцевый синий'},{hex:'#FF1493',name:'Глубокий розовый'},
{hex:'#2E8B57',name:'Морской зелёный'},{hex:'#F0E68C',name:'Хаки'},
{hex:'#CD853F',name:'Перу'},{hex:'#BC8F8F',name:'Розово-коричневый'},
{hex:'#B0C4DE',name:'Светлый стальной'},{hex:'#9370DB',name:'Средний пурпурный'},
{hex:'#3CB371',name:'Средний морской'},{hex:'#FFB6C1',name:'Светло-розовый'},
{hex:'#87CEEB',name:'Небесно-голубой'},{hex:'#FA8072',name:'Лососевый'},
{hex:'#DDA0DD',name:'Сливовый'},{hex:'#F5DEB3',name:'Пшеничный'}
];
// Вспомогательные функции
function hexToRgb(hex){const c=hex.slice(1);const n=parseInt(c,16);return{r:(n>>16)&255,g:(n>>8)&255,b:n&255};}
function rgbToHex(r,g,b){return'#'+((1<<24)+(r<<16)+(g<<8)+b).toString(16).slice(1).toUpperCase();}
function findName(hex){
const t=hexToRgb(hex);let min=Infinity,best='Цвет';
for(const c of colorNames){
const o=hexToRgb(c.hex);
const d=Math.sqrt((t.r-o.r)**2+(t.g-o.g)**2+(t.b-o.b)**2);
if(d<min){min=d;best=c.name;}
}
return best;
}
function hsvToRgb(h,s,v){
h=((h%360)+360)%360;
const i=Math.floor(h/60)%6,f=h/60-i,p=v*(1-s),q=v*(1-f*s),t=v*(1-(1-f)*s);
let r,g,b;
switch(i){
case 0:r=v;g=t;b=p;break;case 1:r=q;g=v;b=p;break;
case 2:r=p;g=v;b=t;break;case 3:r=p;g=q;b=v;break;
case 4:r=t;g=p;b=v;break;case 5:r=v;g=p;b=q;break;
}
return{r:Math.round(r*255),g:Math.round(g*255),b:Math.round(b*255)};
}
// Функция копирования
function copyToClipboard(text, element) {
if (navigator.clipboard && navigator.clipboard.writeText) {
navigator.clipboard.writeText(text).then(function() {
showToast('✅ HEX скопирован: ' + text, element);
}).catch(function() {
fallbackCopy(text, element);
});
} else {
fallbackCopy(text, element);
}
}
function fallbackCopy(text, element) {
const textarea = document.createElement('textarea');
textarea.value = text;
textarea.style.position = 'fixed';
textarea.style.opacity = '0';
textarea.style.left = '-9999px';
document.body.appendChild(textarea);
textarea.select();
try {
document.execCommand('copy');
showToast('✅ HEX скопирован: ' + text, element);
} catch (e) {
showToast('❌ Не удалось скопировать', element);
}
document.body.removeChild(textarea);
}
function showToast(message, element) {
// Удаляем старые уведомления
document.querySelectorAll('.chw-copy-toast').forEach(function(n){n.remove();});
const toast = document.createElement('div');
toast.className = 'chw-copy-toast';
toast.textContent = message;
// Позиционируем над элементом
const rect = element.getBoundingClientRect();
toast.style.left = rect.left + rect.width / 2 + 'px';
toast.style.top = rect.top - 10 + 'px';
toast.style.transform = 'translate(-50%, -100%)';
document.body.appendChild(toast);
// Автоудаление
setTimeout(function() {
if (toast.parentNode) {
toast.remove();
}
}, 1900);
}
// Инициализация всех виджетов
document.querySelectorAll('.chw-widget').forEach(function(w){
const canvas = w.querySelector('canvas');
const marker = w.querySelector('.chw-marker');
const nameEl = w.querySelector('.chw-info-name');
const hexEl = w.querySelector('.chw-info-hex');
const swatchEl = w.querySelector('.chw-info-swatch');
const palettesEl = w.querySelector('.chw-palettes');
const type = parseInt(w.dataset.type) || 3;
const ctx = canvas.getContext('2d');
const S = canvas.width, C = S/2, R = S/2-3;
let hue = 0;
// Рисуем круг
const img = ctx.createImageData(S,S);
const d = img.data;
for(let y=0; y<S; y++){
for(let x=0; x<S; x++){
const dx=x-C, dy=y-C, dist=Math.sqrt(dx*dx+dy*dy);
if(dist<=R){
let ang=Math.atan2(dy,dx)*180/Math.PI;
if(ang<0)ang+=360;
const sat=Math.min(dist/R,1);
const {r,g,b}=hsvToRgb(ang,sat,1);
const i=(y*S+x)*4;
d[i]=r; d[i+1]=g; d[i+2]=b; d[i+3]=255;
}
}
}
ctx.putImageData(img,0,0);
function update(h){
hue = h;
const {r,g,b} = hsvToRgb(h,1,1);
const hex = rgbToHex(r,g,b);
hexEl.textContent = hex;
nameEl.textContent = findName(hex);
swatchEl.style.background = hex;
const rad = h*Math.PI/180;
marker.style.left = (C+Math.cos(rad)*R)+'px';
marker.style.top = (C+Math.sin(rad)*R)+'px';
renderPalettes();
}
function createSwatchElement(hex, name) {
const row = document.createElement('div');
row.className = 'chw-swatch';
row.innerHTML = `
<div class="chw-swatch-block" style="background:${hex};"></div>
<div>
<div class="chw-swatch-hex">${hex}</div>
<div class="chw-swatch-name">${name}</div>
</div>
<span class="chw-swatch-copy-hint">📋</span>
`;
// Обработчик клика для копирования
row.addEventListener('click', function(e) {
e.stopPropagation();
copyToClipboard(hex, row);
});
return row;
}
function renderPalettes(){
palettesEl.innerHTML = '';
const allHarmonies = [
{
key:'complementary',
title:'🎯 Комплементарное',
hues:[hue, (hue+180)%360]
},
{
key:'triadic',
title:'🔺 Триадное',
hues:[hue, (hue+120)%360, (hue+240)%360]
},
{
key:'analogous',
title:'🌀 Аналоговое',
hues:[(hue-30+360)%360, hue, (hue+30)%360]
},
{
key:'tetradic',
title:'🔲 Тетрадное',
hues:[hue, (hue+90)%360, (hue+180)%360, (hue+270)%360]
},
{
key:'split',
title:'✂️ Раздельно-комплементарное',
hues:[hue, (hue+150)%360, (hue+210)%360]
},
{
key:'mono',
title:'🎨 Монохроматическое',
hues:[
{h:hue, s:0.2, v:1},
{h:hue, s:0.4, v:1},
{h:hue, s:0.6, v:1},
{h:hue, s:0.8, v:1},
{h:hue, s:1, v:1}
],
isMono:true
}
];
const selected = allHarmonies.slice(0, type);
selected.forEach(function(harm){
const card = document.createElement('div');
card.className = 'chw-card';
card.innerHTML = '<div class="chw-card-title">' + harm.title + '</div>';
if(harm.isMono){
harm.hues.forEach(function(item){
const {r,g,b} = hsvToRgb(item.h, item.s, item.v);
const hex = rgbToHex(r,g,b);
const name = findName(hex);
card.appendChild(createSwatchElement(hex, name));
});
} else {
harm.hues.forEach(function(h){
const {r,g,b} = hsvToRgb(h, 1, 1);
const hex = rgbToHex(r,g,b);
const name = findName(hex);
card.appendChild(createSwatchElement(hex, name));
});
}
palettesEl.appendChild(card);
});
}
// Копирование по клику на основной цвет
const infoBlock = w.querySelector('.chw-info');
if (infoBlock) {
infoBlock.style.cursor = 'pointer';
infoBlock.title = 'Нажмите, чтобы скопировать HEX';
infoBlock.addEventListener('click', function() {
const hex = hexEl.textContent.trim();
copyToClipboard(hex, infoBlock);
});
}
update(0);
// Обработчики перетаскивания
function getPos(e){
const rect = canvas.getBoundingClientRect();
const sx = canvas.width/rect.width, sy = canvas.height/rect.height;
let cx, cy;
if(e.touches){cx=e.touches[0].clientX; cy=e.touches[0].clientY;}
else{cx=e.clientX; cy=e.clientY;}
return{x:(cx-rect.left)*sx, y:(cy-rect.top)*sy};
}
function onMove(e){
e.preventDefault();
const p = getPos(e);
const dx=p.x-C, dy=p.y-C;
if(Math.sqrt(dx*dx+dy*dy)>R)return;
let a=Math.atan2(dy,dx)*180/Math.PI;
if(a<0)a+=360;
update(a);
}
function onDown(e){
e.preventDefault();
onMove(e);
window.addEventListener('mousemove', onMove);
window.addEventListener('mouseup', onUp);
window.addEventListener('touchmove', onMove, {passive:false});
window.addEventListener('touchend', onUp);
}
function onUp(){
window.removeEventListener('mousemove', onMove);
window.removeEventListener('mouseup', onUp);
window.removeEventListener('touchmove', onMove);
window.removeEventListener('touchend', onUp);
}
canvas.addEventListener('mousedown', onDown);
canvas.addEventListener('touchstart', onDown, {passive:false});
});
})();
</script>
<?php
}
// ==================== СТАТЬИ ====================
private function getArticle($type) {
$articles = [
3 => '
<h3>🎯 Комплементарное сочетание</h3>
<p>Два цвета, расположенных <strong>напротив друг друга</strong> на цветовом круге (разница 180°). Создают максимальный контраст и визуальное напряжение. Идеально для акцентов, кнопок призыва к действию, спортивных брендов.</p>
<div class="chw-tip">💡 Совет: используйте один цвет как основной (фон), а второй — для ключевых элементов. Избегайте равных пропорций — это утомляет глаза.</div>
<h3>🔺 Триадное сочетание</h3>
<p>Три цвета, равномерно распределённые по кругу (через 120°). Дают <strong>яркую, сбалансированную</strong> палитру. Отлично подходит для иллюстраций, детских сайтов, творческих проектов.</p>
<div class="chw-tip">💡 Совет: выберите один доминирующий цвет, а два других используйте для второстепенных элементов. Так палитра останется гармоничной, а не пёстрой.</div>
<h3>🌀 Аналоговое сочетание</h3>
<p>Три соседних цвета на круге (разница ±30°). Создают <strong>спокойное, природное</strong> впечатление. Часто встречаются в пейзажах: трава, листва, небо. Подходит для wellness-брендов, спа, экологии.</p>
<div class="chw-tip">💡 Совет: добавьте контрастный акцент (например, белый или тёмный текст), чтобы интерфейс не выглядел размытым.</div>
',
4 => '
<h3>🎯 Комплементарное</h3>
<p>Два противоположных цвета (180°). Максимальный контраст, привлекает внимание.</p>
<h3>🔺 Триадное</h3>
<p>Три равноудалённых цвета (120°). Ярко и энергично.</p>
<h3>🌀 Аналоговое</h3>
<p>Три соседних цвета (±30°). Мягкость и природная гармония.</p>
<h3>🔲 Тетрадное сочетание</h3>
<p>Четыре цвета — две комплементарные пары (90° между соседними). <strong>Богатая, сложная</strong> палитра. Требует осторожности: лучше выбрать один главный цвет, остальные — для деталей.</p>
<div class="chw-tip">💡 Совет: распределите цвета в пропорции 60/30/10 для наилучшего результата.</div>
',
5 => '
<h3>🎯 Комплементарное</h3>
<p>Противоположные цвета — контраст и драма.</p>
<h3>🔺 Триадное</h3>
<p>Три равноудалённых — баланс и энергия.</p>
<h3>🌀 Аналоговое</h3>
<p>Соседние оттенки — покой и природа.</p>
<h3>🔲 Тетрадное</h3>
<p>Две комплементарные пары — богатство выбора.</p>
<h3>✂️ Раздельно-комплементарное</h3>
<p>Базовый цвет + два соседних от его комплемента (150° и 210°). <strong>Контраст мягче</strong>, чем у чистого комплемента, но интереснее аналогового. Идеально для интерфейсов.</p>
<div class="chw-tip">💡 Совет: одна из самых универсальных схем для веб-дизайна. Базовый цвет для фона, два других для кнопок и иконок.</div>
',
6 => '
<h3>🎯 Комплементарное</h3>
<p>Контраст противоположностей. Эффектно, смело, заметно.</p>
<h3>🔺 Триадное</h3>
<p>Равновесие трёх. Динамика без хаоса.</p>
<h3>🌀 Аналоговое</h3>
<p>Гармония соседей. Природа, уют, спокойствие.</p>
<h3>🔲 Тетрадное</h3>
<p>Четыре цвета — двойной контраст. Для сложных дизайнов.</p>
<h3>✂️ Раздельно-комплементарное</h3>
<p>Мягкий контраст: база + два почти-противоположных. Универсальный выбор.</p>
<h3>🎨 Монохроматическое</h3>
<p>Пять оттенков <strong>одного цвета</strong> с разной насыщенностью. <strong>Элегантно, минималистично, профессионально.</strong> Идеально для корпоративных сайтов и fashion-брендов.</p>
<div class="chw-tip">💡 Совет: добавьте текстуры, градиенты и игру с прозрачностью, чтобы создать глубину без дополнительных цветов.</div>
'
];
return isset($articles[$type]) ? $articles[$type] : $articles[3];
}
// ==================== HTML ====================
private function buildHtml($type) {
$titles = [
3 => 'Цветовой круг: 3 базовые гармонии',
4 => 'Цветовой круг: 4 гармонии',
5 => 'Цветовой круг: 5 гармоний',
6 => 'Цветовой круг: полный набор из 6 гармоний'
];
$subtitles = [
3 => 'Комплементарное • Триадное • Аналоговое',
4 => '+ Тетрадное сочетание',
5 => '+ Раздельно-комплементарное',
6 => '+ Монохроматическое'
];
$title = isset($titles[$type]) ? $titles[$type] : $titles[3];
$subtitle = isset($subtitles[$type]) ? $subtitles[$type] : $subtitles[3];
$article = $this->getArticle($type);
ob_start();
?>
<div class="chw-widget" data-type="<?php echo (int)$type; ?>">
<h2><?php echo esc_html($title); ?></h2>
<p class="chw-subtitle"><?php echo esc_html($subtitle); ?></p>
<div class="chw-wheel-wrap">
<canvas width="250" height="250"></canvas>
<div class="chw-marker"></div>
</div>
<div class="chw-info" title="Нажмите, чтобы скопировать HEX">
<div class="chw-info-swatch" style="background:#FF0000;"></div>
<span class="chw-info-name">Красный</span>
<span class="chw-info-hex">#FF0000</span>
</div>
<div class="chw-palettes"></div>
<div class="chw-article">
<?php echo $article; ?>
</div>
</div>
<?php
return ob_get_clean();
}
// ==================== ШОРТКОДЫ ====================
public function shortcode3($atts) { return $this->buildHtml(3); }
public function shortcode4($atts) { return $this->buildHtml(4); }
public function shortcode5($atts) { return $this->buildHtml(5); }
public function shortcode6($atts) { return $this->buildHtml(6); }
}
// Запуск
ColorHarmonyWheelPro::getInstance();📋 Полный функционал
Возможность Описание
🎨 4 шорткода color_wheel_3], color_wheel_4], color_wheel_5], [color_wheel_6
📋 Копирование HEX Клик на любой цвет → всплывающее уведомление
🖱 Копирование основного Клик на главный инфо-блок тоже копирует HEX
📱 Адаптивность 5 брейкпоинтов: десктоп, планшет, телефон, маленький телефон
🌙 Тёмная тема Автоопределение prefers-color-scheme: dark
📝 Статья Уникальное описание под каждый шорткод
🏷 40+ названий Русские имена цветов
🎯 6 гармоний Комплементарное, триадное, аналоговое, тетрадное, раздельно-комплементарное, монохроматическое
👆 Touch Полная поддержка сенсорных экранов
🔔 Toast-уведомления Плавная анимация при копировании
Добавить комментарий