以前のアプレット(下記リンク)では、マウスイベントやタッチイベントにあわせて、既存のcanvas 要素にグラデーションを描画していました(setInteval メソッドを利用していました)。その際、グラデーションが意図せず点滅する問題を抱えていました。
グラデーション三角形_タッチデバイス対応版 - うしブログ
今回のバージョンでは、既存のcanvas 要素にグラデーションを描画するのではなく、新たにcanvasを作成し、そこに描画しています。また、イベントハンドラやsetInterval メソッドを使うのではなく、requestAnimationFrame メソッドを使うことで、適切なタイミングで描画が実行されるようにしました。
これらの改善によって、描画を安定させることができました。
以下に、グローバルJavaスクリプトの内容を記載します。
function ggbOnInit() {
insertCanvas();
console.log(document.getElementsByClassName('usicanvas')[0].className + ' is loaded.');
Drawer();
var fullButton = document.getElementsByClassName('zoomPanelBtn zoomPanelBtn-up')[0];
if(typeof fullButton !== 'undefined'){
fullButton.parentNode.removeChild(fullButton);
console.log('fullscreen button is removed.');
}
else{
console.log('fullscreen button is undefined.');
}
}
function insertCanvas(){
var preCanvas = document.getElementsByTagName('canvas')[0];
var canvasWidth = preCanvas.width;
var canvasHeight = preCanvas.height;
var canvasCss = preCanvas.style.cssText;
preCanvas.insertAdjacentHTML('afterend','<div style="position: absolute; right: 0px; bottom: -4px;"><canvas height=\"'+canvasHeight+'\" width=\"'+canvasWidth+'\" dir=\"ltr\" tabindex=\"10000\" class=\"usicanvas\">UsiCanvas</canvas></div>');
document.getElementsByClassName('usicanvas')[0].style.cssText = canvasCss;
}
function Drawer(){
var requestAnimationFrame = window.requestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.msRequestAnimationFrame;
window.requestAnimationFrame = requestAnimationFrame;
var canvas = document.getElementsByClassName('usicanvas')[0];
var context = canvas.getContext('2d');
context.clearRect(0, 0, canvas.width, canvas.height);
var transformText = document.getElementsByClassName('applet_scaler')[0];
if(typeof transformText === 'undefined'){
transformText = 'none';
}
else{
transformText = transformText.style.transform;
ggbApplet.setTextValue('transformText', transformText);
if(transformText == 'none'){
ggbApplet.evalCommand('SetValue[Ratio,(1,1)]');
}
else{
var editedText = transformText.slice(5);
ggbApplet.evalCommand('SetValue[Ratio,'+editedText+']');
}
}
var ratioX = ggbApplet.getValue('ratioX');
var ratioY = ggbApplet.getValue('ratioY');
var canvasRatioX = document.getElementsByTagName('canvas')[1].width / document.getElementsByTagName('canvas')[0].width;
var canvasRatioY = document.getElementsByTagName('canvas')[1].height / document.getElementsByTagName('canvas')[0].height;
var touch = window.ontouchstart===null?2:1;
var x1 = touch * ggbApplet.getValue('x1') * ratioX * canvasRatioX;
var y1 = touch * ggbApplet.getValue('y1') * ratioY * canvasRatioY;
var x2 = touch * ggbApplet.getValue('x2') * ratioX * canvasRatioX;
var y2 = touch * ggbApplet.getValue('y2') * ratioY * canvasRatioY;
var x3 = touch * ggbApplet.getValue('x3') * ratioX * canvasRatioX;
var y3 = touch * ggbApplet.getValue('y3') * ratioY * canvasRatioY;
context.beginPath();
context.moveTo(x1, y1);
context.lineTo(x2, y2);
context.lineTo(x3, y3);
context.closePath();
var xs = touch * ggbApplet.getValue('xs') * ratioX * canvasRatioX;
var ys = touch * ggbApplet.getValue('ys') * ratioY * canvasRatioY;
var xg = touch * ggbApplet.getValue('xg') * ratioX * canvasRatioX;
var yg = touch * ggbApplet.getValue('yg') * ratioY * canvasRatioY;
var grad = context.createLinearGradient(xs, ys, xg, yg);
var r0 = ggbApplet.getValue('r0');
var g0 = ggbApplet.getValue('g0');
var b0 = ggbApplet.getValue('b0');
var r1 = ggbApplet.getValue('r1');
var g1 = ggbApplet.getValue('g1');
var b1 = ggbApplet.getValue('b1');
grad.addColorStop(0,'rgba('+r0+','+g0+','+b0+', 0.5)');
grad.addColorStop(1,'rgba('+r1+','+g1+','+b1+', 0.5)');
context.fillStyle = grad;
context.fill();
window.requestAnimationFrame(Drawer);
}