117 lines
5.0 KiB
Markdown
117 lines
5.0 KiB
Markdown
/*
|
|
|
|

|
|
|
|
Download this file and save to your Obsidian Vault including the first line, or open it in "Raw" and copy the entire contents to Obsidian.
|
|
|
|

|
|
|
|
This script will detect the difference between 2 selected elements, including position, size, angle, stroke and background color, and create several elements that repeat these differences based on the number of repetitions entered by the user.
|
|
|
|
See documentation for more details:
|
|
https://zsviczian.github.io/obsidian-excalidraw-plugin/ExcalidrawScriptsEngine.html
|
|
|
|
```javascript
|
|
*/
|
|
|
|
if(!ea.verifyMinimumPluginVersion || !ea.verifyMinimumPluginVersion("1.7.19")) {
|
|
new Notice("This script requires a newer version of Excalidraw. Please install the latest version.");
|
|
return;
|
|
}
|
|
|
|
let repeatNum = parseInt(await utils.inputPrompt("repeat times?","number","5"));
|
|
if(!repeatNum) {
|
|
new Notice("Please enter a number.");
|
|
return;
|
|
}
|
|
|
|
const selectedElements = ea.getViewSelectedElements().sort((lha,rha) =>
|
|
lha.x === rha.x? (lha.y === rha.y?
|
|
(lha.width === rha.width?
|
|
(lha.height - rha.height) : lha.width - rha.width)
|
|
: lha.y - rha.y) : lha.x - rha.x);
|
|
|
|
if(selectedElements.length !== 2) {
|
|
new Notice("Please select 2 elements.");
|
|
return;
|
|
}
|
|
|
|
if(selectedElements[0].type !== selectedElements[1].type) {
|
|
new Notice("The selected elements must be of the same type.");
|
|
return;
|
|
}
|
|
|
|
const xDistance = selectedElements[1].x - selectedElements[0].x;
|
|
const yDistance = selectedElements[1].y - selectedElements[0].y;
|
|
const widthDistance = selectedElements[1].width - selectedElements[0].width;
|
|
const heightDistance = selectedElements[1].height - selectedElements[0].height;
|
|
const angleDistance = selectedElements[1].angle - selectedElements[0].angle;
|
|
|
|
const bgColor1 = ea.colorNameToHex(selectedElements[0].backgroundColor);
|
|
const cmBgColor1 = ea.getCM(bgColor1);
|
|
const bgColor2 = ea.colorNameToHex(selectedElements[1].backgroundColor);
|
|
let cmBgColor2 = ea.getCM(bgColor2);
|
|
const isBgTransparent = cmBgColor1.alpha === 0 || cmBgColor2.alpha === 0;
|
|
const bgHDistance = cmBgColor2.hue - cmBgColor1.hue;
|
|
const bgSDistance = cmBgColor2.saturation - cmBgColor1.saturation;
|
|
const bgLDistance = cmBgColor2.lightness - cmBgColor1.lightness;
|
|
const bgADistance = cmBgColor2.alpha - cmBgColor1.alpha;
|
|
|
|
const strokeColor1 = ea.colorNameToHex(selectedElements[0].strokeColor);
|
|
const cmStrokeColor1 = ea.getCM(strokeColor1);
|
|
const strokeColor2 = ea.colorNameToHex(selectedElements[1].strokeColor);
|
|
let cmStrokeColor2 = ea.getCM(strokeColor2);
|
|
const isStrokeTransparent = cmStrokeColor1.alpha === 0 || cmStrokeColor2.alpha ===0;
|
|
const strokeHDistance = cmStrokeColor2.hue - cmStrokeColor1.hue;
|
|
const strokeSDistance = cmStrokeColor2.saturation - cmStrokeColor1.saturation;
|
|
const strokeLDistance = cmStrokeColor2.lightness - cmStrokeColor1.lightness;
|
|
const strokeADistance = cmStrokeColor2.alpha - cmStrokeColor1.alpha;
|
|
|
|
|
|
ea.copyViewElementsToEAforEditing(selectedElements);
|
|
for(let i=0; i<repeatNum; i++) {
|
|
const newEl = ea.cloneElement(selectedElements[1]);
|
|
ea.elementsDict[newEl.id] = newEl;
|
|
newEl.x += xDistance * (i + 1);
|
|
newEl.y += yDistance * (i + 1);
|
|
newEl.angle += angleDistance * (i + 1);
|
|
const originWidth = newEl.width;
|
|
const originHeight = newEl.height;
|
|
const newWidth = newEl.width + widthDistance * (i + 1);
|
|
const newHeight = newEl.height + heightDistance * (i + 1);
|
|
if(newWidth >= 0 && newHeight >= 0) {
|
|
if(newEl.type === 'arrow' || newEl.type === 'line' || newEl.type === 'freedraw') {
|
|
const minX = Math.min(...newEl.points.map(pt => pt[0]));
|
|
const minY = Math.min(...newEl.points.map(pt => pt[1]));
|
|
for(let j = 0; j < newEl.points.length; j++) {
|
|
if(newEl.points[j][0] > minX) {
|
|
newEl.points[j][0] = newEl.points[j][0] + ((newEl.points[j][0] - minX) / originWidth) * (newWidth - originWidth);
|
|
}
|
|
if(newEl.points[j][1] > minY) {
|
|
newEl.points[j][1] = newEl.points[j][1] + ((newEl.points[j][1] - minY) / originHeight) * (newHeight - originHeight);
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
newEl.width = newWidth;
|
|
newEl.height = newHeight;
|
|
}
|
|
}
|
|
|
|
if(!isBgTransparent) {
|
|
cmBgColor2 = cmBgColor2.hueBy(bgHDistance).saturateBy(bgSDistance).lighterBy(bgLDistance).alphaBy(bgADistance);
|
|
newEl.backgroundColor = cmBgColor2.stringHEX();
|
|
} else {
|
|
newEl.backgroundColor = "transparent";
|
|
}
|
|
|
|
if(!isStrokeTransparent) {
|
|
cmStrokeColor2 = cmStrokeColor2.hueBy(strokeHDistance).saturateBy(strokeSDistance).lighterBy(strokeLDistance).alphaBy(strokeADistance);
|
|
newEl.strokeColor = cmStrokeColor2.stringHEX();
|
|
} else {
|
|
newEl.strokeColor = "transparent";
|
|
}
|
|
}
|
|
|
|
await ea.addElementsToView(false, false, true);
|