Jump to content

Mad_Griffith

Members
  • Posts

    146
  • Joined

  • Last visited

Everything posted by Mad_Griffith

  1. I agree. But I don't manage to proceed any further because I am inexperienced with PHP and AJAX requests and I wouldn't know how to build or debug this...
  2. This I understand. But I am having lots of problems with Twitter's auth popup so I decided to kill the session everytime...
  3. As far as I understand, initiating a session allows me to pass variables coming from an AJAX request easily between files.
  4. Ok thanks, so I moved them at the end of the else block. This is what I have so far and it works only if I unset the variables/destroy the session every time. my page 1 session_start() if(whatever) { $_SESSION['myData'] = $_POST['MyData']; session_write_close() echo $url; // I get this response in AJAX and I open it in a popup back through the "then" method of a JS promise } else { // Do something with $_SESSION['myData'] session_unset(); session_destroy(); } twitter auth page once logged in and accepted the app, goes to page 2 my page 2 session_start() // some other stuff happens, but $_SESSION['myData'] does need to be manipulated on this page header( go back to page 1, evaluates the else block)
  5. Ok, thanks! I have the additional problem that the data is coming from an AJAX request and there's Twitter involved. This is what I am currently doing (and it is not working): my page 1 session_start() if(whatever) { $_SESSION['myData'] = $_POST['MyData']; session_write_close() echo $url; // I get this response in AJAX and I open it in a popup back through the "then" method of a JS promise } else { // Do something with $_SESSION['myData'] } twitter auth page once logged in and accepted the app, goes to page 2 my page 2 session_start() // some other stuff happens, but $_SESSION['myData'] does need to be manipulated on this page session_unset(); session_destroy(); header( go back to page 1, evaluates the else block)
  6. Hi, I have the following problem in PHP and I wouldn't know how to do it... could you help me out? Thanks! page 1 if(x is not set) { go to page 2 } else { access variable x's content and do something with it } page 2 x = something go back to page 1
  7. for example this attempt at building the AJAX call doesn't work consistently... $('#twitter').click(function() { canvasToData(); $.ajax({ url: 'tweet-with-media.php', type: 'POST', data: formData, processData: false, contentType: false, cache: false, beforeSend: function() { $('#twitter').addClass('twitter-beforesend'); }, success: function(data) { console.log(data) if (data.indexOf('https://api.twitter.com/oauth') > -1) { window.open(data); // authorisation URL $.ajax({ url: 'tweet-with-media.php', type: 'POST', data: formData, processData: false, contentType: false, cache: false }) } }, complete: function() { $('#twitter').removeClass('twitter-beforesend'); $('#twitter').addClass('twitter-success'); setTimeout( function() { $('#twitter').removeClass('twitter-success'); }, 3000); } }); }); In fact I receive this error: <b>Notice</b>: Undefined variable: request_token in <b>tweet-with-media.php</b> on line <b>31</b><br /> <br /> <b>Notice</b>: Undefined property: stdClass::$media_id in <b>tweet-with-media.php</b> on line <b>45</b><br /> stdClass Object ( [errors] => Array ( [0] => stdClass Object ( [code] => 89 [message] => Invalid or expired token. ) ) )
  8. I found out I have to use file_get_contents and now I actually see the picture saved. The problem now is I don't know when to open the popup to ask for user's authorisation. Do I have to open it through JS? If so, on "success" or "beforeSend"? Or should this happen in the tweet-with-image.php file? Also, do I have too many files? I have the index.html (where the user's interaction with the button is supposed to happen), then this tweet-with-image.php file and the callback.php file. I would be grateful if you could make me understand how to handle this final part... Thank you, I feel I am close!
  9. I am not sure I understand the flow correctly, though: I post the blob appended to the form, from main.js (referenced in the index page) to tweet-with-media.php. The tweet-with-media.php starts the session and checks whether the access token was retrieved. If it was not received, it opens up a popup to callback.php where the access token is retrieved and stored in the session. If the access token was already retrieved, it first saves the formData on the disk, then posts it to Twitter with a status, then deletes the picture from the disk. I am not sure if it's okay what I am doing: splitting the process in 3 files and when should the popup be opened to have the user authorise the app. I had header('Location:' . $url); which I replaced with echo '<script>window.open("' . $url . '")</script>'; but the link is not opening in a new window. The response is: <script>window.open("https://api.twitter.com/oauth/authorize?oauth_token=KbJJbAAAAAAAvciIAAABVRx51JM")</script>
  10. Thanks... I had them at the top of tweet-with-media.php already...
  11. Thank you. The response is empty, this is the request: -----------------------------14391895511350467496552540129 Content-Disposition: form-data; name="canvasToData"; filename="blob" Content-Type: image/jpeg ÿØÿàJFIFÿÛC ÿÛC ÿÀ°ÿÄ ÿĵ}!1AQa"q2¡#B±ÁRÑð$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖ×ØÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖ×ØÙÚâãäåæçèéêòóôõö÷øùúÿÚ?ùj¿?Ò ( ( ...
  12. Capitalization is correct... still receive "Notice: Undefined index" :/
  13. $_FILES['CanvasToTwitter'] does nothing
  14. Here I thought I appended 'canvasToTwitter' to the formData... $('#twitter').click(function() { canvasToData(); $.ajax({ url: 'tweet-with-media.php', type: 'POST', data: formData, processData: false, contentType: false, cache: false, beforeSend: function() { $('#twitter').addClass('twitter-beforesend'); }, success: function(data) { window.open('tweet-with-media.php'); }, complete: function() { $('#twitter').removeClass('twitter-beforesend'); $('#twitter').addClass('twitter-success'); setTimeout( function() { $('#twitter').removeClass('twitter-success'); }, 3000); } }); }); function canvasToData() { var canvasDataUrl = canvas.toDataURL("image/jpeg"), canvasBlob = dataURItoBlob(canvasDataUrl); formData = new FormData(); formData.append("canvasToTwitter", canvasBlob); } function dataURItoBlob(dataURI) { var byteString = atob(dataURI.split(',')[1]), mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0], ab = new ArrayBuffer(byteString.length), ia = new Uint8Array(ab); for (var i = 0; i < byteString.length; i++) { ia[i] = byteString.charCodeAt(i); } var bb = new Blob([ab], { "type": mimeString }); return bb; } And this is the payload request: ------WebKitFormBoundaryvABBdiIWg1ln71M1 Content-Disposition: form-data; name="canvasToTwitter"; filename="blob" Content-Type: image/jpeg ------WebKitFormBoundaryvABBdiIWg1ln71M1--
  15. I am still in the dark...
  16. I believe it is referring to that method, yeah. I did the change. Now the error is gone and I see this response: Notice: Undefined index: canvasToTwitter in mypath/tweet-with-media.php on line 27 This is my new twitter-with-media.php. <?php header("Access-Control-Allow-Origin: *"); session_start(); require 'twitteroauth/autoload.php'; use Abraham\TwitterOAuth\TwitterOAuth; define('CONSUMER_KEY', 'x'); // add your app consumer key between single quotes define('CONSUMER_SECRET', 'x'); // add your app consumer secret key between single quotes define('OAUTH_CALLBACK', 'httwitter/callback.php'); // your app callback URL if (!isset($_SESSION['access_token'])) { $connection = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET); $request_token = $connection->oauth('oauth/request_token', array('oauth_callback' => OAUTH_CALLBACK)); $_SESSION['oauth_token'] = $request_token['oauth_token']; $_SESSION['oauth_token_secret'] = $request_token['oauth_token_secret']; $url = $connection->url('oauth/authorize', array('oauth_token' => $request_token['oauth_token'])); header('Location:' . $url); } else { $access_token = $_SESSION['access_token']; $connection = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET, $access_token['oauth_token'], $access_token['oauth_token_secret']); // getting basic user info $user = $connection->get("account/verify_credentials"); $img = $_POST['canvasToTwitter']; $data = base64_decode($img); $path = getcwd(); $file = $path . "/temp-upload/twitter.png"; $success = file_put_contents($file, $data); // uploading media (image) and getting media_id $tweetWM = $connection->upload('media/upload', ['media' => $file]); // tweeting with uploaded media (image) using media_id $tweet = $connection->post('statuses/update', ['media_ids' => $tweetWM->media_id, 'status' => 'my status']); } unlink($file); echo "<script>window.close();</script>";
  17. This is the TwitterOAuth.php Thank you ! <?php /** * The most popular PHP library for use with the Twitter OAuth REST API. * * @license MIT */ namespace Abraham\TwitterOAuth; use Abraham\TwitterOAuth\Util\JsonDecoder; /** * TwitterOAuth class for interacting with the Twitter API. * * @author Abraham Williams <abraham@abrah.am> */ class TwitterOAuth extends Config { const API_VERSION = '1.1'; const API_HOST = 'https://api.twitter.com'; const UPLOAD_HOST = 'https://upload.twitter.com'; const UPLOAD_CHUNK = 40960; // 1024 * 40 /** @var Response details about the result of the last request */ private $response; /** @var string|null Application bearer token */ private $bearer; /** @var Consumer Twitter application details */ private $consumer; /** @var Token|null User access token details */ private $token; /** @var HmacSha1 OAuth 1 signature type used by Twitter */ private $signatureMethod; /** * Constructor * * @param string $consumerKey The Application Consumer Key * @param string $consumerSecret The Application Consumer Secret * @param string|null $oauthToken The Client Token (optional) * @param string|null $oauthTokenSecret The Client Token Secret (optional) */ public function __construct($consumerKey, $consumerSecret, $oauthToken = null, $oauthTokenSecret = null) { $this->resetLastResponse(); $this->signatureMethod = new HmacSha1(); $this->consumer = new Consumer($consumerKey, $consumerSecret); if (!empty($oauthToken) && !empty($oauthTokenSecret)) { $this->token = new Token($oauthToken, $oauthTokenSecret); } if (empty($oauthToken) && !empty($oauthTokenSecret)) { $this->bearer = $oauthTokenSecret; } } /** * @param string $oauthToken * @param string $oauthTokenSecret */ public function setOauthToken($oauthToken, $oauthTokenSecret) { $this->token = new Token($oauthToken, $oauthTokenSecret); } /** * @return string|null */ public function getLastApiPath() { return $this->response->getApiPath(); } /** * @return int */ public function getLastHttpCode() { return $this->response->getHttpCode(); } /** * @return array */ public function getLastXHeaders() { return $this->response->getXHeaders(); } /** * @return array|object|null */ public function getLastBody() { return $this->response->getBody(); } /** * Resets the last response cache. */ public function resetLastResponse() { $this->response = new Response(); } /** * Make URLs for user browser navigation. * * @param string $path * @param array $parameters * * @return string */ public function url($path, array $parameters) { $this->resetLastResponse(); $this->response->setApiPath($path); $query = http_build_query($parameters); return sprintf('%s/%s?%s', self::API_HOST, $path, $query); } /** * Make /oauth/* requests to the API. * * @param string $path * @param array $parameters * * @return array * @throws TwitterOAuthException */ public function oauth($path, array $parameters = []) { $response = []; $this->resetLastResponse(); $this->response->setApiPath($path); $url = sprintf('%s/%s', self::API_HOST, $path); $result = $this->oAuthRequest($url, 'POST', $parameters); if ($this->getLastHttpCode() != 200) { throw new TwitterOAuthException($result); } parse_str($result, $response); $this->response->setBody($response); return $response; } /** * Make /oauth2/* requests to the API. * * @param string $path * @param array $parameters * * @return array|object */ public function oauth2($path, array $parameters = []) { $method = 'POST'; $this->resetLastResponse(); $this->response->setApiPath($path); $url = sprintf('%s/%s', self::API_HOST, $path); $request = Request::fromConsumerAndToken($this->consumer, $this->token, $method, $url, $parameters); $authorization = 'Authorization: Basic ' . $this->encodeAppAuthorization($this->consumer); $result = $this->request($request->getNormalizedHttpUrl(), $method, $authorization, $parameters); $response = JsonDecoder::decode($result, $this->decodeJsonAsArray); $this->response->setBody($response); return $response; } /** * Make GET requests to the API. * * @param string $path * @param array $parameters * * @return array|object */ public function get($path, array $parameters = []) { return $this->http('GET', self::API_HOST, $path, $parameters); } /** * Make POST requests to the API. * * @param string $path * @param array $parameters * * @return array|object */ public function post($path, array $parameters = []) { return $this->http('POST', self::API_HOST, $path, $parameters); } /** * Make DELETE requests to the API. * * @param string $path * @param array $parameters * * @return array|object */ public function delete($path, array $parameters = []) { return $this->http('DELETE', self::API_HOST, $path, $parameters); } /** * Make PUT requests to the API. * * @param string $path * @param array $parameters * * @return array|object */ public function put($path, array $parameters = []) { return $this->http('PUT', self::API_HOST, $path, $parameters); } /** * Upload media to upload.twitter.com. * * @param string $path * @param array $parameters * @param boolean $chunked * * @return array|object */ public function upload($path, array $parameters = [], $chunked = false) { if ($chunked) { return $this->uploadMediaChunked($path, $parameters); } else { return $this->uploadMediaNotChunked($path, $parameters); } } /** * Private method to upload media (not chunked) to upload.twitter.com. * * @param string $path * @param array $parameters * * @return array|object */ private function uploadMediaNotChunked($path, $parameters) { $file = file_get_contents($parameters['media']); $base = base64_encode($file); $parameters['media'] = $base; return $this->http('POST', self::UPLOAD_HOST, $path, $parameters); } /** * Private method to upload media (chunked) to upload.twitter.com. * * @param string $path * @param array $parameters * * @return array|object */ private function uploadMediaChunked($path, $parameters) { // Init $init = $this->http('POST', self::UPLOAD_HOST, $path, [ 'command' => 'INIT', 'media_type' => $parameters['media_type'], 'total_bytes' => filesize($parameters['media']) ]); // Append $segment_index = 0; $media = fopen($parameters['media'], 'rb'); while (!feof($media)) { $this->http('POST', self::UPLOAD_HOST, 'media/upload', [ 'command' => 'APPEND', 'media_id' => $init->media_id_string, 'segment_index' => $segment_index++, 'media_data' => base64_encode(fread($media, self::UPLOAD_CHUNK)) ]); } fclose($media); // Finalize $finalize = $this->http('POST', self::UPLOAD_HOST, 'media/upload', [ 'command' => 'FINALIZE', 'media_id' => $init->media_id_string ]); return $finalize; } /** * @param string $method * @param string $host * @param string $path * @param array $parameters * * @return array|object */ private function http($method, $host, $path, array $parameters) { $this->resetLastResponse(); $url = sprintf('%s/%s/%s.json', $host, self::API_VERSION, $path); $this->response->setApiPath($path); $result = $this->oAuthRequest($url, $method, $parameters); $response = JsonDecoder::decode($result, $this->decodeJsonAsArray); $this->response->setBody($response); return $response; } /** * Format and sign an OAuth / API request * * @param string $url * @param string $method * @param array $parameters * * @return string * @throws TwitterOAuthException */ private function oAuthRequest($url, $method, array $parameters) { $request = Request::fromConsumerAndToken($this->consumer, $this->token, $method, $url, $parameters); if (array_key_exists('oauth_callback', $parameters)) { // Twitter doesn't like oauth_callback as a parameter. unset($parameters['oauth_callback']); } if ($this->bearer === null) { $request->signRequest($this->signatureMethod, $this->consumer, $this->token); $authorization = $request->toHeader(); } else { $authorization = 'Authorization: Bearer ' . $this->bearer; } return $this->request($request->getNormalizedHttpUrl(), $method, $authorization, $parameters); } /** * Make an HTTP request * * @param string $url * @param string $method * @param string $authorization * @param array $postfields * * @return string * @throws TwitterOAuthException */ private function request($url, $method, $authorization, $postfields) { /* Curl settings */ $options = [ // CURLOPT_VERBOSE => true, CURLOPT_CAINFO => __DIR__ . DIRECTORY_SEPARATOR . 'cacert.pem', CURLOPT_CONNECTTIMEOUT => $this->connectionTimeout, CURLOPT_HEADER => true, CURLOPT_HTTPHEADER => ['Accept: application/json', $authorization, 'Expect:'], CURLOPT_RETURNTRANSFER => true, CURLOPT_SSL_VERIFYHOST => 2, CURLOPT_SSL_VERIFYPEER => true, CURLOPT_TIMEOUT => $this->timeout, CURLOPT_URL => $url, CURLOPT_USERAGENT => $this->userAgent, ]; if($this->gzipEncoding) { $options[CURLOPT_ENCODING] = 'gzip'; } if (!empty($this->proxy)) { $options[CURLOPT_PROXY] = $this->proxy['CURLOPT_PROXY']; $options[CURLOPT_PROXYUSERPWD] = $this->proxy['CURLOPT_PROXYUSERPWD']; $options[CURLOPT_PROXYPORT] = $this->proxy['CURLOPT_PROXYPORT']; $options[CURLOPT_PROXYAUTH] = CURLAUTH_BASIC; $options[CURLOPT_PROXYTYPE] = CURLPROXY_HTTP; } switch ($method) { case 'GET': break; case 'POST': $options[CURLOPT_POST] = true; $options[CURLOPT_POSTFIELDS] = Util::buildHttpQuery($postfields); break; case 'DELETE': $options[CURLOPT_CUSTOMREQUEST] = 'DELETE'; break; case 'PUT': $options[CURLOPT_CUSTOMREQUEST] = 'PUT'; break; } if (in_array($method, ['GET', 'PUT', 'DELETE']) && !empty($postfields)) { $options[CURLOPT_URL] .= '?' . Util::buildHttpQuery($postfields); } $curlHandle = curl_init(); curl_setopt_array($curlHandle, $options); $response = curl_exec($curlHandle); // Throw exceptions on cURL errors. if (curl_errno($curlHandle) > 0) { throw new TwitterOAuthException(curl_error($curlHandle), curl_errno($curlHandle)); } $this->response->setHttpCode(curl_getinfo($curlHandle, CURLINFO_HTTP_CODE)); $parts = explode("\r\n\r\n", $response); $responseBody = array_pop($parts); $responseHeader = array_pop($parts); $this->response->setHeaders($this->parseHeaders($responseHeader)); curl_close($curlHandle); return $responseBody; } /** * Get the header info to store. * * @param string $header * * @return array */ private function parseHeaders($header) { $headers = []; foreach (explode("\r\n", $header) as $line) { if (strpos($line, ':') !== false) { list ($key, $value) = explode(': ', $line); $key = str_replace('-', '_', strtolower($key)); $headers[$key] = trim($value); } } return $headers; } /** * Encode application authorization header with base64. * * @param Consumer $consumer * * @return string */ private function encodeAppAuthorization($consumer) { // TODO: key and secret should be rfc 1738 encoded $key = $consumer->key; $secret = $consumer->secret; return base64_encode($key . ':' . $secret); } }
  18. I changed the JS like below, sending the base64 data via a form and opening the tweet-with-media.php file via window.open in the beforesend state. When the tweet-with-media.php fopens up I get this Warning: file_get_contents(): Filename cannot be empty in /path/to/TwitterOAuth.php on line 249 How can I debug this 400 bad request from Twitter? I am sorry, I am new to all this... My JS: $('#twitter').click(function() { var formData = new FormData(); var mimetype = canvas.toDataURL().substring(canvas.toDataURL().lastIndexOf(":") + 1, canvas.toDataURL().lastIndexOf(";")), blobTW = dataURItoBlob(canvas.toDataURL().split(',')[1], mimetype); formData.append('canvasToTwitter', blobTW); $.ajax({ url: './twitter/tweet-with-media.php', type: 'POST', data: formData, processData: false, contentType: false, cache: false, beforeSend: function() { window.open('tweet-with-media.php'); $('#twitter').addClass('twitter-beforesend'); }, success: function() { $('#twitter').removeClass('twitter-beforesend'); $('#twitter').addClass('twitter-success'); setTimeout( function() { $('#twitter').removeClass('twitter-success'); }, 3000); } }); });
  19. the 400 is because one should be authenticated. but before authenticating, the redirect should work... at least that's my intention in the tweet-with-media.php file when I use: header('Location: ' . $url); Why is the header() function not working? What am I doing wrong?
  20. Help with the above please to understand what's going on? If I browse straight away to the twitter.php file, it seems to work, as in it asks for the user agreement on adding the app. Is there anything wrong with the AJAX code?
  21. I have a problem. The code above allows anybody to post the canvas image only to the twitter wall of the account that generated the keys. How can I allow people to post the canvas image on their own twitter wall? So far this is what I have but it is not working. In my app's main index file I have this AJAX request: $('#twitter').click(function() { var canvasImgData = canvas.toDataURL(); $.ajax({ url: './twitter/tweet-with-media.php', type: 'POST', data: { canvasImgData: canvasImgData }, crossDomain: true, success: function() { $('#twitter').addClass('twitter-success'); setTimeout( function() { $('#twitter').removeClass('twitter-success'); }, 3000); } }); }); The payload request: canvasImgData:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABLAAAAOECAY... Whereas the response is empty and these are the statuses: I also created a TWEET-WITH-MEDIA.PHP file with this content: <?php session_start(); require 'twitteroauth/autoload.php'; use Abraham\TwitterOAuth\TwitterOAuth; define('CONSUMER_KEY', 'my consumer key'); // add your app consumer key between single quotes define('CONSUMER_SECRET', 'my consumer secret'); // add your app consumer secret key between single quotes define('OAUTH_CALLBACK', 'http://www.mywebsite.com/twitter/callback.php'); // your app callback URL if (!isset($_SESSION['access_token'])) { $connection = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET); $request_token = $connection->oauth('oauth/request_token', array('oauth_callback' => OAUTH_CALLBACK)); $_SESSION['oauth_token'] = $request_token['oauth_token']; $_SESSION['oauth_token_secret'] = $request_token['oauth_token_secret']; $url = $connection->url('oauth/authorize', array('oauth_token' => $request_token['oauth_token'])); header('Location:' . $url); } else { $access_token = $_SESSION['access_token']; $connection = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET, $access_token['oauth_token'], $access_token['oauth_token_secret']); // getting basic user info $user = $connection->get("account/verify_credentials"); // uploading media (image) and getting media_id $tweetWM = $connection->upload('media/upload', ['media' => $_POST['canvasImgData']]); // tweeting with uploaded media (image) using media_id $tweet = $connection->post('statuses/update', ['media_ids' => $tweetWM->media_id_string, 'status' => 'My status']); } Put this in CALLBACK.PHP (which is referenced also within the app I created in apps.twitter.com): <?php session_start(); require 'twitteroauth/autoload.php'; use Abraham\TwitterOAuth\TwitterOAuth; if (isset($_REQUEST['oauth_verifier'], $_REQUEST['oauth_token']) && $_REQUEST['oauth_token'] == $_SESSION['oauth_token']) { $request_token = []; $request_token['oauth_token'] = $_SESSION['oauth_token']; $request_token['oauth_token_secret'] = $_SESSION['oauth_token_secret']; $connection = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET, $request_token['oauth_token'], $request_token['oauth_token_secret']); $access_token = $connection->oauth("oauth/access_token", array("oauth_verifier" => $_REQUEST['oauth_verifier'])); $_SESSION['access_token'] = $access_token; // redirect user back to index page header('Location: http://mywebsite.com/twitter/tweet-with-media.php'); }
  22. super handy, thanks. And I just realised that if you want to draw this overlay over a layer that is updated via the RequestAnimationFrame, method you have to put this overlay in the RequestAnimationFrame method and get rid of the onload method that normally is used with the drawImage method
  23. Thanks a lot Ingolme! I have two questions now: 1) Where would a new image object, acting as an overlay to the profile image, be positioned best? I put it there in the profileImg.onload but it always shows behind the profile image... 2) How can I pass 2 events to a function and select them individually?
  24. For some reason, each profileImg.x = canvas.width - distanceFromRightSide - ((profileImg.width - 183) / 2); profileImg.y = canvas.height - distanceFromBottomSide - ((profileImg.height - 242) / 2); always return 0, even though the individual values return integers... how come?
×
×
  • Create New...