Thứ Năm, 6 tháng 7, 2017

Đường cong Bezier


Bezier Curve
Đường cong Bezier là một mô hình đường cong thường được sử dụng trong đồ họa máy tính. Nếu bạn đã làm việc với các chương trình đồ họa vector như AI (Adobe Illustrator) hay CorelDRAW, bạn sẽ dễ dàng bắt gặp mô hình này. Đường cong này được hình thành với bốn điểm như minh họa trên.
Bezier Curve
Đường cong Bézier cũng được sử dụng trong các lĩnh vực đồ họa. Cụ thể là kiểm soát quy trình chuyển động của vật thể theo thời gian. Ví dụ, một đường cong Bézier có thể được sử dụng để xác định vận tốc theo thời gian của một đối tượng như một biểu tượng di chuyển từ A đến B. Chứ không phải chỉ đơn giản là di chuyển với bước nhảy cố định (step). Ví dụ như sự chuyển động của mũi tên màu đỏ trên.

Tìm hiểu giá trị cubic-bezier trong Transition

Và thật may mắn khi Bezier Curve cũng được ứng dụng trong Transition với giá trị cubic-bezier, nó là một giá trị hết sức đặc biệt của bộ giá trị các hàm kiểm soát thời gian (timing-function) vì nó cho phép ta tự động tùy chỉnh các kiểu chuyển động với các mốc thời gian khác nhau. Cú pháp nó sẽ như sau:
transition-timing-function: cubic-bezier(P1x, P1y, P2x, P2y);

Bezier Curve
Có 4 điểm nhưng trong cú pháp trển chỉ đề cập tới P1 và P2 tương ứng với X (trục tung) và giá trị Y (trục hoành).
Bezier Curve
Vì như các bạn thấy trong hình vẽ P0(0,0) còn P3(1,1) nên hai điểm này đã là cố định nên không được nhắc tới. Và cũng vì lý do đó, các điểm P1x, P1y, P2x, P2y phải là các giá trị nằm giữa 0 và 1. Ý nghĩa của nó là biểu diễn từ 0 đến 100% thời gian tương ứng với từ 0 đến 100% chuyển động của hiệu ứng (mối tương quan giữa transition-duration và transition-timing-function).
Bezier Curve

Lưu ý

Theo một số tài liệu, nếu các bạn sử dụng các giá trị ví dụ như là cubic-bezier(2,3,5,2), đường chuyển động sẽ nằm ngoài trục tuyến tính, và điều tệ nhất là nó sẽ không hoạt động trên một số trình duyệt. Và đề xuất sử dụng cubic-bezier với giá trị khác 0 và 1 đã được chấp thuận trên WebKit Bugzilla (khung ứng dụng mã nguồn mở xây dựng trình duyệt web của App Inc) nên các bạn cứ thoải mái sử dụng các giá trị tùy biến bất kỳ.

Nhưng sử dụng cubic-bezier như thế nào cho đúng?

Đây là một câu hỏi cực kỳ “hack não” vì cubic-bezier cực kỳ trừu tượng nhưng có một điều tuyệt vời là bạn có thể sử dụng công cụ cubic-bezier.com của Lea Verou để tự tay, tận mắt xem quy trình chuyển động của cubic-bezier và quyết định chuyển động như thế nào sẽ phù hợp với mình.

Bezier Curve

Tuy nhiên, ở khía cạnh kỹ thuật, tôi sẽ mổ xẻ các giá trị trong hàm cubic-bezier này. Theo như các tài liệu, x tức trục tung là thời gian chuyển động còn y tức trục hoành sẽ là sự chuyển động thay đổi theo thời gian x của phần tử (lưu ý là nó không chuyển động theo đường cong mà là một đường thẳng dựa trên cubic-bezier giống như hình ảnh có mũi tên chuyển động màu đỏ ở phía trên). Các bạn nên vào website cubic-bezier.com để tự mình trải nghiệm vì các giá trị này nếu chỉ diễn giải suông như thế này thì nó rất là mơ hồ.

Minh họa các giá trị bằng cubic-bezier

Và nếu chúng ta chuyển 5 giá trị easeease-inease-outease-in-out và linear sang cubic-bezier thì lần lượt chúng sẽ có giá trị như sau:
Bezier Curve
easecubic-bezier(0.25,0.1,0.25,1)
ease-incubic-bezier(0.42, 0.0, 1.0, 1.0)
ease-outcubic-bezier(0.0, 0.0, 0.58, 1.0)
ease-in-outcubic-bezier(0.42, 0.0, 0.58, 1.0)
linearcubic-bezier(0,0,1,1)
https://blog.cione.vn/html-css/css-transition-quy-trinh-chuyen-dong.html#Tim_hieu_gia_tri_cubic-bezier_trong_Transition

Thứ Ba, 4 tháng 7, 2017

SVG Path Circle

    <circle cx="" cy="" r="" />

    <path d="
        M cx, cy
        m -r, 0
        a r,r 0 1,0 (r * 2),0
        a r,r 0 1,0 -(r * 2),0
    "/>

    ...or a bit shorter (merging the two moves) 

    <path d="
        M cx - r, cy
        a r,r 0 1,0 (r * 2),0
        a r,r 0 1,0 -(r * 2),0
    "/>


    Example
    <circle cx="100" cy="100" r="75" />

    <path d="
        M 100, 100
        m -75, 0
        a 75,75 0 1,0 150,0
        a 75,75 0 1,0 -150,0
    "/>



Thứ Tư, 28 tháng 6, 2017

AUTOMATICALLY INSTALL PLUGINS WITH THEMES FOR WORDPRESS

Well, now that is completely possible with a new class that I have built on top of a lot of WordPress APIs. With some help from Gary Jones, the TGM_Plugin_Activation class is now available for WordPress theme authors and users everywhere!
***UPDATE***
Version 2.0 now has an API for theme authors to hook into to use the class, eliminating the need to change the code within the class. Check out the details below!

HOW IT WORKS

The TGM_Plugin_Activation class works by taking a set a key => value pairs from a multidimensional array and processes them to do one of two things:
  1. Automatically install a plugin that comes pre-packaged with the theme
  2. Automatically download the .zip file from the WordPress Plugin Repository and install it
In either case, this new class can handle multiple instances of both, which means that you can include/prompt to download as many plugins as needed!
On theme activation, users are prompted with admin notices that certain plugins are required for the theme. Users can then click the links that take them to a page where forms are prepared for them to submit.
The UI is very familiar and intuitive because it follows suit with the rest of the WordPress admin UI. Users can then hit the submit button that installs the plugin. You can even have plugins be downloaded and installed from the WordPress Plugin Repository!
The TGM_Plugin_Activation class uses the same methods as WordPress itself uses to download, install, upgrade and activate plugins.

HOW TO INCLUDE THE TGM_PLUGIN_ACTIVATION CLASS WITH YOUR THEME

Take a look at the following code (taken from the example.php file included with the class):
<?php
/**
* Include the TGM_Plugin_Activation class.
*/
require_once dirname( __FILE__ ) . '/class-tgm-plugin-activation.php';
add_action( 'tgmpa_register', 'my_theme_register_required_plugins' );
/**
* Register the required plugins for this theme.
*
* In this example, we register two plugins - one included with the TGMPA library
* and one from the .org repo.
*
* The variable passed to tgmpa_register_plugins() should be an array of plugin
* arrays.
*
* This function is hooked into tgmpa_init, which is fired within the
* TGM_Plugin_Activation class constructor.
*/
function my_theme_register_required_plugins() {
/**
* Array of plugin arrays. Required keys are name and slug.
* If the source is NOT from the .org repo, then source is also required.
*/
$plugins = array(
/** This is an example of how to include a plugin pre-packaged with a theme */
array(
'name' => 'TGM Example Plugin', // The plugin name
'slug' => 'tgm-example-plugin', // The plugin slug (typically the folder name)
'source' => get_stylesheet_directory() . '/lib/plugins/tgm-example-plugin.zip', // The plugin source
'required' => false,
),
/** This is an example of how to include a plugin from the WordPress Plugin Repository */
array(
'name' => 'Edit Howdy',
'slug' => 'edit-howdy',
),
);
/** Change this to your theme text domain, used for internationalising strings */
$theme_text_domain = 'tgmpa';
/**
* Array of configuration settings. Uncomment and amend each line as needed.
* If you want the default strings to be available under your own theme domain,
* uncomment the strings and domain.
* Some of the strings are added into a sprintf, so see the comments at the
* end of each line for what each argument will be.
*/
$config = array(
/*'domain' => $theme_text_domain, // Text domain - likely want to be the same as your theme. */
/*'default_path' => '', // Default absolute path to pre-packaged plugins */
/*'menu' => 'install-my-theme-plugins', // Menu slug */
'strings' => array(
/*'page_title' => __( 'Install Required Plugins', $theme_text_domain ), // */
/*'menu_title' => __( 'Install Plugins', $theme_text_domain ), // */
/*'instructions_install' => __( 'The %1$s plugin is required for this theme. Click on the big blue button below to install and activate %1$s.', $theme_text_domain ), // %1$s = plugin name */
/*'instructions_activate' => __( 'The %1$s is installed but currently inactive. Please go to the <a href="%2$s">plugin administration page</a> page to activate it.', $theme_text_domain ), // %1$s = plugin name, %2$s = plugins page URL */
/*'button' => __( 'Install %s Now', $theme_text_domain ), // %1$s = plugin name */
/*'installing' => __( 'Installing Plugin: %s', $theme_text_domain ), // %1$s = plugin name */
/*'oops' => __( 'Something went wrong with the plugin API.', $theme_text_domain ), // */
/*'notice_can_install' => __( 'This theme requires the %1$s plugin. <a href="%2$s"><strong>Click here to begin the installation process</strong></a>. You may be asked for FTP credentials based on your server setup.', $theme_text_domain ), // %1$s = plugin name, %2$s = TGMPA page URL */
/*'notice_cannot_install' => __( 'Sorry, but you do not have the correct permissions to install the %s plugin. Contact the administrator of this site for help on getting the plugin installed.', $theme_text_domain ), // %1$s = plugin name */
/*'notice_can_activate' => __( 'This theme requires the %1$s plugin. That plugin is currently inactive, so please go to the <a href="%2$s">plugin administration page</a> to activate it.', $theme_text_domain ), // %1$s = plugin name, %2$s = plugins page URL */
/*'notice_cannot_activate' => __( 'Sorry, but you do not have the correct permissions to activate the %s plugin. Contact the administrator of this site for help on getting the plugin activated.', $theme_text_domain ), // %1$s = plugin name */
/*'return' => __( 'Return to Required Plugins Installer', $theme_text_domain ), // */
),
);
tgmpa( $plugins, $config );
}
view rawgistfile1.php hosted with ❤ by GitHub
This may seem like a lot of code, but don’t let it scare you. Most of it is commenting to help you understand what each part does and how the API interacts with the class.
First you need to include the class for use within your functions.php file. This is done by the require_once line. You should amend the path so that it targets wherever you decide to place the class within your theme directory structure.
The crux of the API is the tgmpa_register() hook and the tgmpa() function. Your plugin information and configurations are added within a function that is added to the tgmpa_register hook. There are three variables for you to play with: $plugins$config and $theme_text_domain.
The $plugins variables is required for you to fill out to include your plugins. The variable takes multiple arrays of arguments for your plugins. The keys ‘name’ and ‘slug’ are required for both pre-packaged and repo plugins. If you plugin is pre-packaged, the ‘source’ key is also required. The ‘required’ key is a boolean that will soon be used to determine whether your plugin is required or simply recommended. You can leave this out for now as it will not be active until a future update.
The $theme_text_domain is for localization. You set your own text domain here so that the strings used by the class can be localized along with your other theme text strings.
The $config variable allows you to set the theme text domain, the default absolute path to your pre-packaged plugins, the menu slug for the install plugins page, and an array of strings to customize admin notices and other messages to your theme users. Refer to the example.php file to learn how you can customize these for your theme.

A LOOK AT WHAT’S INSIDE

This automatic plugin installer class makes use of quite a few of WordPress’ own classes. Specifically, this class uses WP_Filesystem, Plugin_Upgrader, Plugin_Skin_Installer and WP_Error. This class also makes use of the plugins_api function as well for preparation for the plugin install and activation.
Unfortunately, none of these classes have extensive documentation (apart from WP_Error). Otto has a great tutorial on WP_Filesystem which I recommend you read get an understand of how to instantiate it. I will make a tutorial soon on how to use WP_Filesystem is correlation with other WordPress classes so you too can learn how to make applications like this one. 🙂
Questions? Comments? I’d love to have them! Please post any bugs you find or any questions that may arise when using this class because I would love to work them out. I believe this class has some great potential within the WordPress community, so please make sure you let everyone know about it!
Thomas