I’m making XD plugin for changing color selected items.
I refer to plugin sample that “ui-hello-vue”.
I can showing dialog,but selected items can not change colors.
Consolo show:
not permitted to make changes from the background. Return a Promise to continue execution asynchronously.
I can find information for “object change attribute must asynchronously”,but “return new Promise” in child component resolve error…
what is bad ?
its main.js
// temporary stubs required for Vue. These will not be required as soon as the XD environment provides setTimeout/clearTimeout
global.setTimeout = function (fn) { fn() }
global.clearTimeout = function () { };
const styles = require("./styles.css");
const Vue = require("vue").default;
const color = require("./color.vue").default;
const { Rectangle,Text, Color } = require("scenegraph");
const chroma = require("chroma-js");
global.chroma = chroma;
function getDialog() {
document.body.innerHTML = `<dialog><div id="container"></div></dialog>`
return document.querySelector("dialog");
}
async function colorChanger(selection){
return new Promise(function(resolve,reject){
if(selection.items[0]){
const dialog = getDialog();
const result = dialog.showModal();
if(result){
var app = new Vue({
el: "#container",
components: { color },
render(h) {
return h(color,{
props: {dialog,selection}
})
}
});
}
}
resolve();
});
}
module.exports = {
commands: {
colorChanger
}
};
its color.vue
<template>
<div class="row">
<form action="">
<div class="col" v-for="(elem,i) in color">
<div>
<h3>{{ elem.disp }}</h3>
</div>
<div>
<input type="range" min="-180" max="180" step="1" v-model="color[i].num" v-on:change="updateColor" v-if="i == 'h'" />
<input type="range" min="-50" max="50" step="1" v-model="color[i].num" v-on:change="updateColor" v-else />
</div>
<div>{{ elem.num }}</div>
</div>
<footer class="col col-btn">
<button v-on:click="reset">reset</button>
<button v-on:click="close">close</button>
</footer>
</form>
</div>
</template>
<script>
const { Rectangle,Text, Color } = require("scenegraph");
module.exports = {
props: {
dialog: {
type: Object
},
selection: {
type: Object
}
},
methods: {
close(){
var vm = this;
vm.dialog.close();
},
reset(){
this.$set(this.color.h,'num',0);
this.$set(this.color.s,'num',0);
this.$set(this.color.l,'num',0);
},
getColor(rgba){
return new Color({
r: rgba[1],
g: rgba[2],
b: rgba[3],
a: rgba[4] || 1,
});
},
updateColor(){
var vm = this;
vm.selection.items.forEach(function(elem,i){
vm.setColor(elem);
});
},
setColor(elem){
var vm = this;
if(elem.fill.value){
var currentColor = chroma(elem.fill.r,elem.fill.g,elem.fill.b);
var newColor = currentColor.hsl(currentColor.get('hsl.h') + vm.color.h.num,currentColor.get('hsl.s') + vm.color.s.num,currentColor.get('hsl.l') + vm.color.l.num);
vm.setColorFunc(elem,newColor,vm);
}
},
setColorFunc(elem,newColor){
var vm = this;
console.log('fill');
elem.fill = vm.getColor(newColor);
}
},
data() {
return {
color: {
h: {
num: 0,
disp: 'H'
},
s: {
num: 0,
disp: 'S'
},
l: {
num: 0,
disp: 'B'
}
}
}
}
}
</script>
<style scoped>
.row {
width: 500px;
}
.col {
display: flex;
align-items: center;
}
form > div + div {
margin-top: 20px;
}
.col > div:nth-child(2) {
flex: 1 1 auto;
}
.col > div:nth-child(1),
.col > div:nth-child(3) {
text-align: center;
flex: none;
width: 50px;
}
.col-btn {
justify-content: flex-end;
}
</style>
thanks.