Skip to content

Commit

Permalink
Merge pull request #1 from L21s/feature/fill_background
Browse files Browse the repository at this point in the history
Feature/fill background
  • Loading branch information
schmitzhermes authored Feb 12, 2024
2 parents 5056fc5 + c3f1ad9 commit 9b511db
Show file tree
Hide file tree
Showing 9 changed files with 284 additions and 50 deletions.
5 changes: 4 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,8 @@
],
"extends": [
"plugin:office-addins/recommended"
]
],
"env": {
"browser": true
}
}
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -174,4 +174,7 @@ dist
# SvelteKit build / generate output
.svelte-kit

# IDEA
.idea

# End of https://www.toptal.com/developers/gitignore/api/macos,node
42 changes: 42 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# L21s PowerPoint-AddIn

## Set up Locally

To start the AddIn locally, `Node.js` and `npm` must be installed.
An activated version of `PowerPoint` is also required.

To prepare the project for the first execution, the following two commands must be executed one after the other:

```zsh Terminal
npm install
```

```zsh Terminal
npm run build:dev
```

After the project has been successfully built, the following command starts the AddIn.

```zsh Terminal
npm run start:desktop
```

A new PowerPoint instance should be started at startup. After a few moments, the version of the AddIn can be seen in
this instance. This is reflected as follows. If an installation of the AddIn already exists, the icon on the right-hand
side is the locally started one.

![Debug AddIn](docs/addInNew.png)

While the code is being edited, the AddIn should be continuously updated (HotReload) so that the DevServer does not have
to be restarted. As soon as the local instance is no longer required, it can be terminated with the following
command:

```zsh Terminal
npm run stop
```

## Helpful links

[PowerPoint Api-Documentation](https://learn.microsoft.com/de-de/javascript/api/powerpoint?view=powerpoint-js-preview)
[Office AddIn Scripts](https://github.com/OfficeDev/Office-Addin-Scripts)
[Office AddIn Samples](https://github.com/OfficeDev/Office-Add-in-samples)
Binary file added docs/addInNew.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
139 changes: 112 additions & 27 deletions package-lock.json

Large diffs are not rendered by default.

8 changes: 8 additions & 0 deletions src/taskpane/taskpane.css
Original file line number Diff line number Diff line change
Expand Up @@ -77,4 +77,12 @@

b {
font-weight: bold;
}

.content {
display: flex;
justify-content: space-between;
flex-direction: column;
margin: 0 auto;
gap: 5px;
}
20 changes: 20 additions & 0 deletions src/taskpane/taskpane.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,26 @@ <h1 class="ms-font-su">L21s PP</h1>
<h3>Sticker</h3>
<button class="ms-Button" id="yellow-sticker">Yellow</button>
<button class="ms-Button" id="cyan-sticker">Cyan</button><br/><br/>

<h3>Image with Background</h3>
<div class="content">
<div>
<input type="color" id="image-background-color" name="head" value="#FFFFFF" />
<label for="image-background-color">Background color</label>
</div>
<input type='file' accept='image/*' id="load-image"><br>
<button class="ms-Button" id="insert-image">Insert Image</button>
</div>

<h3>Background Options</h3>
<div class="content">
<div>
<input type="color" id="background-color" name="head" value="#FFFFFF" />
<label for="background-color">Background color</label>
</div>
<button class="ms-Button" id="fill-background">Fill</button>
<button class="ms-Button" id="remove-background">Remove</button>
</div>
</div>
</section>
</body>
Expand Down
114 changes: 93 additions & 21 deletions src/taskpane/taskpane.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,40 +3,112 @@
* See LICENSE in the project root for license information.
*/

/* global document, Office */
/* global Office, PowerPoint */

Office.onReady((info) => {
if (info.host === Office.HostType.PowerPoint) {
let initials = <HTMLInputElement>document.getElementById("initials")
initials.value = localStorage.getItem("initials")
let initials = <HTMLInputElement>document.getElementById("initials");
initials.value = localStorage.getItem("initials");

document.getElementById("yellow-sticker").onclick = () => insertSticker("yellow");
document.getElementById("cyan-sticker").onclick = () => insertSticker("#00ffff");
document.getElementById("save-initials").onclick = () => localStorage.setItem("initials", ((<HTMLInputElement>document.getElementById("initials")).value))
document.getElementById("fill-background").onclick = () => {
const colorPicker = <HTMLInputElement>document.getElementById("background-color");
const selectedColor = colorPicker.value;
addBackground(selectedColor);
};
document.getElementById("remove-background").onclick = () => removeBackground();
document.getElementById("insert-image").onclick = () => {
const colorPicker = <HTMLInputElement>document.getElementById("image-background-color");
const selectedColor = colorPicker.value;
insertImageWithBackground(selectedColor);
};
document.getElementById("load-image").onchange = (event) => {
loadImageIntoLocalStorage(event.target as HTMLInputElement);
};
document.getElementById("yellow-sticker").onclick = () => insertSticker("yellow");
document.getElementById("cyan-sticker").onclick = () => insertSticker("#00ffff");
document.getElementById("save-initials").onclick = () =>
localStorage.setItem("initials", (<HTMLInputElement>document.getElementById("initials")).value);
}
});

function loadImageIntoLocalStorage(input?: HTMLInputElement) {
if (!input) return;
const file = input.files[0];
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function () {
const base64String = (reader.result as string).replace(new RegExp("^data.{0,}base64,"), "");
localStorage.setItem("base64Image", base64String);
};
}

export async function insertSticker(color) {
await PowerPoint.run(async (context) => {

const today = new Date()
const shapes = context.presentation.getSelectedSlides().getItemAt(0).shapes
const textbox = shapes.addTextBox(localStorage.getItem("initials") + ", " + today.toDateString() + "\n");
await runPowerPoint((powerPointContext) => {
const today = new Date();
const shapes = powerPointContext.presentation.getSelectedSlides().getItemAt(0).shapes;
const textbox = shapes.addTextBox(localStorage.getItem("initials") + ", " + today.toDateString() + "\n");
textbox.left = 50;
textbox.top = 50;
textbox.height = 50;
textbox.width = 150;
textbox.name = "Square";
textbox.fill.setSolidColor(color)
textbox.textFrame.textRange.font.bold = true
textbox.textFrame.textRange.font.name = "Arial"
textbox.textFrame.textRange.font.size = 12
textbox.textFrame.textRange.font.color = "#5A5A5A"
textbox.lineFormat.visible = true
textbox.lineFormat.color = "#000000"
textbox.lineFormat.weight = 1.5
console.log(textbox.lineFormat.toJSON)
textbox.fill.setSolidColor(color);
textbox.textFrame.textRange.font.bold = true;
textbox.textFrame.textRange.font.name = "Arial";
textbox.textFrame.textRange.font.size = 12;
textbox.textFrame.textRange.font.color = "#5A5A5A";
textbox.lineFormat.visible = false;
textbox.lineFormat.visible = false;
console.log(textbox.lineFormat.toJSON);
});
}

export async function addBackground(backgroundColor?: string) {
if (!backgroundColor) backgroundColor = "white";
await runPowerPoint((powerPointContext) => {
const selectedImage = powerPointContext.presentation.getSelectedShapes().getItemAt(0);
selectedImage.fill.setSolidColor(backgroundColor);
});
}

export async function removeBackground() {
await runPowerPoint((powerPointContext) => {
const selectedImage = powerPointContext.presentation.getSelectedShapes().getItemAt(0);
selectedImage.fill.clear();
});
}

export async function insertImageWithBackground(backgroundColor?: string) {
if (!backgroundColor) backgroundColor = "white";
const base64Image = localStorage.getItem("base64Image");
await runPowerPoint((powerPointContext) => {
Office.context.document.setSelectedDataAsync(
base64Image,
{
coercionType: Office.CoercionType.Image,
},
async () => {
const id = await getNewestShapeIdAsync();
const shapes = powerPointContext.presentation.getSelectedSlides().getItemAt(0).shapes;
shapes.getItem(id).fill.setSolidColor(backgroundColor);
await powerPointContext.sync();
}
);
});
}

async function getNewestShapeIdAsync() {
return await PowerPoint.run(async function (context) {
const shapes = context.presentation.getSelectedSlides().getItemAt(0).shapes.load();
await context.sync();
const length = shapes.items.length;
return shapes.items[length - 1].id;
});
}

export async function runPowerPoint(updateFunction: (context: PowerPoint.RequestContext) => void) {
await PowerPoint.run(async (context) => {
updateFunction(context);
await context.sync();
});
}
}
3 changes: 2 additions & 1 deletion webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,9 @@ module.exports = async (env, options) => {
con = con.replace(new RegExp("1\.0\.0\.0", "g"), "1.0.0." + process.env.BUILD_NUMBER);
return con;
}
return content;
},
}
},
],
}),
new HtmlWebpackPlugin({
Expand Down

0 comments on commit 9b511db

Please sign in to comment.