ブラウザでFlashの画像をドラッグアンドドロップする

サービスのテスト中に、十分な量のフィードバックが収集され、アプリケーションにファイルをダウンロードする昔ながらの方法は持ち越されません。 人々はドラッグアンドドロップを望み、デスクトップから直接写真をドラッグアンドドロップしようとしました。 このアプリケーションはブラウザ画面全体を占有し、フラッシュに書き込まれているため、問題を直接解決する方法はありませんでした。



考えてグーグルで調べた後、少なくとも次のようにD&Dを次のように実装することにしました。

ユーザーがアプリケーションでタブから切り替えると、つまり フォーカスを失い、ドロップされたファイルをキャッチするイベントがハングするフラッシュドライブの上にdivが重ねられます。

次に、ExternalInterfaceを介して、ByteArray形式のイメージがフラッシュに転送され、そこでデコードおよび表示されます。





フラッシュにdivを表示



#over_holder_full { background-color: #eee; opacity: 0.6; position: absolute; width: 100%; height: 100%; z-index: 7; display: none; } #flash_conainer { width: 100%; height: 100%; position: absolute; z-index: 0; } <div id="over_holder_full"></div> <div id="flash_conainer"> <div id="myContent"> <h1>Alternative content</h1> </div> </div>
      
      







ドラッグアンドドロップがマウントされているフォーカスが失われたときに#over_holder_fullを表示します



 window.addEventListener('blur', function() { fullDragArea.style.display = "block"; console.log("not focused"); }); window.addEventListener('focus', function() { fullDragArea.style.display = "none"; console.log("focus"); });
      
      







#over_holder_fullによってドロップされたファイルをキャッチ



 fullDragArea = $id("over_holder_full"); // is XHR2 available? var xhr = new XMLHttpRequest(); if (xhr.upload) { fullDragArea.addEventListener("dragover", FileDragHover, false); fullDragArea.addEventListener("drop", FileSelectHandler, false); // <--     //.... }
      
      







フラッシュ画像転送



 // file selection function FileSelectHandler(e) { fullDragArea.style.display = "none"; // fetch FileList object var files = e.target.files || e.dataTransfer.files; //set grey preview in flash setPreview(pageX, pageY); // process all File objects setTimeout(function(){//<--     setPreview     for (var i = 0, f; f = files[i]; i++) { ParseFile(f); }}, 100); } // output file information function ParseFile(file) { var arrBuffer; if (file.type.indexOf("image") == 0) { var reader = new FileReader(); reader.onload = function(e) { //console.log("arrBuffer + " + e.target.result.byteLength); var dataview = new DataView(e.target.result); var ints = new Int32Array(e.target.result.byteLength / 4); //<--       for (var i = 0; i < ints.length; i++) { ints[i] = dataview.getInt32(i * 4);//<--    4  (        ByteArray) } console.log("ints" + ints.length); // display an image setImage(pageX, pageY, ints); } reader.readAsArrayBuffer(file); } }
      
      







JavaScriptとFlashをバインドする関数



 function setImage(pageX, pageY, int32Arr) { if (swfReady){ var res = []; for (var i = 0; i < int32Arr.length; i++) { res[i] = int32Arr[i]; //<--   ..  externalinterface      ,  Int32Array   } getSWF("DefaultLauncher").setImage(pageX, pageY, res);//    -   } } function setPreview(pageX, pageY) { if (swfReady) { console.log("setPreview"); getSWF("DefaultLauncher").setPreview(pageX, pageY); } }
      
      







フラッシュ側で画像を受け入れます



 var exManager:EXManager = new EXManager(); exManager.setImageCallback = function(pageX:Number, pageY:Number, listBytes:Array):void{ var ba:ByteArray = new ByteArray(); for(var i:int = 0; i<listBytes.length; i++){ ba.writeInt(listBytes[i]); //  ByteArray } var myDecoder:JPEGDecoder = new JPEGDecoder(); //        ByteArray myDecoder.parse(ba); var colorComponents:uint = myDecoder.colorComponents; var numComponents:uint = myDecoder.numComponents; var pixels:Vector.<uint> = myDecoder.pixels; var width:uint = myDecoder.width; var height:uint = myDecoder.height; var bitmap:BitmapData = new BitmapData ( width, height, false ); bitmap.setVector ( bitmap.rect, pixels ); var bmp:Bitmap = new Bitmap(bitmap); var oldW:Number = bmp.width; bmp.width = bmp.width > 500 ? 500 : bmp.width; bmp.height = bmp.height*(bmp.width / oldW); bmp.x = pageX; bmp.y = pageY; stage.addChild(bmp); } exManager.setPreviewCallback = function(pageX:Number, pageY:Number):void{ var sp:Sprite = new Sprite(); sp.graphics.beginFill(0x666666, 0.8); sp.graphics.drawRect(0,0,100,80); sp.x = pageX; sp.y = pageY; stage.addChild(sp); }
      
      







ソースここからダウンロードできます



注:

この例は、JPG拡張子の画像でのみ機能しますが、他の形式に簡単に拡張できます。



wmode:opaqueプロパティは、その上にdivを表示するために必要であるため、フラッシュドライブのスクロールは機能しません。 解決策があれば、私はそれらを聞いてうれしいです。



この例を実行するには、少なくともローカルサーバーに配置する必要があります。



更新:

提案されているように、mouseWheelイベントでグリッチを克服するには、次をjsに追加する必要があります。



 function wheel(event){ var delta = 0; if (!event) event = window.event; //  IE. //   delta if (event.wheelDelta) { // IE, Opera, safari, chrome -    120 delta = event.wheelDelta/120; } else if (event.detail) { // Mozilla,    3 delta = -event.detail/3; } //    mousewheel if (delta && typeof wheelHandle == 'function') { wheelHandle(delta); //    -   ( ). if (event.preventDefault) event.preventDefault(); event.returnValue = false; //  IE } } function wheelHandle(delta){ if (swfReady){ getSWF("DefaultLauncher").externalMouseWheelHandler(delta); } } function pageInit() { jsReady = true; //   mousewheel if (window.addEventListener) // mozilla, safari, chrome window.addEventListener('DOMMouseScroll', wheel, false); // IE, Opera. window.onmousewheel = document.onmousewheel = wheel; }
      
      







また、フラッシュに追加します。

 private function externalMouseWheelHandler(delta:int):void { var globalPoint:Point = new Point(stage.mouseX, stage.mouseY); var objects:Array = stage.getObjectsUnderPoint(globalPoint); if (!objects || !objects.length) { return; } var target:DisplayObject = objects[objects.length - 1] as DisplayObject; if (!target) { return; } target = (target is InteractiveObject) ? target : target.parent; if (!target) { return; } var localPoint:Point = target.globalToLocal(globalPoint); var mouseEvent:MouseEvent = new MouseEvent(MouseEvent.MOUSE_WHEEL); mouseEvent.localX = localPoint.x; mouseEvent.localY = localPoint.y; mouseEvent.delta = delta; target.dispatchEvent(mouseEvent); }
      
      







アップデート2:

いくつかの実験の後、データを分割して転送すること、およびgetInt8



ではなくgetInt8



介してバッファーから読み取る方が良いことが明らかになりました。 最初のケースで想定されているように、ファイル長は必ずしも4の倍数ではありません。



Javascript

 function setImage(bufer) { if (swfReady){ var dataview = new DataView(bufer); var byteLength = bufer.byteLength; //    4 var numBytes = 10000; var startPos = 0; var finishPos; var i = 0; while(i < byteLength){ finishPos = ((startPos + numBytes) > byteLength) ? byteLength : startPos + numBytes; var res = []; for (i = startPos; i < finishPos; i++) { res[i - startPos] = dataview.getInt8(i); //  getInt32  getInt8 } startPos = finishPos; getSWF().sendData(res); } getSWF().sendDataFinish(); } } function setPreview(pageX, pageY, fileName) { if (swfReady){ getSWF().sendDataStart(pageX, pageY, fileName); } }
      
      







ActionScript

 _exManager.sendDataStartCb = function(pageX:Number, pageY:Number, fileName:String):void { prevtime = getTimer(); }; _exManager.sendDataCb = function(listBytes:Array):void { for (var i:int = 0; i < listBytes.length; i++) { ba.writeByte(listBytes[i]);//      } }; _exManager.sendDataFinishCb = function():void { loadFromByteArray(ba); ba.clear(); };
      
      






All Articles