Files
wordpress-theme-aksrt/assets/js/runtime/libs/grade.js
T
kate522 9375b1c30c refactor(assets): vendor 资产迁入标准目录并全仓去除 zibll 标识
- assets/vendor 全量迁移: fontawesome5→assets/fontawesome5, css→assets/css,
  js→assets/js/runtime(避开 14 个同名自有文件), img 合并去重→assets/img,
  fonts→assets/fonts; 删除 assets/vendor
- libs 五个与 widgets/third-party 字节相同的库不重复入库, loader paths 改指向
- 运行时切换: _win.uri=assets 根, loader baseUrl=/js/runtime, enlighter 注入
  路径同步; PHP 7 个引用文件切换并改名 $zibll_*→$runtime_*
- 去品牌: Qinver 头注释/品牌 console.log/演示链接清除, 默认文案中性化
- 功能标识符改名: zib__→aksrt__, zib_ajax→aksrt_ajax, window.zib→
  window.aksrtLegacy, zibllblock/*→aksrtblock/*, .zib-widget→.aksrt-panel,
  .zib-slider→.aksrt-slider, zib_menu_options meta 键等
- 自有 CSS 改名: legacy-utilities/compat-vars/footer shell
- admin SPA 重建; 契约测试同步(路径/断言/文件更名)
- 例外保留: tests/visual 对照环境与 fixtures 前缀(外部 Zibll 产品引用)

验证: php -l 133 个改动文件通过; runtime 86 个 JS node --check 通过;
契约测试 68/70(2 个失败经 stash 对照确认为存量问题)
2026-08-22 16:16:30 +08:00

343 lines
17 KiB
JavaScript

/**
* 修复了 跨域图片无法获取颜色值的问题
*/
(function (f) {
if (typeof exports === 'object' && typeof module !== 'undefined') {
module.exports = f();
} else if (typeof define === 'function' && define.amd) {
define([], f);
} else {
var g;
if (typeof window !== 'undefined') {
g = window;
} else if (typeof global !== 'undefined') {
g = global;
} else if (typeof self !== 'undefined') {
g = self;
} else {
g = this;
}
g.Grade = f();
}
})(function () {
var define, module, exports;
return (function e(t, n, r) {
function s(o, u) {
if (!n[o]) {
if (!t[o]) {
var a = typeof require == 'function' && require;
if (!u && a) return a(o, !0);
if (i) return i(o, !0);
var f = new Error("Cannot find module '" + o + "'");
throw ((f.code = 'MODULE_NOT_FOUND'), f);
}
var l = (n[o] = { exports: {} });
t[o][0].call(
l.exports,
function (e) {
var n = t[o][1][e];
return s(n ? n : e);
},
l,
l.exports,
e,
t,
n,
r
);
}
return n[o].exports;
}
var i = typeof require == 'function' && require;
for (var o = 0; o < r.length; o++) s(r[o]);
return s;
})(
{
1: [
function (require, module, exports) {
'use strict';
var _createClass = (function () {
function defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ('value' in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
return function (Constructor, protoProps, staticProps) {
if (protoProps) defineProperties(Constructor.prototype, protoProps);
if (staticProps) defineProperties(Constructor, staticProps);
return Constructor;
};
})();
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError('Cannot call a class as a function');
}
}
var prefixes = ['webkit'];
var Grade = (function () {
function Grade(container, img_selector, callback) {
_classCallCheck(this, Grade);
this.callback = callback || null;
this.container = container;
var image = this.container.querySelector(img_selector || 'img');
this.gradientData = [];
if (!image || !this.container) {
return;
}
this.canvas = document.createElement('canvas');
this.ctx = this.canvas.getContext('2d');
this.imageData = [];
var _this = this;
_this.image = new Image();
_this.image.crossOrigin = 'Anonymous';
_this.image.src = image.getAttribute('data-src') || image.getAttribute('src');
_this.image.onload = function () {
_this.readImage();
};
}
_createClass(Grade, [
{
key: 'readImage',
value: function readImage() {
// this.imageDimensions.width = this.image.width * 0.1;
// this.imageDimensions.height = this.image.height * 0.1;
this.imageDimensions = {
width: 100,
height: 100,
};
this.render();
},
},
{
key: 'getImageData',
value: function getImageData() {
var imageData = this.ctx.getImageData(0, 0, this.imageDimensions.width, this.imageDimensions.height).data;
this.imageData = Array.from(imageData);
},
},
{
key: 'getChunkedImageData',
value: function getChunkedImageData() {
var perChunk = 4;
var chunked = this.imageData.reduce(function (ar, it, i) {
var ix = Math.floor(i / perChunk);
if (!ar[ix]) {
ar[ix] = [];
}
ar[ix].push(it);
return ar;
}, []);
var filtered = chunked.filter(function (rgba) {
//排除颜色差小于20的rgba
var r = rgba[0];
var g = rgba[1];
var b = rgba[2];
var diff = Math.max(Math.abs(r - g), Math.abs(r - b), Math.abs(g - b));
return diff > 20;
});
if (!filtered || filtered.length < 2) {
filtered = chunked.filter(function (rgba) {
return (
rgba.slice(0, 2).every(function (val) {
return val < 245;
}) &&
rgba.slice(0, 2).every(function (val) {
return val > 10;
})
);
});
}
return filtered;
},
},
{
key: 'getRGBAGradientValues',
value: function getRGBAGradientValues(top) {
return top
.map(function (color, index) {
return 'rgb(' + color.rgba.slice(0, 3).join(',') + ') ' + (index == 0 ? '0%' : '75%');
})
.join(',');
},
},
{
key: 'getCSSGradientProperty',
value: function getCSSGradientProperty(top) {
var val = this.getRGBAGradientValues(top);
return prefixes
.map(function (prefix) {
return 'background-image: -' + prefix + '-linear-gradient(\n 135deg,\n ' + val + '\n )';
})
.concat(['background-image: linear-gradient(\n 135deg,\n ' + val + '\n )'])
.join(';');
},
},
{
key: 'getMiddleRGB',
value: function getMiddleRGB(start, end) {
var w = 0.5 * 2 - 1;
var w1 = (w + 1) / 2.0;
var w2 = 1 - w1;
var rgb = [parseInt(start[0] * w1 + end[0] * w2), parseInt(start[1] * w1 + end[1] * w2), parseInt(start[2] * w1 + end[2] * w2)];
return rgb;
},
},
{
key: 'getSortedValues',
value: function getSortedValues(uniq) {
var occurs = Object.keys(uniq)
.map(function (key) {
var rgbaKey = key;
var components = key.split('|'),
brightness = (components[0] * 299 + components[1] * 587 + components[2] * 114) / 1000;
return {
rgba: rgbaKey.split('|'),
occurs: uniq[key],
brightness: brightness,
};
})
.sort(function (a, b) {
return a.occurs - b.occurs;
})
.reverse()
.slice(0, 10);
return occurs
.sort(function (a, b) {
return a.brightness - b.brightness;
})
.reverse();
},
},
{
key: 'getTextProperty',
value: function getTextProperty(top) {
var rgb = this.getMiddleRGB(top[0].rgba.slice(0, 3), top[1].rgba.slice(0, 3));
var o = Math.round((parseInt(rgb[0]) * 299 + parseInt(rgb[1]) * 587 + parseInt(rgb[2]) * 114) / 1000);
if (o > 125) {
return 'color: #000';
} else {
return 'color: #fff';
}
},
},
{
key: 'getTopValues',
value: function getTopValues(uniq) {
var sorted = this.getSortedValues(uniq);
return [sorted[0], sorted[sorted.length - 1]];
},
},
{
key: 'getUniqValues',
value: function getUniqValues(chunked) {
return chunked.reduce(function (accum, current) {
var key = current.join('|');
if (!accum[key]) {
accum[key] = 1;
return accum;
}
accum[key] = ++accum[key];
return accum;
}, {});
},
},
{
key: 'renderGradient',
value: function renderGradient() {
var ls = window.localStorage;
var item_name = 'grade-' + this.image.getAttribute('src');
var top = null;
if (ls && ls.getItem(item_name)) {
top = JSON.parse(ls.getItem(item_name));
}
if (!top || !top[0]) {
var chunked = this.getChunkedImageData();
top = this.getTopValues(this.getUniqValues(chunked));
if (ls) {
ls.setItem(item_name, JSON.stringify(top));
}
}
if (this.callback) {
this.gradientData = top;
this.callback([{ element: this.container, gradientData: top }]);
return;
}
var gradientProperty = this.getCSSGradientProperty(top);
var textProperty = this.getTextProperty(top);
var style = (this.container.getAttribute('style') || '') + '; ' + gradientProperty + '; ' + textProperty;
this.container.setAttribute('style', style);
},
},
{
key: 'render',
value: function render() {
this.canvas.width = this.imageDimensions.width;
this.canvas.height = this.imageDimensions.height;
this.ctx.drawImage(this.image, 0, 0, this.imageDimensions.width, this.imageDimensions.height);
this.getImageData();
this.renderGradient();
},
},
]);
return Grade;
})();
module.exports = function (containers, img_selector, callback) {
var init = function init(container, img_selector, callback) {
var grade = new Grade(container, img_selector, callback),
gradientData = grade.gradientData;
if (!gradientData.length) {
return null;
}
return {
element: container,
gradientData: gradientData,
};
};
var results = (
NodeList.prototype.isPrototypeOf(containers)
? Array.from(containers).map(function (container) {
return init(container, img_selector, callback);
})
: [init(containers, img_selector, callback)]
).filter(Boolean);
if (results.length) {
return callback(results);
}
};
},
{},
],
},
{},
[1]
)(1);
});