Optimized page loading a bit for grade levels by adding separate loader page for the data: images used on badges.

This commit is contained in:
pmk 2018-10-01 11:19:44 +02:00
parent 2dca35341d
commit fa8dd4b653
6 changed files with 58 additions and 21 deletions

View File

@ -1 +1 @@
define(["jquery","core/str","core/ajax","block_gradelevel/debugger"],function(e,t,i,l){let r=l("renderbadge"),a={init:function(){e("figure.levelbadge").each(function(){a.setup_badge(this,!0)})},setup_badge:function(t,i){let l=e(t),n=e(t).data("badge-props");if(r.info("Setting up skill badge on ",t,n),n&&i)r.info(" skill badge was already configured. Skipping process...");else{n=a.fetchProperties(t);let i=e("<canvas height= '"+n.height+"' width = '"+n.width+"'/>");e("canvas",t).remove(),l.append(i),a.render(i[0],n),l.data("badge-props",n)}},render:function(e,t){let i=e.getContext("2d"),l={base:t.color,light:a.shadeBlendConvert(.6,t.color),dark:a.shadeBlendConvert(.3,t.color),lightPoint:a.shadeBlendConvert(.8,t.color),reflection:{lightest:"#ffffff51",darkest:"#ffffff20"},radialGradient:{x0:.75,y0:.25,r0:.05,x1:.6,y1:.4,r1:.4},levelText:"white"},n={size:Math.min(t.height,t.width),borderWidth:.05,reflection:{angle:-20,offset:.125},levelText:{x:.5,y:.9,size:.2,font:"Open Sans, Arial, helvetica, sans-serif"},icon:{x:.5,y:.47,scale:.7}};r.info(" Config",n),r.info(" Colors",l),r.info(" Props",t);let s=i.createRadialGradient(n.size*l.radialGradient.x0,n.size*l.radialGradient.y0,n.size*l.radialGradient.r0,n.size*l.radialGradient.x1,n.size*l.radialGradient.y1,n.size*l.radialGradient.r1);s.addColorStop(0,l.lightPoint),s.addColorStop(1,l.base),i.beginPath(),i.fillStyle=s,i.arc(.5*n.size,.5*n.size,n.size/2,0,2*Math.PI),i.fill();let o=Math.asin(n.reflection.offset),h=n.reflection.angle/360*2*Math.PI,d=i.createLinearGradient((.5-n.reflection.offset*Math.sin(h))/2*n.size,(.5+n.reflection.offset*Math.cos(h))/2*n.size,Math.sin(h)/2*n.size,Math.cos(h)/2*n.size);d.addColorStop(0,l.reflection.lightest),d.addColorStop(1,l.reflection.darkest),i.beginPath(),i.fillStyle=d,i.arc(.5*n.size,.5*n.size,n.size/2,0+o+h,Math.PI-o+h),i.fill();let f=n.size*n.borderWidth;if(i.beginPath(),i.strokeStyle=l.light,i.lineWidth=f,i.arc(.5*n.size,.5*n.size,n.size/2-f/2,0,2*Math.PI),i.stroke(),i.beginPath(),i.strokeStyle=l.dark,i.lineWidth=f,i.arc(.5*n.size,.5*n.size,n.size/2-f/2,0-Math.PI/2,2*t.progress*Math.PI-Math.PI/2),i.stroke(),t.level&&(i.font=n.size*n.levelText.size+"px "+n.levelText.font,i.fillStyle=l.levelText,i.textAlign="center",i.fillText(""+t.level,n.size*n.levelText.x,n.size*n.levelText.y)),t.image){let e=new Image;e.onload=function(){let e={x:0,y:0,w:n.size*n.icon.scale,h:n.size*n.icon.scale};this.width>this.height?e.h*=this.height/this.width:e.w*=this.width/this.height,e.x=n.size*n.icon.x-e.w/2,e.y=n.size*n.icon.y-e.h/2,i.drawImage(this,e.x,e.y,e.w,e.h)},e.src=t.image}},fetchProperties:function(t){let i=e(t),l=i.find("img"),r=null;return l.length>0&&(r=l.attr("src")),{progress:i.attr("data-progress"),width:i.attr("data-width"),height:i.attr("data-height"),color:"#"+i.attr("data-color"),level:i.attr("data-level"),image:r}},shadeBlendConvert:function(e,t,i){if("number"!=typeof e||e<-1||e>1||"string"!=typeof t||"r"!=t[0]&&"#"!=t[0]||i&&"string"!=typeof i)return null;this.sbcRip||(this.sbcRip=(e=>{let t=e.length,i={};if(t>9){if((e=e.split(",")).length<3||e.length>4)return null;i[0]=l(e[0].split("(")[1]),i[1]=l(e[1]),i[2]=l(e[2]),i[3]=e[3]?parseFloat(e[3]):-1}else{if(8==t||6==t||t<4)return null;t<6&&(e="#"+e[1]+e[1]+e[2]+e[2]+e[3]+e[3]+(t>4?e[4]+""+e[4]:"")),e=l(e.slice(1),16),i[0]=e>>16&255,i[1]=e>>8&255,i[2]=255&e,i[3]=-1,9!=t&&5!=t||(i[3]=r(i[2]/255*1e4)/1e4,i[2]=i[1],i[1]=i[0],i[0]=e>>24&255)}return i}));var l=parseInt,r=Math.round,a=t.length>9,n=(a="string"==typeof i?i.length>9||"c"==i&&!a:a,e<0),s=(e=n?-1*e:e,i=i&&"c"!=i?i:n?"#000000":"#FFFFFF",this.sbcRip(t)),o=this.sbcRip(i);return s&&o?a?"rgb"+(s[3]>-1||o[3]>-1?"a(":"(")+r((o[0]-s[0])*e+s[0])+","+r((o[1]-s[1])*e+s[1])+","+r((o[2]-s[2])*e+s[2])+(s[3]<0&&o[3]<0?")":","+(s[3]>-1&&o[3]>-1?r(1e4*((o[3]-s[3])*e+s[3]))/1e4:o[3]<0?s[3]:o[3])+")"):"#"+(4294967296+16777216*r((o[0]-s[0])*e+s[0])+65536*r((o[1]-s[1])*e+s[1])+256*r((o[2]-s[2])*e+s[2])+(s[3]>-1&&o[3]>-1?r(255*((o[3]-s[3])*e+s[3])):o[3]>-1?r(255*o[3]):s[3]>-1?r(255*s[3]):255)).toString(16).slice(1,s[3]>-1||o[3]>-1?void 0:-2):null}};return a}); define(["jquery","core/str","core/ajax","block_gradelevel/debugger"],function(e,t,i,l){let r=l("renderbadge");r.enable();let a={init:function(){r.info("Setting up badge renderers"),e("figure.levelbadge").each(function(){a.setup_badge(this,!0)})},setup_badge:function(t,i){let l=e(t),n=e(t).data("badge-props");if(r.info("Setting up skill badge on ",t,n),n&&i)r.info(" skill badge was already configured. Skipping process...");else{n=a.fetchProperties(t);let i=e("<canvas height= '"+n.height+"' width = '"+n.width+"'/>");e("canvas",t).remove(),l.append(i),a.render(i[0],n),l.data("badge-props",n)}},render:function(e,t){let i=e.getContext("2d"),l={base:t.color,light:a.shadeBlendConvert(.6,t.color),dark:a.shadeBlendConvert(.3,t.color),lightPoint:a.shadeBlendConvert(.8,t.color),reflection:{lightest:"#ffffff51",darkest:"#ffffff20"},radialGradient:{x0:.75,y0:.25,r0:.05,x1:.6,y1:.4,r1:.4},levelText:"white"},n={size:Math.min(t.height,t.width),borderWidth:.05,reflection:{angle:-20,offset:.125},levelText:{x:.5,y:.9,size:.2,font:"Open Sans, Arial, helvetica, sans-serif"},icon:{x:.5,y:.47,scale:.7}};r.info(" Config",n),r.info(" Colors",l),r.info(" Props",t);let s=i.createRadialGradient(n.size*l.radialGradient.x0,n.size*l.radialGradient.y0,n.size*l.radialGradient.r0,n.size*l.radialGradient.x1,n.size*l.radialGradient.y1,n.size*l.radialGradient.r1);s.addColorStop(0,l.lightPoint),s.addColorStop(1,l.base),i.beginPath(),i.fillStyle=s,i.arc(.5*n.size,.5*n.size,n.size/2,0,2*Math.PI),i.fill();let o=Math.asin(n.reflection.offset),d=n.reflection.angle/360*2*Math.PI,h=i.createLinearGradient((.5-n.reflection.offset*Math.sin(d))/2*n.size,(.5+n.reflection.offset*Math.cos(d))/2*n.size,Math.sin(d)/2*n.size,Math.cos(d)/2*n.size);h.addColorStop(0,l.reflection.lightest),h.addColorStop(1,l.reflection.darkest),i.beginPath(),i.fillStyle=h,i.arc(.5*n.size,.5*n.size,n.size/2,0+o+d,Math.PI-o+d),i.fill();let f=n.size*n.borderWidth;if(i.beginPath(),i.strokeStyle=l.light,i.lineWidth=f,i.arc(.5*n.size,.5*n.size,n.size/2-f/2,0,2*Math.PI),i.stroke(),i.beginPath(),i.strokeStyle=l.dark,i.lineWidth=f,i.arc(.5*n.size,.5*n.size,n.size/2-f/2,0-Math.PI/2,2*t.progress*Math.PI-Math.PI/2),i.stroke(),t.level&&(i.font=n.size*n.levelText.size+"px "+n.levelText.font,i.fillStyle=l.levelText,i.textAlign="center",i.fillText(""+t.level,n.size*n.levelText.x,n.size*n.levelText.y)),t.image){let e=new Image;e.onload=function(){let e={x:0,y:0,w:n.size*n.icon.scale,h:n.size*n.icon.scale};this.width>this.height?e.h*=this.height/this.width:e.w*=this.width/this.height,e.x=n.size*n.icon.x-e.w/2,e.y=n.size*n.icon.y-e.h/2,i.drawImage(this,e.x,e.y,e.w,e.h)},e.src=t.image}},fetchProperties:function(t){let i=e(t),l=i.find("img"),r=null;return l.length>0&&(r=l.attr("src")),{progress:i.attr("data-progress"),width:i.attr("data-width"),height:i.attr("data-height"),color:"#"+i.attr("data-color"),level:i.attr("data-level"),image:r}},shadeBlendConvert:function(e,t,i){if("number"!=typeof e||e<-1||e>1||"string"!=typeof t||"r"!=t[0]&&"#"!=t[0]||i&&"string"!=typeof i)return null;this.sbcRip||(this.sbcRip=(e=>{let t=e.length,i={};if(t>9){if((e=e.split(",")).length<3||e.length>4)return null;i[0]=l(e[0].split("(")[1]),i[1]=l(e[1]),i[2]=l(e[2]),i[3]=e[3]?parseFloat(e[3]):-1}else{if(8==t||6==t||t<4)return null;t<6&&(e="#"+e[1]+e[1]+e[2]+e[2]+e[3]+e[3]+(t>4?e[4]+""+e[4]:"")),e=l(e.slice(1),16),i[0]=e>>16&255,i[1]=e>>8&255,i[2]=255&e,i[3]=-1,9!=t&&5!=t||(i[3]=r(i[2]/255*1e4)/1e4,i[2]=i[1],i[1]=i[0],i[0]=e>>24&255)}return i}));var l=parseInt,r=Math.round,a=t.length>9,n=(a="string"==typeof i?i.length>9||"c"==i&&!a:a,e<0),s=(e=n?-1*e:e,i=i&&"c"!=i?i:n?"#000000":"#FFFFFF",this.sbcRip(t)),o=this.sbcRip(i);return s&&o?a?"rgb"+(s[3]>-1||o[3]>-1?"a(":"(")+r((o[0]-s[0])*e+s[0])+","+r((o[1]-s[1])*e+s[1])+","+r((o[2]-s[2])*e+s[2])+(s[3]<0&&o[3]<0?")":","+(s[3]>-1&&o[3]>-1?r(1e4*((o[3]-s[3])*e+s[3]))/1e4:o[3]<0?s[3]:o[3])+")"):"#"+(4294967296+16777216*r((o[0]-s[0])*e+s[0])+65536*r((o[1]-s[1])*e+s[1])+256*r((o[2]-s[2])*e+s[2])+(s[3]>-1&&o[3]>-1?r(255*((o[3]-s[3])*e+s[3])):o[3]>-1?r(255*o[3]):s[3]>-1?r(255*s[3]):255)).toString(16).slice(1,s[3]>-1||o[3]>-1?void 0:-2):null}};return a});

View File

@ -5,11 +5,11 @@
define(['jquery', 'core/str', 'core/ajax','block_gradelevel/debugger' ], function ($, str, ajax, Debugger) { define(['jquery', 'core/str', 'core/ajax','block_gradelevel/debugger' ], function ($, str, ajax, Debugger) {
let debug = Debugger("renderbadge"); let debug = Debugger("renderbadge");
//debug.enable(); debug.enable();
let self = { let self = {
init: function init() { init: function init() {
debug.info("Setting up badge renderers");
// Put whatever you like here. $ is available // Put whatever you like here. $ is available
// to you as normal. // to you as normal.
$("figure.levelbadge").each(function () { $("figure.levelbadge").each(function () {

View File

@ -344,7 +344,7 @@ class block_gradelevel_levelset {
*/ */
public function calculate_level($points){ public function calculate_level($points){
$levels = $this->badgelevels($levelset_id); $levels = $this->badgelevels();
$level = 0; $level = 0;
$badge_color = static::NULL_BADGE_COLOR; $badge_color = static::NULL_BADGE_COLOR;
@ -456,16 +456,16 @@ class block_gradelevel_levelset {
$info = $this->calculate_level($points); $info = $this->calculate_level($points);
$image = $this->getIcon(); $image = $this->getIcon();
if(strncmp($image,"data:",5) != 0) if(strncmp($image,"data:",5) == 0)
{ {
$image_url = $CFG->wwwroot.$image; $image_url = $CFG->wwwroot."/blocks/gradelevel/view-icon.php?skillid=".$this->id;
} }
else else
{ {
$image_url = $image; $image_url = $image;
} }
$html = "<figure class='levelbadge'"; $html = "<figure class='levelbadge weird'";
$html .= " data-color='{$info->badge_color}'"; $html .= " data-color='{$info->badge_color}'";
$html .= " data-progress='{$info->progress}'"; $html .= " data-progress='{$info->progress}'";
$html .= " data-level='{$info->level}'"; $html .= " data-level='{$info->level}'";

View File

@ -1,4 +1,4 @@
<?php <?php
$plugin->component = 'block_gradelevel'; // Recommended since 2.0.2 (MDL-26035). Required since 3.0 (MDL-48494) $plugin->component = 'block_gradelevel'; // Recommended since 2.0.2 (MDL-26035). Required since 3.0 (MDL-48494)
$plugin->version = 2018092400; // YYYYMMDDHH (year, month, day, 24-hr time) $plugin->version = 2018092402; // YYYYMMDDHH (year, month, day, 24-hr time)
$plugin->requires = 2018050800; // YYYYMMDDHH (This is the release version for Moodle 3.5) $plugin->requires = 2018050800; // YYYYMMDDHH (This is the release version for Moodle 3.5)

49
view-icon.php Normal file
View File

@ -0,0 +1,49 @@
<?php
//header("Content-type: image/svg+xml");
//ob_start();
require_once("../../config.php");
global $CFG;
global $DB;
$skillid = required_param('skillid', PARAM_INT);
$skill = $DB->get_record('block_gradelevel_levelset', array('id' => $skillid));
if(is_object($skill))
{
$image = $skill->icon;
if(strncmp($image,"data:",5) == 0)
{
$parts = explode(",",ltrim(substr($image,5)),2);
$typeinfo = explode(";",$parts[0]);
if(count($typeinfo) > 1 && $typeinfo[1] == "base64")
{
$binary = base64_decode($parts[1]);
}
else
{
$binary = $parts[0];
}
$mime = $typeinfo[0];
// set header
header("Content-type: {$mime}");
header("Pragma:");
// Allow cache for 5 seconds
header("Cache-Control: public, max-age=5");
// print data
print $binary;
}
else
{
// redirect to specified url
header("Location: {$image}",true,302);
}
}
else
{
http_response_code(404);
print "Image not found";
}

View File

@ -1,17 +1,5 @@
<?php <?php
if(isset($_SERVER['SCRIPT_FILENAME']))
{
// If SCRIPT_FILENAME is set, use that so the symlinked directories the developmen environment uses are handled correctly
$root = dirname(dirname(dirname($_SERVER['SCRIPT_FILENAME'])));
error_log("Using {$root}/config.php");
require_once($root."/config.php");
}
else
{
// If not, assume the cwd is not symlinked and proceed as we are used to
require_once("../../config.php"); require_once("../../config.php");
}
global $DB; global $DB;
global $CFG; global $CFG;