Flex 3: Timer Won't Stop - apache-flex

I'm using Flex 3 with Flash 9.
I'm trying to make a timer that will run once after 1 second. Unfortunately, me timer keeps repeating. How do I get it to stop?
public var myTimer:Timer = new Timer(1000, 1);
private function visFunc():void {
myTimer.addEventListener(TimerEvent.TIMER_COMPLETE, imageProducer);
myTimer.start();
}
private function imageProducer(event:TimerEvent):void {
var img:Image = new Image;
img.source = image_path;
img.x = 56;
img.y = (tf.y + tf.height + 40);
radioVBox.addChildAt(img, 0);
this.height = radioVBox.y + radioVBox.height +110;
myTimer.stop();
myTimer.removeEventListener(TimerEvent.TIMER_COMPLETE, imageProducer);
}
Thank you.
-Laxmidi

I'd change my code to the following and run some tests, since I don't see any major issues... HOWEVER, if you're not debugging and/or don't have a debugger version of flashplayer running, something may be blowing up on the vbox.addChild line (for example -- null vbox). If your imageProducer function is cool, then your issue is outside of the 'calling' function.
private var myTimer : Timer;
private function visFunc():void
{
if(myTimer != null)
{
tearDownTimer();
}
myTimer = new Timer(1000,1);
myTimer.addEventListener(TimerEvent.TIMER_COMPLETE, imageProducer);
myTimer.start();
}
private function tearDownTimer():void
{
if(myTimer)
{
myTimer.stop();
myTimer.removeEventListener(TimerEvent.TIMER_COMPLETE, imageProducer);
myTimer = null;
}
}
private function imageProducer(event:TimerEvent):void
{
var img:Image = new Image();
img.source = image_path;
img.x = 56;
img.y = (tf.y + tf.height + 40);
radioVBox.addChildAt(img, 0);
this.height = radioVBox.y + radioVBox.height +110;
tearDownTimer();
}

Related

Need soution for equalizer in flex?

I have developed a small application for testing 5 band equalizer in flex. I found the code in this link Flex Equalizer
The equalizer works fine.But i am not able to seek the desired position while playing the mp3 file.Following is my code....How to solve this problem?
import __AS3__.vec.Vector;
import mx.events.FlexEvent;
import spark.components.VSlider;
public static const BUFFER_SIZE:int = 8192;
public static const SAMPLE_RATE:int = 44100;
private var _Position:Number=0;
private var timer:Timer = new Timer(1000);
private const _soundURI:String = "testfile.mp3";
private var _out_snd:Sound = new Sound();
private const _eqL:EQ = new EQ();
private const _eqR:EQ = new EQ();
private var _loop_snd:Sound = new Sound();
// For storing dynamically created VSliders
private const _sliders_vect:Vector.<VSlider> = new Vector.<VSlider>();
private var _channel:SoundChannel = new SoundChannel();
private var _samples:ByteArray;
protected function view1_initializeHandler(event:FlexEvent):void
{
// TODO Auto-generated method stub
timer.addEventListener(TimerEvent.TIMER,timerFunction);
pgHolder.addEventListener(MouseEvent.CLICK,seekf);
setupEQ();
loadSound();
}
private function timerFunction(event:TimerEvent):void
{
_Position = _channel.position;
pgHolder.value=_Position;
}
private function seekf(event:MouseEvent):void
{
_channel.stop();
_Position = (pgHolder.contentMouseX/pgHolder.width)*_loop_snd.length;
startPlay();
}
private function loadSound():void
{
_Position=0;
_loop_snd.addEventListener(Event.COMPLETE, loadSoundComplete);
_loop_snd.addEventListener(IOErrorEvent.IO_ERROR, loadSoundError);
_out_snd.addEventListener(SampleDataEvent.SAMPLE_DATA, processSound);
_loop_snd.load(new URLRequest(_soundURI));
}
private function loadSoundComplete(event:Event):void
{
pgHolder.minimum=0;
pgHolder.maximum=_loop_snd.length;
timer.start();
startPlay();
}
private function startPlay():void
{
_channel=_out_snd.play(_Position);
}
private function loadSoundError(event:Event):void
{
trace("loadError");
}
// Create Sliders for changing EQ gain
private function setupEQ():void
{
var slider:VSlider;
for (var i:int = 0; i < _eqL.gains.length; i++) {
slider = new VSlider();
slider.x = (i * 35);
slider.y = 20;
slider.value = .9;
slider.maximum = 1;
slider.snapInterval=0.1;
slider.minimum = 0;
slider.addEventListener("change", changeEQHandler);
addElement(slider);
_sliders_vect[i] = slider;
}
var event:Event = new Event("change");
changeEQHandler(event);
}
private function processSound(event:SampleDataEvent):void
{
//trace("loading");
if(_Position>=_loop_snd.length)
{
_channel.stop();
}
_samples = new ByteArray();
var len:Number = _loop_snd.extract(_samples,BUFFER_SIZE);
var i:int=0;
var l:Number;
var r:Number;
if ( len < BUFFER_SIZE ) { // If end of MP3, start over
len += _loop_snd.extract(_samples,BUFFER_SIZE-len,0);
}
_samples.position = 0;
trace("len" + len + "//" + _channel.position + "//" +_samples.length);
while (i < BUFFER_SIZE) {
event.data.writeFloat(_eqL.compute(_samples.readFloat()));
event.data.writeFloat(_eqR.compute(_samples.readFloat()));
i++;
}
}
// Update EQ gains when sliders are changed
private function changeEQHandler(event:Event):void
{
var i:int = 0;
for(i = 0; i < _eqL.gains.length; i++){
_eqL.gains[i] = _sliders_vect[i].value * 2;
}
for(i = 0; i < _eqR.gains.length; i++){
_eqR.gains[i] = _sliders_vect[i].value * 2;
}
}
]]>
</fx:Script>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:HSlider width="100%" height="100%" id="pgHolder">
</s:HSlider>
When you handle the slider change, I see you calculate the new _Position, but _Position is not bindable and its never used set set the player position.
This is just pseudo-code, but shouldn't you do something like:
private function seekf(event:MouseEvent):void
{
_channel.stop();
_channel.position = (pgHolder.contentMouseX/pgHolder.width)*_loop_snd.length;
_channel.start();
}
Just looking at your code, when you set _Position = _channel.position, you are simply getting a value, not a reference. My guess is that you need to set _channel.position

How should I set up my touch controls in starling?

I am developing a game in starling that has two controls. One will be the users left thumb touching anywhere on the left side of the screen, which drags the character up and down the y axis. The other control that I am having trouble implementing is a single button in the bottom right of the screen that will make the character fire a bullet.
My question is how do I set this up without having the character jump down to the bottom of the screen whenever the button is pressed.
Will I need to mess with multi-touch in order to get this running?
A more specific question I have is how do I define a rectangle for a sprite in starling? Since starling has no drawing API, I can't just do this...
touchLayer.graphics.beginFill(0x000000, 0);
touchLayer.graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
touchLayer.graphics.endFill();
Currently my character drag is working, but the touch registers everywhere on the screen (im not sure how to make it just the left side of the screen...)
Any advise would be appreciated, thank you.
Here is the complete code for my InGame class as requested.
package screens
{
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.utils.getTimer;
import objects.Enemy;
import objects.GameBackground;
import objects.Laser;
import objects.Scarlet;
import objects.SnowBall;
import starling.display.Button;
import starling.display.Sprite;
import starling.events.Event;
import starling.events.Touch;
import starling.events.TouchEvent;
import starling.utils.RectangleUtil;
import starling.utils.deg2rad;
public class InGame extends Sprite
{
private var startBtn:Button;
private var fireBtn:Button;
private var bg:GameBackground;
private var scarlet:Scarlet;
private var enemies:Array;
private var lasers:Array;
private var scarletLocation:Point;
private var lasersLayer:Sprite;
private var enemiesLayer:Sprite;
private var touchLayer:Sprite;
private var enemySpawnDelay:Number;
private var enemySpawnCounter:Number;
private var difficulty:Number;
private var difficultyRate:Number;
private var timePrevious:Number;
private var timeCurrent:Number;
private var elapsed:Number;
private var gameState:String;
private var playerSpeed:Number;
private const MIN_SPEED:Number = 650;
//private var scoreDistance:int;
private var gameArea:Rectangle;
private var touchArea:Rectangle;
private var shape:starling.display.Sprite = new starling.display.Sprite();
private var target:Point = new Point(100, 100);
private var touch:Touch;
private var touchX:Number;
private var touchY:Number;
public function InGame()
{
super();
this.addEventListener(starling.events.Event.ADDED_TO_STAGE, onAddedToStage);
}
private function onAddedToStage(event:Event):void
{
this.removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
drawGame();
}
private function drawGame():void
{
bg = new GameBackground();
this.addChild(bg);
scarlet = new Scarlet;
scarlet.x = stage.stageWidth/2;
scarlet.y = stage.stageHeight/2;
this.addChild(scarlet);
startBtn = new Button(Assets.getTexture("PlayBtn"));
startBtn.x = stage.stageWidth * 0.5 - startBtn.width * 0.5;
startBtn.y = stage.stageHeight * 0.5 - startBtn.height * 0.5 + 35;
this.addChild(startBtn);
fireBtn = new Button(Assets.getTexture("FireBtn"));
fireBtn.x = 675;
fireBtn.y = 435;
this.addChild(fireBtn);
//defines area scarlet can fly in
gameArea = new Rectangle(0, 15, stage.stageWidth, stage.stageHeight - 150);
}
public function disposeTemporarily():void
{
this.visible = false;
}
public function initialize():void
{
this.visible = true;
this.addEventListener(Event.ENTER_FRAME, checkElapsed);
scarlet.x = -stage.stageWidth;
scarlet.y = stage.stageHeight * 0.5;
gameState = "idle";
playerSpeed = 0;
difficultyRate = 0.3;
difficulty = 1;
enemySpawnDelay = enemySpawnCounter = 100;
enemies = new Array();
lasers = new Array();
scarletLocation = new Point(200, 400);
addEventListener(Event.ENTER_FRAME, update);
lasersLayer = new Sprite();
enemiesLayer = new Sprite();
touchLayer = new Sprite();
addChild(lasersLayer);
addChild(enemiesLayer);
addChild(touchLayer);
addEventListener(Event.ADDED_TO_STAGE, setupTouchLayer);
touchLayer.addEventListener(Event.TRIGGERED, shootLaser);
//scoreDistance = 0;
startBtn.addEventListener(Event.TRIGGERED, onStartBtnClick);
this.addEventListener(TouchEvent.TOUCH, onTouch);
}
private function onStartBtnClick(event:Event):void
{
startBtn.visible = false;
startBtn.removeEventListener(Event.TRIGGERED, onStartBtnClick);
launchScarlet();
}
private function launchScarlet():void
{
this.addEventListener(TouchEvent.TOUCH, onTouch);
this.addEventListener(Event.ENTER_FRAME, onGameTick);
}
private function onTouch(event:TouchEvent):void
{
touch = event.getTouch(stage);
touchX = touch.globalX;
touchY = touch.globalY;
target.x = event.touches[0].globalX;
target.y = event.touches[0].globalY;
}
private function onGameTick(event:Event):void
{
switch(gameState)
{
case"idle":
//Take off
if (scarlet.x < stage.stageWidth * 0.5 * 0.5)
{
scarlet.x += ((stage.stageWidth * 0.5 * 0.5 + 10) - scarlet.x) * 0.5;
scarlet.y = stage.stageHeight * 0.5;
playerSpeed += (MIN_SPEED - playerSpeed) * 0.05;
}
else
{
gameState = "flying";
}
break;
case"flying":
playerSpeed -= (playerSpeed - MIN_SPEED) * 0.01;
scarlet.y -= (scarlet.y - touchY) * 0.1;
if (-(scarlet.y - touchY) < 150 && -(scarlet.y - touchY) > -150)
{
scarlet.rotation = deg2rad(-(scarlet.y - touchY) * 0.075);
}
if (scarlet.y > gameArea.bottom - scarlet.height * 0.5)
{
scarlet.y = gameArea.bottom - scarlet.height * 0.5;
scarlet.rotation = deg2rad(0);
}
if (scarlet.y < gameArea.top + scarlet.height * 0.5)
{
scarlet.y = gameArea.top + scarlet.height * 0.5;
scarlet.rotation = deg2rad(0);
}
//scoreDistance += (playerSpeed * elapsed) * 0.1;
//trace(scoreDistance);
break;
case"over":
break;
}
}
//addapted from "Shoot"
private function setupTouchLayer(event:Event):void
{
touchLayer.graphics.beginFill(0x000000, 0);
touchLayer.graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
touchLayer.graphics.endFill();
touchArea = new Rectangle(0, 0, stage.stageWidth, stage.stageHeight);
}
private function shootLaser(event:TouchEvent):void
{
makeLaser(scarletLocation);
}
private function makeLaser(scarletLocation:Point):void
{
var newLaser:Laser = new Laser();
newLaser.x = scarletLocation.x;
newLaser.y = scarletLocation.y;
newLaser.xVel = 5;
newLaser.yVel = 5;
newLaser.addEventListener(Laser.PURGE_EVENT, purgeLaserHandler);
lasersLayer.addChild(newLaser);
lasers.push(newLaser);
}
private function purgeLaserHandler(event:Event):void
{
var targetLaser:Laser = Laser(event.target);
purgeLaser(targetLaser);
}
private function purgeLaser(targetLaser:Laser):void
{
targetLaser.removeEventListener(Laser.PURGE_EVENT, purgeLaserHandler);
try
{
var i:int;
for (i = 0; i < lasers.length; i++)
{
if (lasers[i].name == targetLaser.name)
{
lasers.splice(i, 1);
lasersLayer.removeChild(targetLaser);
i = lasers.length;
}
}
}
catch(e:Error)
{
trace("Failed to delete laser!", e);
}
}
private function makeEnemies():void
{
enemySpawnCounter++;
if (enemySpawnCounter > enemySpawnDelay)
{
enemySpawnCounter = 0;
enemySpawnDelay -= difficultyRate;
difficulty += difficultyRate;
makeEnemy();
}
}
private function makeEnemy():void
{
var i:int;
for (i = 0; i < Math.floor(difficulty); i++)
{
var newEnemy:Enemy = new SnowBall();
newEnemy.x = 925;
newEnemy.y = Math.random() * 375 + 50;
//trace(newEnemy.x); trace(newEnemy.y);
newEnemy.xVel = (-Math.random() * difficulty) - 5;
newEnemy.sinMeter = Math.random() * 10;
newEnemy.bobValue = Math.random() * difficulty;
newEnemy.addEventListener(Enemy.PURGE_EVENT, purgeEnemyHandler);
enemiesLayer.addChild(newEnemy);
enemies.push(newEnemy);
}
}
private function purgeEnemyHandler(event:Event):void
{
var targetEnemy:Enemy = Enemy(event.target);
purgeEnemy(targetEnemy);
}
private function purgeEnemy(targetEnemy:Enemy):void
{
targetEnemy.removeEventListener(Enemy.PURGE_EVENT, purgeLaserHandler);
try
{
var i:int;
for (i = 0; i < enemies.length; i++)
{
if (enemies[i].name == targetEnemy.name)
{
enemies.splice(i, 1);
enemiesLayer.removeChild(targetEnemy);
i = enemies.length;
}
}
}
catch(e:Error)
{
trace("Failed to delete enemy!", e);
}
}
private function newHitTest(laser:Laser):void
{
for each (var enemy:Enemy in enemies)
{
if (enemy.status != "Dead" && enemy.hitTest(new Point(laser.x, laser.y)))
{
enemy.destroy();
purgeLaser(laser);
}
}
}
private function checkElapsed(event:Event):void
{
timePrevious = timeCurrent;
timeCurrent = getTimer();
elapsed = (timeCurrent - timePrevious) * 0.001;
}
private function update():void
{
//trace(enemies.length, lasers.length);
for each (var enemy:Enemy in enemies)
{
enemy.update();
}
for each (var laser:Laser in lasers)
{
laser.update();
newHitTest(laser);
}
makeEnemies();
}
//addapted from "Shoot"
}
}
Oh wow, well a very simple way to solve this problem is to simply enable multi-touch.
Starling.multitouchEnabled = true;
However this still leaves the problem of my character jumping to the bottom of the screen when I press the button in the bottom right IF I am not touching the screen already to control the character... not really a big deal but it would look better if this didn't happen.

Selenium webdriver C# - Taking full page screenshot

Can anyone help me to take a full page screenshot using Selenium webdriver. I am using c#/Nunit. The current method i am using is not taking the full browser page.
I am using the code below to take the screenshot.
public void TakeScreenShot(IWebDriver webDriver,string testName,string className)
{
string folderName = String.Format("{0}.{1}", className, testName);
// Create Screenshot folder
string createdFolderLocation = CreateFolder(folderName);
// Take the screenshot
Screenshot ss = ((ITakesScreenshot)webDriver).GetScreenshot();
string screenshot = ss.AsBase64EncodedString;
byte[] screenshotAsByteArray = ss.AsByteArray;
// Save the screenshot
ss.SaveAsFile((string.Format("{0}\\{1}",createdFolderLocation,testName + ".Jpeg")), System.Drawing.Imaging.ImageFormat.Jpeg);
ss.ToString();
}
You can use this package https://www.nuget.org/packages/Noksa.WebDriver.ScreenshotsExtensions/
In order to take a screenshot of the entire page, use the VerticalCombineDecorator:
var vcs = new VerticalCombineDecorator(new ScreenshotMaker());
var screen = _driver.TakeScreenshot(vcs);
"Full-page" screenshots are defined by WebDriver to include the entirety of the page displayed in the browser, not the browser chrome (URL bar, toolbar, window resizing handles, and so on). If you don't care about getting the full DOM in your screenshot, you don't need to use WebDriver to get your screenshot. You can use the API of your operating system to handle that instead.
This one I used in our solution:
public byte[] TakeScreenshot()
{
try
{
var getMaxSide = "return Math.max(document.body.scroll{0}, document.body.offset{0}, document.documentElement.client{0}, document.documentElement.scroll{0}, document.documentElement.offset{0})";
var scrollHeight = (Driver as IJavaScriptExecutor).ExecuteScript(string.Format(getMaxSide, "Height"));
var scrollWidth = (Driver as IJavaScriptExecutor).ExecuteScript(string.Format(getMaxSide, "Width"));
Driver.Manage().Window.Size = new Size(int.Parse(scrollWidth.ToString()), int.Parse(scrollHeight.ToString()));
return (Driver as ITakesScreenshot).GetScreenshot().AsByteArray;
}
catch
{
return Array.Empty<byte>();
}
}
Then you can use the result to attach it to e.g. Allure or NUnit test results:
private void AttachScreenshot()
{
var screenshot = _browser?.TakeScreenshot();
if (screenshot.Length > 0)
{
// add screenshot to test results
var path = DateTime.Now.Ticks.ToString() + ".png";
File.WriteAllBytes(path, screenshot);
TestContext.AddTestAttachment(path, "screenshot");
// attach screenshot to Allure report
AllureLifecycle.Instance.AddAttachment("screenshot", "image/png", screenshot);
}
}
Try changing the size of the browser window to something huge before taking your screen shot. I have the size to 10 less than the width, and 10 less than the height. Try adding rather than subtracting.
driver = new FirefoxDriver(firefoxProfile);
if (Config.MAXIMIZE_BROWSER_WINDOW)
{
driver.Manage().Window.Size = new System.Drawing.Size(System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Width - 10, System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Height - 10);
}
you may try this
IWebDriver driver = new PhantomJSDriver();
driver.Navigate().GoToUrl("http://www.google.com");
((ITakesScreenshot)driver).GetScreenshot().SaveAsFile("image.png", ImageFormat.Png);
Greetings from 2017))!
If the page size is larger than the screen size - you can use the PhantomJS driver (PhantomJS download page)
var fileName = "test.png";
var size = new Size(800, 2000);
var url = "https://stackoverflow.com/";
using (var driver = new PhantomJSDriver())
{
driver.Manage().Window.Size = size;
driver.Navigate().GoToUrl(url);
((ITakesScreenshot)driver)
.GetScreenshot()
.SaveAsFile(fileName, ImageFormat.Png);
driver.Close();
}
I remeber that ((ITakesScreenshot)webDriver).GetScreenshot(); takes full page screenshot but if you have some ajax request and other loading elements you can add scrolling and at the end to wait some seconds, after that you will know that it took full loaded page screenshot.
for (int second = 0;; second++)
{
if (second >= 4)
{
break;
}
((IJavaScriptExecutor)Global.Driver).ExecuteScript("window.scrollBy(0,800)", string.Empty);
Thread.Sleep(500);
}
Thread.Sleep(3000);
Try this hope it will work fine for u.
public void TakeScreenshot(string SSName)
{
try
{
string path = "D:\\WorkSpace\\Screenshot\\";
Screenshot ss = ((ITakesScreenshot)driver).GetScreenshot();
ss.SaveAsFile((path + SSName), System.Drawing.Imaging.ImageFormat.Jpeg);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
throw;
}
}
Changing browser height doesn't always work. This is the solution I used. It scrolls through the page and composes the full-page screenshot.
public static Image TakeFullPageScreenshot(this RemoteWebDriver driver, int maxHeight = 10000)
{
Bitmap fullPageScreenshot = null;
using (var fullMs = new MemoryStream((driver.GetScreenshot()).AsByteArray)) {
fullPageScreenshot = Image.FromStream(fullMs) as Bitmap;
}
var originalPageOffset = driver.GetPageOffset();
var prevPageOffset = 0;
var currentPageOffset = 0;
var scrollLength = (int)(driver.Manage().Window.Size.Height / 1.5);
while (fullPageScreenshot.Height < maxHeight)
{
prevPageOffset = driver.GetPageOffset().Y;
driver.ScrollPageBy(0, scrollLength);
System.Threading.Thread.Sleep(500);
currentPageOffset = driver.GetPageOffset().Y;
if (prevPageOffset == currentPageOffset)
{
break;
}
var pageMovedBy = currentPageOffset - prevPageOffset;
using (var ms = new MemoryStream(driver.GetScreenshot().AsByteArray))
{
using (var viewPortScreenshot = Image.FromStream(ms) as Bitmap)
{
var croppedScreenshot = CropBitmapAtRect(viewPortScreenshot, new Rectangle(0, viewPortScreenshot.Height - pageMovedBy, viewPortScreenshot.Width, pageMovedBy));
var newFullPage = AppendBitmap(fullPageScreenshot, croppedScreenshot);
fullPageScreenshot.Dispose();
fullPageScreenshot = newFullPage;
}
}
}
driver.ScrollPageTo(originalPageOffset.X, originalPageOffset.Y);
return fullPageScreenshot;
}
public static Bitmap CropBitmapAtRect(Bitmap b, Rectangle r)
{
Bitmap nb = new Bitmap(r.Width, r.Height);
using (Graphics g = Graphics.FromImage(nb))
{
g.DrawImage(b, -r.X, -r.Y);
return nb;
}
}
public static Bitmap AppendBitmap(Bitmap source, Bitmap target, int spacing = 0)
{
int w = Math.Max(source.Width, target.Width);
int h = source.Height + target.Height + spacing;
Bitmap bmp = new Bitmap(w, h);
using (Graphics g = Graphics.FromImage(bmp))
{
g.DrawImage(source, 0, 0);
g.DrawImage(target, 0, source.Height + spacing);
}
return bmp;
}
public static void ScrollPageBy(this RemoteWebDriver driver, int x = 0, int y = 0)
{
driver.ExecuteScript(#"window.scroll(window.pageXOffset + arguments[0], window.pageYOffset + arguments[1]);", x, y);
}
public static void ScrollPageTo(this RemoteWebDriver driver, int x = 0, int y = 0)
{
driver.ExecuteScript(#"window.scroll(arguments[0], arguments[1]);", x, y);
}
public static Point GetPageOffset(this RemoteWebDriver driver)
{
var offsetArray = driver.ExecuteScript(#"return [window.pageXOffset, window.pageYOffset];") as ReadOnlyCollection<object>;
var x = (long)offsetArray[0];
var y = (long)offsetArray[1];
return new Point((int)x, (int)y);
}
based on the answer from #Michal Kalous I created an etension class.
This also takes into account the font size currently set in widows and the real viewport size and removes the vertical scrollbar by setting body.style.overflowY to hidden.
Usage
RemoteWebDriver driver = new EdgeDriver();
driver.SetViewportSize(1200, 1200);
driver.Navigate().GoToUrl("https://www.bikereview.info/en/ktm-1290-super-duke-rr-innerhalb-von-48-minuten-ausverkauft.html");
Image tempImage = driver.TakeFullPageScreenshot();
tempImage.Save(#"c:\full.png", ImageFormat.Png);
driver.Close();
driver.Quit();
Extension-Class
using System;
using System.Drawing;
using System.IO;
using OpenQA.Selenium.Remote;
using System.Collections.ObjectModel;
using System.Runtime.InteropServices;
using OpenQA.Selenium;
namespace TestRenderHtmlToPng
{
public static class RemoteWebDriverExtensions
{
public static Image TakeFullPageScreenshot(this RemoteWebDriver driver, int maxHeight = 10000)
{
//Screenshots depend on fontscaleing-property in windows
double DpiScalingFactor = GetDpiScalingFactor();
Bitmap fullPageScreenshot = null;
using (var fullMs = new MemoryStream((driver.GetScreenshotOverflowHidden()).AsByteArray))
{
fullPageScreenshot = Image.FromStream(fullMs) as Bitmap;
}
var originalPageOffset = driver.GetPageOffset();
var prevPageOffset = 0;
var currentPageOffset = 0;
var scrollLength = driver.GetWindowInnerHeight();
while (fullPageScreenshot.Height < maxHeight)
{
prevPageOffset = driver.GetPageOffset().Y;
driver.ScrollPageBy(0, scrollLength);
System.Threading.Thread.Sleep(100);
currentPageOffset = driver.GetPageOffset().Y;
if (prevPageOffset == currentPageOffset)
{
break;
}
var pageMovedBy = currentPageOffset - prevPageOffset;
pageMovedBy = (int)(pageMovedBy * DpiScalingFactor);
using (var ms = new MemoryStream(driver.GetScreenshotOverflowHidden().AsByteArray))
{
Bitmap fullPageScreenshot1 = Image.FromStream(ms) as Bitmap;
using (var viewPortScreenshot = Image.FromStream(ms) as Bitmap)
{
var s = driver.Manage().Window.Size;
var croppedScreenshot = CropBitmapAtRect(viewPortScreenshot, new Rectangle(0, viewPortScreenshot.Height - pageMovedBy, viewPortScreenshot.Width, pageMovedBy));
var newFullPage = AppendBitmap(fullPageScreenshot, croppedScreenshot);
fullPageScreenshot.Dispose();
fullPageScreenshot = newFullPage;
}
}
}
driver.ScrollPageTo(originalPageOffset.X, originalPageOffset.Y);
return fullPageScreenshot;
}
private static Bitmap CropBitmapAtRect(Bitmap b, Rectangle r)
{
Bitmap nb = new Bitmap(r.Width, r.Height);
using (Graphics g = Graphics.FromImage(nb))
{
g.DrawImage(b, -r.X, -r.Y);
return nb;
}
}
private static Bitmap AppendBitmap(Bitmap source, Bitmap target, int spacing = 0)
{
int w = Math.Max(source.Width, target.Width);
int h = source.Height + target.Height + spacing;
Bitmap bmp = new Bitmap(w, h);
using (Graphics g = Graphics.FromImage(bmp))
{
g.DrawImage(source, 0, 0);
g.DrawImage(target, 0, source.Height + spacing);
}
return bmp;
}
private static Screenshot GetScreenshotOverflowHidden(this RemoteWebDriver driver)
{
driver.ExecuteScript(#" document.body.style.overflowY = ""hidden"";");
var s = driver.GetScreenshot();
driver.ExecuteScript(#" document.body.style.overflowY = """";");
return s;
}
private static void ScrollPageBy(this RemoteWebDriver driver, int x = 0, int y = 0)
{
driver.ExecuteScript(#"window.scroll(window.pageXOffset + arguments[0], window.pageYOffset + arguments[1]);", x, y);
}
private static void ScrollPageTo(this RemoteWebDriver driver, int x = 0, int y = 0)
{
driver.ExecuteScript(#"window.scroll(arguments[0], arguments[1]);", x, y);
}
public static void SetViewportSize(this RemoteWebDriver driver, int width, int height)
{
var jsGetPadding = #"return [ window.outerWidth - window.innerWidth,window.outerHeight - window.innerHeight ];";
var paddingArray = driver.ExecuteScript(jsGetPadding) as ReadOnlyCollection<object>;
driver.Manage().Window.Size = new Size(width + int.Parse(paddingArray[0].ToString()), height + int.Parse(paddingArray[1].ToString()));
}
private static Point GetPageOffset(this RemoteWebDriver driver)
{
var offsetArray = driver.ExecuteScript(#"return [window.pageXOffset, window.pageYOffset];") as ReadOnlyCollection<object>;
var x = int.Parse(offsetArray[0].ToString());
var y = int.Parse(offsetArray[1].ToString().Split(',')[0]);
return new Point((int)x, (int)y);
}
private static int GetWindowInnerHeight(this RemoteWebDriver driver)
{
var Value = driver.ExecuteScript(#"return [window.innerHeight];") as ReadOnlyCollection<object>;
return int.Parse(Value[0].ToString());
}
[DllImport("gdi32.dll")]
private static extern int GetDeviceCaps(IntPtr hdc, int nIndex);
public enum DeviceCap
{
VERTRES = 10,
DESKTOPVERTRES = 117,
// http://pinvoke.net/default.aspx/gdi32/GetDeviceCaps.html
// https://stackoverflow.com/questions/5977445/how-to-get-windows-display-settings#answer-21450169
}
private static float GetDpiScalingFactor()
{
Graphics g = Graphics.FromHwnd(IntPtr.Zero);
IntPtr desktop = g.GetHdc();
int LogicalScreenHeight = GetDeviceCaps(desktop, (int)DeviceCap.VERTRES);
int PhysicalScreenHeight = GetDeviceCaps(desktop, (int)DeviceCap.DESKTOPVERTRES);
float ScreenScalingFactor = (float)PhysicalScreenHeight / (float)LogicalScreenHeight;
return ScreenScalingFactor; // 1.25 = 125%
}
}
}

Creating a parallax on a tiling background

I am using the blitting technique that Jeff from 8bitrocket.com uses for creating tiles. I am trying to paint 2 layers of bitmapdata onto a bitmap. One the first layer is the background ( 1 image). and the second layer is the tiles. In that class below. the updateMap is the method that gets called in the loop to repaint the image.
package com.eapi
{
/**
* ...
* #author Anthony Gordon
*/
import com.objects.XmlManager;
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.*;
import flash.display.BitmapData;
import flash.display.Bitmap
import flash.geom.Rectangle;
import flash.geom.Point;
import flash.display.DisplayObject;
public class EngineApi extends MovieClip
{
public var images:Array;
public var world:Array;
//w stands for world, how big it is in columns and rows
private var wCols:Number = 50;
private var wRows:Number = 16;
public var wWidth:Number;
public var wHeight:Number;
//v stands for view, which means your field of view
public var vRows:Number;
public var vCols:Number;
public var vWidth:Number = 540;
public var vHeight:Number = 360;
//how big your indivual tile is
public var tileW:Number = 80;
public var tileH:Number = 80;
public var offsX:Number = 0;
public var offsY:Number = 0;
public var xEnd:Number = 0;
public var yEnd:Number = 0;
public var tilex:int;
public var tiley:int;
public var scrollx:Number = 0;
public var scrolly:Number = 0;
private var screen:Bitmap;
private var canvas:BitmapData;
private var buffer:BitmapData;
public var mapHolder:Array;
private var scrollLoop:Boolean;
private var minLoop:Number;
private var maxLoop:Number;
public var currentMap:Number = 0;
private var queue:Array;
public var currentCol:Number = 0;
public var currentRow:Number = 0;
public var enviroment:Array;
public var currentTileSheet:Number = 0;
private var layer1:Sprite;
private var layer2:Sprite;
private var layer3:Sprite;
private var layer4:Sprite;
private var layer5:Sprite;
public var background:BitmapData
protected var stageObject:Array;
protected var gameObjects:Array;
public function EngineApi(w:Number = 540,h:Number = 360, tw:Number = 50, th:Number = 50)
{
stageObject = new Array();
gameObjects = new Array();
//Add Layers
layer1 = new Sprite();
layer2 = new Sprite();
layer3 = new Sprite();
layer4 = new Sprite();
layer5 = new Sprite();
//end
images = new Array();
vWidth = w;
vHeight = h;
tileW = tw;
tileH = th;
queue = new Array();
mapHolder = new Array();
vCols = Math.floor(vWidth/tileW);
vRows = Math.floor(vHeight/tileH);
wWidth = wCols * tileW;
wHeight = wRows * tileH;
canvas = new BitmapData(vWidth,vHeight,true,0x000000);
buffer = new BitmapData(vWidth + 2 * tileW, vHeight + 2 * tileH ,false,0x000000);
screen = new Bitmap(canvas);
addChild(screen);
addChild(layer1);
addChild(layer2);
addChild(layer3);
addChild(layer4);
addChild(layer5);
}
public function addGameChild(object:IGameObject, layer:Number):void
{
switch(layer)
{
case 1:
layer1.addChild(DisplayObject(object));
break;
case 2:
layer2.addChild(DisplayObject(object));
break;
case 3:
layer3.addChild(DisplayObject(object));
break;
case 4:
layer4.addChild(DisplayObject(object));
break;
case 5:
layer5.addChild(DisplayObject(object));
break;
default:
}
if (object.IsDisplay == true)
gameObjects.push(object);
stageObject.push(object);
}
public function UpDateMap():void
{
offsX += scrollx;
offsY += scrolly;
tilex = int(offsX/tileW);
tiley = int(offsY/tileH);
xEnd = tilex + vWidth;
yEnd = tiley + vHeight;
var tileNum:int;
var tilePoint:Point = new Point(0,0);
var tileRect:Rectangle = new Rectangle(0, 0, tileW, tileH);
var rowCtr:int=0;
var colCtr:int=0;
for (rowCtr=0; rowCtr <= vRows; rowCtr++) {
for (colCtr = 0; colCtr <= vCols; colCtr++) {
currentCol = colCtr+tilex;
currentRow = rowCtr+tiley;
tileNum = mapHolder[currentMap][rowCtr+tiley][colCtr+tilex];
tilePoint.x = colCtr * tileW;
tilePoint.y = rowCtr * tileH;
tileRect.x = int((tileNum % 100))* tileW;
tileRect.y = int((tileNum / 100))* tileH;
buffer.copyPixels(images[currentTileSheet],tileRect,tilePoint);
}
}//End Loop
var bgRect:Rectangle = new Rectangle(0, 0, 544, 510);
var bgPoint:Point = new Point(0, 0);
var bufferRect:Rectangle = new Rectangle(0,0,vWidth,vHeight);
var bufferPoint:Point = new Point();
bufferRect.x = offsX % tileW;
bufferRect.y = offsY % tileH;
canvas.copyPixels(background,bgRect,bgPoint);
canvas.copyPixels(buffer,bufferRect,bufferPoint);
}//End UpdateMap
public function StartRender():void
{
addEventListener(Event.ENTER_FRAME, loop);
}
protected function loop(e:Event):void
{
UpDateMap();
UpdateObjects();
}
protected function UpdateObjects():void
{
for (var i:Number = 0; i < stageObject.length; i++)
{
stageObject[i].UpdateObject();
}
for (var g:Number = 0; g < stageObject.length; g++)
{
if (stageObject[g].Garbage && stageObject[g].IsDisplay)
{
removeChild(DisplayObject(stageObject[g]));
stageObject[g] = null;
}
else if (stageObject[g].Garbage == true && stageObject[g].IsDisplay == false)
{
stageObject[g] = null;
}
}
}
public function StopRender():void
{
removeEventListener(Event.ENTER_FRAME, loop);
}
}
}
It's not the complete code, but if I remove canvas.copyPixels(background,bgRect,bgPoint); or canvas.copyPixels(buffer,bufferRect,bufferPoint); I can see either or. If I paint them both then I can only see the one that painted last. My tile image is 128 x 32. 0 - 3. array 3 is transparent image. I used that hoping that I could see through the image and see the background. I was wrong.
At first it was an all black background, but then I changed the transparent constructor to true on the buffer variable. Now it shows a white background (like the stage), but still no background image.
I'm not sure I completely understand the example, but it looks like the issue is that you're using copyPixels--this should replace the old pixels in the canvas bmp with new values.
Try using draw for the foreground instead:
canvas.copyPixels(background, bgRect, bgPoint);
canvas.draw(buffer, transform, null, null, clipRect);
Also, I'm not sure why you're drawing the background image to a different rect than the foreground? There may be something there.
I took a seperate movieclip and used it as a parallax behind the blitting tiles.

as3: reloading an image

I have an image that I am attempting to load, and then reload. Here is my code for the loading of the image:
public function loadImage(url:String, _w:int, _h:int):void
{
this._stwidth = _w;
this._stheight = _h;
this._imageURL = url;
if(!_imageURL)
{
return;
}
this.alpha = 1.0; //need this because we might have just faded the image out
_ldr.alpha = 0.0;
_prog.alpha = 1.0;
_sqr.alpha = 0.0;
_sqr.graphics.clear();
if(_hasLoaded)
{
try
{
_ldr.close();
_ldr.unload();
}
catch(e:Error)
{
//trace("bmdisplay has loaded once, but there was an error: " + e.message);
}
}
_ldr.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, onProgress);
_ldr.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
_ldr.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onError);
_ldr.contentLoaderInfo.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onError);
_ldr.contentLoaderInfo.addEventListener(Event.INIT, onOpen);
_ldr.load(new URLRequest(_imageURL));
}
For some reason, this code will not load the image without issuing an Error upon the 2nd load.
Can someone please help me figure this out?
I am totally lost on why my variable _asLoaded would do me wrong.
I have an onComplete() handler, which sets that var to true, and I never set it to false after that.
I don't know what else I should be trying...
Thanks
Sometimes back I wrote a helper class to achieve something similar. The helper class extends Loader and provides automatic scaling of image. Here is the code for that class:package {
import flash.display.Loader;
import flash.geom.Rectangle;
import flash.net.URLRequest;
import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.events.SecurityErrorEvent;
public class ImageLoader extends Loader {
private var _imageURL:String; // URL of image
private var _imageBoundary:Rectangle; // boundary rectangle for the image
private var _loaded:Boolean; // flag which tells whether image is loaded or not.
private var _isLoading:Boolean; // flag which say if any loading is in progress
//Constructor function, which calls Loader's constructor
// and loads and resize the image
public function ImageLoader(url:String = null, rect:Rectangle = null):void {
super();
_imageURL = url;
_imageBoundary = rect;
_loaded = false;
_isLoading = false;
loadImage();
}
// sets the image for the loader and loads it
public function set imageURL(url:String):void {
_imageURL = url;
loadImage();
}
// sets the boundary of the image and resizes it
public function set boundary(rect:Rectangle):void {
_imageBoundary = rect;
resizeImage();
}
private function removeListeners():void {
this.contentLoaderInfo.removeEventListener(Event.COMPLETE, onComplete);
this.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR, onError);
this.contentLoaderInfo.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, onError);
}
private function onComplete(e:Event):void {
_loaded = true;
_isLoading = false;
removeListeners();
resizeImage();
}
//In case of error, we are not propogating the event
private function onError(e:Event):void {
e.stopImmediatePropagation();
removeListeners();
}
// real loading goes here
// it first closes and unloads the loader and
// then loads the image
private function loadImage():void {
if (_isLoading) {
trace("Some loading is in progess");
return;
}
try {
this.close();
this.unload();
}
catch(e:Error) {
//discarded
}
if (!_imageURL)
return;
_loaded = false;
_isLoading = true;
this.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
this.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onError);
this.contentLoaderInfo.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onError);
this.load(new URLRequest(_imageURL));
}
// standard resizing function for image so that it's
// aspect ratio is maintained.
private function resizeImage():void {
if (!_imageBoundary || !_loaded)
return;
var aspect:Number = width / height;
var cAspect:Number = _imageBoundary.width / _imageBoundary.height;
if (aspect <= cAspect) {
this.height = _imageBoundary.height;
this.width = aspect * this.height;
}
else {
this.width = _imageBoundary.width;
this.height = this.width / aspect;
}
this.x = (_imageBoundary.width-this.width)/2 + _imageBoundary.x;
this.y = (_imageBoundary.height-this.height)/2 + _imageBoundary.y;
}
}
} And you can use it like this:var _imageLoader:ImageLoader = new ImageLoader();
_imageLoader.imageURL = "http://some-image-url";
_imageLoader.boundary = new Rectangle(0, 0, stage.stageWidth, stage.stageHeight); // or whatever suits you
ImageLoader extends Loader class so you can listen to all the Events dispatches by Loader class. Hope it helps.
i would declare _ldr inside the function so its dead every time you start this function. and i also would not use this unload() and close() methods. its much simpler if make some thing like this (you need to have a empty movieclip called "ldrHelper"):
public function loadImage(url:String, _w:int, _h:int):void
{
// do your job and die bravely, no need to be global
var _ldr:Loader = new Loader();
this._stwidth = _w;
this._stheight = _h;
this._imageURL = url;
if(!_imageURL)
{
return;
}
this.alpha = 1.0; //need this because we might have just faded the image out
// now you will need to make alpha = 1 on ldrHolder since _ldr is dead after this function
ldrHolder.alpha = 0.0;
_prog.alpha = 1.0;
_sqr.alpha = 0.0;
_sqr.graphics.clear();
// remove the old image, doesn't matter whether its empty or not
while(ldrHolder.numChildren > 0){
ldrHolder.removeChildAt(0);
}
//add image
ldrHolder.addChild(_ldr);
_ldr.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, onProgress);
_ldr.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
_ldr.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onError);
_ldr.contentLoaderInfo.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onError);
_ldr.contentLoaderInfo.addEventListener(Event.INIT, onOpen);
_ldr.load(new URLRequest(_imageURL));
}
Try instantiating new Loader, probably trying to recycle it is giving you the problem

Resources