- 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 对照确认为存量问题)
343 lines
17 KiB
JavaScript
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);
|
|
});
|