I'm super frustrated with this.
first for you to understand my code - My goal here is for the user to get randomly selected word appear to them in a way that every letter sits inside of a box.
Then if the user clicks on a button called "Pick a word", another word will be selected and the correct number of boxes will appear.
I have an array of words like this:
var word_group_1 = ["abolsh", "absorbent", "betrayal", "frutish", "commensurate", "eonfident", "zite"]
I'm using this function to select a random word from that array then splice it.. works perfectly:
function random_word_genereator() {
random = randomNumber(0, word_group_1.length);
//putting the chosen word from array in the chosen word variable
chosen_word = word_group_1[random]
//after we used the chosen word were removing it from the away
word_group_1.splice(random, 1)
//splitting the chosen word into an array
chosen_word_letters_arry = chosen_word.split("")
}
in a button click of "pick a word"- I'm creating 5 instances of a Movieclip I have in my library (just a blue box to put text in it) with text in at like this:
function create_boxes(e)
{
//to know which word has been displayed to the user//
old_word=chosen_word
random_word_genereator()
for (i=0;i<chosen_word.length;i++){
cell_boxes = new lib.cell_box();
stage.addChild(cell_boxes)
cell_boxes.name="cell_box"+i;
cell_boxes.x=(xlocation * i) + 50
cell_boxes.y = 80;
output = new createjs.Text();
cell_boxes.addChild(output)
output.text=chosen_word_letters_arry[i]
}
everything works fine on the first click As You Can View Here.
The word being selected and displayed on the stage
my problem is when I'm clicking Again on the button "pick a word"
its not deleting the correct number of boxes.
I'm putting visible false to the boxes which holds the "Old word" (the one I need to delete)
but As you can se here After I click again its getting messed up.
sometimes its's working, switches from 12 letter word, to a 4 one.
but it should be luck. I'm dying to get this to WORK! its for my school project.
Please help me!
Easy answer that will plug and play into your code:
js
...
//to know wichh word has been displayed to the user//
old_word=chosen_word
random_word_genereator()
for (i = 0; i < stage.numChildren; i++) // Loop through all children of the stage
if (stage.getChildAt(i) is lib.cell_box) // Checks if the child is a lib.cell_box
stage.removeChildAt(i--); // Removes child from stage and decrements i
for (i=0;i<chosen_word.length;i++){
...
Original answer (cleaner code, some restructuring):
It's best to break this kind of logic down into steps.
var boxes:MovieClip = new MovieClip();
boxes.y = 80;
addChild(boxes);
...
function createBoxes(word:String):void {
// Remove boxes first
while (boxes.numChildren > 0)
boxes.removeChildAt(0);
// Add boxes
for each(var c:String in word.split("")) {
var box:Box = new Box(c);
box.x = boxes.width + 50;
boxes.addChild(box);
}
}
Then set the text inside a Box class.
I am trying to find the answer in Google Slides API references for how to set the background color of a shape I have in my Google Slide. I have given it the title (using Alt Text feature) "rectangle1", so my intention is to write the code along the lines of "if shape's property "title" == "rectangle1", then set background color to red."
I can't see a single reference to "SetBackgroundFill" or SetBackgroundColor, or anything of that sort.
Is it possible?
This is another possible answer, using a so-called "container bound script", which is only accessible through the specific Slide's Tools/Script Editor menu (no other way, or else it won't work).
I found that this "container bound script" approach gives me more power over my slide, and it avoids these expensive calls to "batchUpdate", when using "stand alone" scripts as in my other "self-answer".
So, in a way, I recommend it to myself, but, perhaps, to someone else, my other approach would be a better choice.
For one thing, this approach has a much faster response time.
var hex_color = '#54BdeF';
function test1() {
var selection = SlidesApp.getActivePresentation().getSelection();
var currentPage = selection.getCurrentPage();
var selectionType = selection.getSelectionType();
var shapes = currentPage.getShapes();
for (i=0; i < shapes.length; i++) {
if (shapes[i].getTitle() == 'rectangle1') {
shape_fill = shapes[i].getFill();
shape_fill.setSolidFill(hex_color);
}
}
}
Again, as before, I would welcome any comments and suggestions.
To set background color, you need Element Operations.
The Slides API allows you to create and edit a variety of page
elements, including text boxes, images, tables, basic shapes, lines,
and embedded videos. The examples on this page show some common page
element operations that can be achieved with the API.
Following the steps specified here will do the changes in your specified shape or element. Check the example.
Well, here is my solution. If someone sees a way to improve it, I am all ears, but so far, it appears to work for me glitch-free.
First, I find the shape I am after using the following logic:
function ChangeColorMain()
{
ChangeShapeBackgroundColor('title', 'rectangle1', color_to_repl_r, color_to_repl_g, color_to_repl_b, alpha_value );
}
function ChangeShapeBackgroundColor(shape_property_name, shape_property_value, color_to_set_r, color_to_set_g, color_to_set_b) {
Logger.log( 'ChangeShapeBackgroundColor(shape_property_name=%s, shape_property_value=%s, color_to_set_r=%s, color_to_set_g=%s, color_to_set_b=%s) ',
shape_property_name, shape_property_value, color_to_set_r, color_to_set_g, color_to_set_b);
var presentation = Slides.Presentations.get(presentationId);
var slides = presentation.slides;
Logger.log('The presentation contains %s slides:', slides.length);
for (i = 0; i < slides.length; i++) {
for (j = 0; j < slides[i].pageElements.length; j++ ) {
if (shape_property_name == 'title' && shape_property_value == slides[i].pageElements[j].title) {
Logger.log('Found it');
//slides[i].pageElements[j].shape.shapeProperties.shapeBackgroundFill.solidFill.color.rgbColor.red = color_to_set_r;
SubmitRequest(slides[i].pageElements[j].objectId, color_to_set_r, color_to_set_g, color_to_set_b, alpha_value);
}
} //end of for that iterates through every element
}
}
So, you'll notice that I start my process by calling the function "ChangeColorMain" which also gets my global variables color_to_repl_r... which are defined in a different file of my google script project, but that's not important.
Once inside the ChangeShapeBackgroundColor(), I iterate through all "PageElements" on my slide (see the relevant for loops) and use if statements to check if I got to the shape I am looking for. Finally, once I have located it, I call the all important function SubmitRequest(), which is "expensive". You can't make too many calls in one day, or else Google blocks this function until the day ends. But not a problem if you are making less than 500 calls per day (this number might be wrong/might change).
Here are the details of "SubmitRequest()" which I was able to create by finally figuring out how to make sense of this reference page:
https://developers.google.com/slides/reference/rest/v1/presentations/request#UpdateShapePropertiesRequest
function SubmitRequest(shape_id, r, g, b, a) {
var rgb_color = {
red: r,
green: g,
blue: b
};
var opaque_color = {
rgbColor: rgb_color
};
var solid_fill = {
color: opaque_color,
alpha: a
};
var background_fill = {
solidFill: solid_fill
};
var shape_properties = {
shapeBackgroundFill: background_fill
};
var update_request = {
objectId: shape_id,
shapeProperties: shape_properties,
fields: "shapeBackgroundFill.solidFill.color"
};
var requests = [{
updateShapeProperties: update_request
}];
// Execute the request.
var batch_update_return = Slides.Presentations.batchUpdate({
requests: requests
}, presentationId);
Logger.log(
'This is what you get from Google after submitting batchUpdate request:\n%s', batch_update_return);
}
There are already two questions about this, but the specific question remains unanswered.
I have a multipage pdf document. I have successfully used pdf.js core to write a page to a canvas. Soon I'm sure I'll have prev / next paging functions so I can see each page. See my existing code at bottom. The reason I am not using the viewer is because my boss doesn't like it. He wants a totally different interface that is extremely minimal and simple, and I have successfully built that minus the full print, ala:
Please note that there is no url to a pdf document. I get the data from a api call that returns base64 data. My code loads the data from an array into the pdf.
My current print function seems like a hack, and I know it isn't how the pdf.js viewer does it. I want to print the pdf as the pdf.js viewer does; meaning, true to form. I'm not sure if converting each page to an image gets it done, but I remain open to suggestions.
The problems are: extra margin not in the original document, and headers / footers. Not to mention pdf documents actually can contain different page layouts and sizes for each page and throwing an image tag into a new window completely ignores that.
I did check the pdf.js examples on Github. None of them are print and they say that using the pdf.js without the viewer is not supported and we are on our own if we do that (is that right?). Anyway, nothing on Google that I could find.
var pdfDocument;
var canvas;
// load from base64 data
loadPdfDocument(file.Content);
function print() {
var doc = document.getElementById('document');
var html = doc.innerHTML;
if (canvas)
html = "<img src='" + canvas.toDataURL() + "'";
var win = window.open('', '', '');
win.document.write(html);
win.document.close();
win.focus();
win.print();
win.close();
};
function loadPdfDocument(base64Data) {
PDFJS.disableWorker = true;
var pdfData = base64ToUint8Array(base64Data);
PDFJS.getDocument(pdfData).then(function(pdf) {
canvas = document.getElementById('pdfPage');
pdfDocument = pdf;
loadPdfPage(1);
});
}
function base64ToUint8Array(base64) {
var raw = atob(base64); // convert base 64 string to raw string
var uint8Array = new Uint8Array(raw.length);
for (var i = 0; i < raw.length; i++) {
uint8Array[i] = raw.charCodeAt(i);
}
return uint8Array;
}
function loadPdfPage(pageIndex) {
pdfDocument.getPage(pageIndex).then(function(page) {
var scale = 1;
var viewport = page.getViewport(scale);
var context = canvas.getContext('2d');
canvas.height = viewport.height;
canvas.width = viewport.width;
page.render({
canvasContext: context,
viewport: viewport
});
});
}
<div id="document">
<canvas id="pdfPage" />
</div>
We use Version 8.1 from ABCPDF to generate some nice PDF documents from html.
Now we discovered that printing from within Adobe Reader, will add some thin borders at the top and bottom of the page, that are not visible when the document is displayed. Also when printing to XPS, those lines are not visible.
I guess we must have missed some setting that avoids that?
At the moment we print pages like that:
using (var doc = new WebSupergoo.ABCpdf8.Doc())
{
doc.HtmlOptions.DoMarkup = false;
doc.HtmlOptions.AddLinks = false;
doc.HtmlOptions.FontEmbed = true;
doc.HtmlOptions.Engine = EngineType.Gecko;
//in case that we need to create more than 1 page, we need go get the PageId and use it
int pdfPageId = doc.AddImageHtml(html);
while (true)
{
doc.FrameRect();
if (!doc.Chainable(pdfPageId))
break;
doc.Page = doc.AddPage();
pdfPageId = doc.AddImageToChain(pdfPageId);
}
for (int i = 1; i <= doc.PageCount; i++)
{
doc.PageNumber = i;
doc.Flatten();
}
doc.Save(pathToSave);
}
I know the websupergoo guys are very friendly and reply fast.
But I think this could help other people as well, so I write it here instead of sending them an email.
Update:
I tried to get rid of the linex by changing the size of the printed document. I actually try to print for A4 Papersize. I added a line of code to change the setting for the MediaBox (the documentation suggested that this should be possible "doc.MediaBox = "A4"", but it's not directly assignable):
//set the printed area to A4
doc.MediaBox.String = "A4";
Result: The lines got thicker and can now even be seen before printing in both AdobeReader and Foxit Reader. this is not yet the solution.
Update2:
I need to set the Rect of the document as well:
//set the printed area to A4
doc.Rect.String ="A4";
doc.MediaBox.String = "A4";
Result: the lines are now drawn on the sides and can only be seen when printing. That's still not the complete solution.
Well well, copy pasting code from the web has it's dangers!
This line adds the Frame around the content:
doc.FrameRect();
all I had to do was remove it.. and no more lines are displayed.
I completely overlooked that until now.
Before I also tried the following, which didn't work as expected:
//set the width to 0, so Rectancles have no width
doc.Width = 0;
// set the color to white, so borders of Rectangles should not be black
doc.Color.String = "255 255 255"; //Edited based on the comments.
I am trying to render a string over an image chosen by user via Photochooser task. I have seen various replies to similar question but none of the replies have nailed it.
This is what I have come up with -
void photochoosertask_Completed(object sender, PhotoResult e)
{
if (e.TaskResult == TaskResult.OK)
{
System.Windows.Media.Imaging.BitmapImage bmp = new System.Windows.Media.Imaging.BitmapImage();
bmp.SetSource(e.ChosenPhoto);
image1.Source = bmp;
string steamer = "SO!";
System.Windows.Media.Imaging.WriteableBitmap bmps = new System.Windows.Media.Imaging.WriteableBitmap(bmp);
RenderString(bmps, steamer);
}
}
private void RenderString(System.Windows.Media.Imaging.WriteableBitmap bitmap, string steamer)
{
textBlock1.Text = steamer;
bitmap.Render(textBlock1 , null);
bitmap.Invalidate();
}
}
The code however doesn't work. I am most likely doing a major mistake. Any help appreciated, thanks!
According to the documentation:
If an empty transform is supplied [i.e. the null you're passing as the second parameter], the bits representing the element show up at the same offset as if they were placed within their parent.
So if I understand what's happening correctly (and I probably don't), your textBlock1 element is being rendered with the same offset as it has on your parent form. So it may be that textBlock1 is so far down from the top and left that it doesn't show up in your writeable bitmap.
BTW, I'm not familiar with WriteableBitmap, but what you're doing (putting text into a UI element and then rendering that element onto your bitmap) seems like a strange way to add text to a bitmap.
I just figured it out. Thought I should post the solution code here, might help somebody - someday :)
//setup a writeable bitmap with required dimensions
System.Windows.Media.Imaging.WriteableBitmap wbmps = new System.Windows.Media.Imaging.WriteableBitmap(x,y);
//set up a transform, we'll use ScaleTransform and we'll keep things simple here, 1x on both the axis
ScaleTransform transform = new System.Windows.Media.ScaleTransform();
transform.ScaleX=1;
transform.ScaleY=1;
//now we need to render the image on the writeablebitmap and follow it up by rendering a //string
wbmps.Render(imageelement,transform);
//Now render the string which is equivalent to TextBlock.Text
wbmps.Render(texblock,transform);
//Finally - redraw the writeablebitmap to complete the rendering
wbmps.Invalidate();