1 Star 4 Fork 0

Arnie/ThemeStudio 扩展程序

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
hwt-ext.js 12.41 KB
一键复制 编辑 原始数据 按行查看 历史
Arnie 提交于 2022-04-16 01:28 . Fixed bugs and increased stability
/*!
* Huawei ThemeStudio Extensions
* @version 1.0.1
* @author Arnie
* @copyright (c) 2022-present arnie.info All Rights Reserved.
*/
function hwt_ext() {
this.base_url = 'https://arnie.gitee.io/hwt-ext/';
this.locale = localStorage.getItem('com.huawei.hwtdesigner.locale');
this.plugins = {
hwt_ext: {path: 'SELF', loaded: false},
jscolor: {path: 'jscolor/jscolor.min.js', loaded: false},
};
// Vocabularies
this.vocab = {
'bg_color' : {en: 'Background Color', cn: '背景颜色'},
'dial_outline' : {en: 'Dial Outline', cn: '表盘轮廓'},
'option' : {en: 'Option', cn: '自定义选项'},
};
/** Get Vocabulary */
this.get_vocab = ( key_name ) => {
return this.vocab[key_name][this.locale];
};
/** Set view names */
this.set_view_names = function(elem, ancestor) {
const names = ancestor.getAttributeNames();
for (let i = 0; i < names.length; i += 1) {
if (names[i].indexOf('data-v') > -1) {
elem.setAttribute(names[i], '');
}
}
};
/** Event agent */
this.event_agent = function(selector, event, callback) {
let times = 0;
let timer = setInterval(()=>{
let elem = document.querySelector(selector);
if (elem || times > 99) {
clearInterval(timer);
if (elem) {
if (event === 'load') callback();
else elem.addEventListener(event, callback);
}
}
times += 1;
},100);
};
/** Listen to document changes */
const observer = new MutationObserver( () => {
// delete project
if (location.hash.indexOf('/watchindex') > -1) {
let projects = document.querySelectorAll('.right-main');
for (let i = 0; i < projects.length; i += 1) {
let btn_delete = projects[i].querySelector('button:last-child');
btn_delete.onclick = () => {
let name = projects[i].querySelector('.name').innerText;
name = name.replace(/^\s+|\s+$/g).replaceAll(' ','_');
// confirm delete
setTimeout(() => {
let query = '.delete-dialog .btn:not(.cancle-btn)';
document.querySelector(query).onclick = ()=>{
localStorage.removeItem('layer.'+name);
}
},100);
}
}
}
});
observer.observe(document, {childList: true, subtree: true});
}
/** Initialize the plugin */
hwt_ext.prototype.init = function() {
// initialize the interface
const init_interface = ()=> {
let route = window.location.hash;
let is_watch_face = route.indexOf('/watch?') === 1;
let is_phone_theme = route.indexOf('/menu/') === 1;
if (is_watch_face) new watch_face;
if (is_phone_theme) new phone_theme;
};
init_interface();
// listen for hash changes
const _history = function(type) {
const orig = history[type];
const e = new Event(type);
return function() {
const rv = orig.apply(this, arguments);
e.arguments = arguments; window.dispatchEvent(e);
return rv;
};
};
history.pushState = _history('pushState');
window.addEventListener('pushState', init_interface);
// show success message
if (! this.plugins.hwt_ext.loaded) {
let message = 'The plugin is loaded and initialized successfully. ';
let style = 'color:white;background:#006400;font-size:12px;padding:3px';
console.log('%c'+message, style);
this.plugins.jscolor.loaded = false;
}
}
/**
* Watch face
*/
function watch_face() {
this._pub = new hwt_ext;
// current project's name
this.get_project_name = () => {
let array = location.hash.match(/\?watchFaceName=(.*)/);
return array[1].replaceAll('%20','_');
};
// watch face layers
this._pub.event_agent('.watch-layer-select-wrapper', 'load', ()=>{
this.init_layers();
});
// recorder
this._pub.event_agent('.watch-record-icon', 'click', ()=>{
if (! document.fullscreenElement)
document.documentElement.requestFullscreen();
setTimeout(()=>{
this.init_recorder();
document.getElementsByClassName('record-tool')[0].lastChild
.addEventListener('click', ()=>{
document.exitFullscreen()
});
},100);
});
}
/** Initialize recorder */
watch_face.prototype.init_recorder = function(){
this.show_outline = false;
const watch_img = this._pub.base_url + 'images/watch.png';
const watch_img_size = 960;
const dial_base_size = 466;
const color_plugin = this._pub.base_url + this._pub.plugins.jscolor.path;
this.record_tools = document.getElementsByClassName('record-tool')[0];
this.record_area = document.getElementById('watch-record-arae');
this.preview_wrap = document.getElementsByClassName('preview-record-warp')[0];
this.dial_wrap = this.preview_wrap.children[1].firstChild;
document.getElementsByClassName('record-tool-null')[0].style.display = 'none';
const dial = this.dial_wrap.lastChild;
let dial_width = dial.clientWidth;
let dial_height = dial.clientHeight;
if (dial_width !== dial_height) return;
// button to show/hide the outline
let btn_outline = document.createElement('button');
btn_outline.className = 'btn';
btn_outline.innerText = this._pub.get_vocab('dial_outline');
this._pub.set_view_names(btn_outline, this.record_tools);
btn_outline.addEventListener('click', () => { this.set_outline_visib() });
this.record_tools.prepend(btn_outline);
// button to set background color
let btn_color = document.createElement('button');
btn_color.className = 'btn';
btn_color.innerText = this._pub.get_vocab('bg_color');
this._pub.set_view_names(btn_color, this.record_tools);
btn_color.setAttribute('id','btn-color-picker');
// color picker
const init_color_picker = ()=>{
this.record_tools.prepend(btn_color);
let bg_color = localStorage.getItem('video.bg_color') || '#000000';
let option = {
backgroundColor: '#585858',
value: bg_color,
previewElement: "#watch-record-arae",
onChange: function() {
localStorage.setItem('video.bg_color', this.toString() )
}
};
new jscolor(btn_color, option);
this._pub.plugins.jscolor.loaded = true;
}
if (this._pub.plugins.jscolor.loaded) {
init_color_picker();
} else {
let js_color = document.createElement('script');
js_color.src = color_plugin;
document.getElementsByTagName('body')[0].appendChild(js_color);
js_color.onload = init_color_picker;
}
// the outline of watch
let watch_outline = document.createElement('div'),
style = `position:absolute; left: 50%; top: 50%; opacity:0;
width:${watch_img_size}px; height:${watch_img_size}px;
background-image: url(${watch_img}); background-size:cover;
-webkit-transform:translate(-50%,-50%);`;
watch_outline.setAttribute('style', style);
watch_outline.style.zoom = dial_width / dial_base_size;
let area_width = this.record_area.clientWidth;
let scale = area_width / dial_width;
this.dial_wrap.style.WebkitTransform = `scale( ${scale} )`;
this.dial_wrap.style.zoom = '1';
this.max_scale = scale;
this.min_scale = area_width / (watch_img_size*watch_outline.style.zoom);
this.dial_wrap.prepend(watch_outline);
this.watch_outline = watch_outline;
}
/** Set visibility of the watch outline */
watch_face.prototype.set_outline_visib = function(e) {
this.watch_outline.style.WebkitTransition = 'opacity 300ms linear';
this.dial_wrap.style.WebkitTransition = 'transform 300ms linear';
// show outline
if (! this.show_outline) {
this.watch_outline.style.opacity = 1;
this.dial_wrap.style.WebkitTransform = `scale( ${this.min_scale} )`;
this.show_outline = true;
}
// hide outline
else {
this.watch_outline.style.opacity = 0;
this.dial_wrap.style.WebkitTransform = `scale( ${this.max_scale} )`;
this.show_outline = false;
}
}
/** Initialize layers */
watch_face.prototype.init_layers = function() {
this.layers_initialized = false;
const key_name = 'layer.'+this.get_project_name();
let layers_json = localStorage.getItem(key_name);
let layers_data = layers_json ? JSON.parse(layers_json) : null;
setTimeout(() => {
this.traverse_layers(true, layers_data);
},100)
const layers_area = document.querySelector('.layer-layer-area');
const option = { attributes: true, childList: true, subtree: true };
const observer = new MutationObserver( () => {
if (this.layers_initialized) {
let data = this.traverse_layers();
let data_str = JSON.stringify(data);
localStorage.setItem(key_name, data_str);
}
});
observer.observe(layers_area, option);
}
/** Traverse the layer list */
watch_face.prototype.traverse_layers = function(init = false, data = null) {
const unlock_code = 'NvbWJpbmVkLVNoYXBlIiBmaWxsPSIjMD';
const visib_code = 'AgICAgICAgPHVzZSBpZD0iQ29tYmluZW';
let layer_names = [];
const traverse = (tree, items_data) => {
let list_data = [];
let hide_count = 0;
let lock_count = 0;
for (let i = 0; i < tree.childElementCount; i += 1) {
let item = tree.children[i];
let item_head = item.querySelector('[class^=layer]');
if (! item_head) continue;
// layer's name
let name_selector = '.layer-name,.label-name,.widget-label-name';
let name = item_head.querySelector(name_selector).innerText;
name = name.replace(/^\s+|\s+$/g,'').replace(/\s{2,}/,' ');
let btn_v = item_head.querySelector('.operate-start').firstChild;
let btn_l = item_head.querySelector('.operate-item:last-child');
let ico_t = item_head.querySelector('[class^=layer]');
// layer/group status
let hide = btn_v.firstChild.style.WebkitMask.indexOf(visib_code)>-1
? 0 : 1;
let lock = btn_l.firstChild.style.WebkitMask.indexOf(unlock_code)>-1
? 0 : 1;
let fold = ico_t.className.indexOf('down') > -1
? 0 : 1;
let group = null;
// when the custom options group has existed, skip it.
let prefix = this._pub.get_vocab('option');
let skip = (name.indexOf(prefix)>-1 && layer_names.indexOf(name)>-1);
if (! skip) {
// layer subgroup
let subitems = item.querySelector('[class^=layer][class$=area]');
if (subitems) {
let data = items_data ? items_data[i].group : null;
let items = traverse(subitems, data); // recursion
group = items.list_data;
hide = items.hide_all ? 1 : 0;
lock = items.lock_all ? 1 : 0;
}
// simulate click event
if (init && items_data) {
if (items_data[i].hide) {btn_v.click(); hide = 1}
if (items_data[i].lock) {btn_l.click(); lock = 1}
if (items_data[i].fold && subitems) {ico_t.click();fold = 1}
}
layer_names.push(name);
}
if (hide) hide_count += 1;
if (lock) lock_count += 1;
list_data.push({ hide, lock, fold, group });
}
let lock_all = lock_count===list_data.length;
let hide_all = hide_count===list_data.length;
return {list_data, lock_all, hide_all};
}
const layers_area = document.querySelector('.layer-layer-area');
let layers = traverse(layers_area, data);
if (init) this.layers_initialized = true;
return layers.list_data;
}
/**
* Phone theme
*/
function phone_theme() {
let message = 'The extension for phone theme is not yet developed.';
let style = 'color:white;background:#fb7e31;font-size:12px;padding:3px';
console.log('%c'+message, style);
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
JavaScript
1
https://gitee.com/arnie/hwt-ext.git
git@gitee.com:arnie/hwt-ext.git
arnie
hwt-ext
ThemeStudio 扩展程序
master

搜索帮助